KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > hivemind > impl > RegistryInfrastructureImpl


1 // Copyright 2004, 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.hivemind.impl;
16
17 import java.beans.Introspector JavaDoc;
18 import java.util.Collections JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.LinkedList JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Locale JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import org.apache.hivemind.ApplicationRuntimeException;
27 import org.apache.hivemind.ErrorHandler;
28 import org.apache.hivemind.HiveMind;
29 import org.apache.hivemind.HiveMindMessages;
30 import org.apache.hivemind.ShutdownCoordinator;
31 import org.apache.hivemind.internal.ConfigurationPoint;
32 import org.apache.hivemind.internal.Module;
33 import org.apache.hivemind.internal.RegistryInfrastructure;
34 import org.apache.hivemind.internal.ServiceModelFactory;
35 import org.apache.hivemind.internal.ServicePoint;
36 import org.apache.hivemind.internal.ser.ServiceSerializationHelper;
37 import org.apache.hivemind.internal.ser.ServiceSerializationSupport;
38 import org.apache.hivemind.internal.ser.ServiceToken;
39 import org.apache.hivemind.service.ThreadEventNotifier;
40 import org.apache.hivemind.util.Defense;
41 import org.apache.hivemind.util.PropertyUtils;
42 import org.apache.hivemind.util.ToStringBuilder;
43
44 /**
45  * Implementation of {@link RegistryInfrastructure}.
46  *
47  * @author Howard Lewis Ship
48  */

49 public final class RegistryInfrastructureImpl implements RegistryInfrastructure,
50         ServiceSerializationSupport
51 {
52
53     /**
54      * Map of {@link Module} keyed on module id.
55      */

56     private Map JavaDoc _modules = new HashMap JavaDoc();
57
58     /**
59      * Map of {@link ServicePoint} keyed on fully qualified service id.
60      */

61     private Map JavaDoc _servicePoints = new HashMap JavaDoc();
62
63     /**
64      * Map of List (of {@link ServicePoint}, keyed on class name service interface.
65      */

66     private Map JavaDoc _servicePointsByInterfaceClassName = new HashMap JavaDoc();
67     
68     /**
69      * Map of List (of {@link ConfigurationPoint}, keyed on class name service interface.
70      */

71     private Map JavaDoc _configurationPointsByTypeName = new HashMap JavaDoc();
72
73     /**
74      * Map of {@link ConfigurationPoint} keyed on fully qualified configuration id.
75      */

76     private Map JavaDoc _configurationPoints = new HashMap JavaDoc();
77
78     private ErrorHandler _errorHandler;
79
80     private Locale JavaDoc _locale;
81
82     private ShutdownCoordinator _shutdownCoordinator;
83
84     /**
85      * Map of {@link org.apache.hivemind.internal.ser.ServiceToken}, keyed on service id.
86      *
87      * @since 1.1
88      */

89
90     private Map JavaDoc _serviceTokens;
91
92     /**
93      * Map of {@link ServiceModelFactory}, keyed on service model name, loaded from
94      * <code>hivemind.ServiceModels</code> configuration point.
95      */

96     private Map JavaDoc _serviceModelFactories;
97
98     private boolean _started = false;
99
100     private boolean _shutdown = false;
101
102     private ThreadEventNotifier _threadEventNotifier;
103
104     public RegistryInfrastructureImpl(ErrorHandler errorHandler, Locale JavaDoc locale)
105     {
106         _errorHandler = errorHandler;
107         _locale = locale;
108     }
109
110     public Locale JavaDoc getLocale()
111     {
112         return _locale;
113     }
114     
115     public void addModule(Module module)
116     {
117         checkStarted();
118
119         _modules.put(module.getModuleId(), module);
120
121     }
122
123     public void addServicePoint(ServicePoint point)
124     {
125         checkStarted();
126
127         _servicePoints.put(point.getExtensionPointId(), point);
128
129         addServicePointByInterface(point);
130     }
131
132     private void addServicePointByInterface(ServicePoint point)
133     {
134         String JavaDoc key = point.getServiceInterfaceClassName();
135
136         List JavaDoc l = (List JavaDoc) _servicePointsByInterfaceClassName.get(key);
137
138         if (l == null)
139         {
140             l = new LinkedList JavaDoc();
141             _servicePointsByInterfaceClassName.put(key, l);
142         }
143
144         l.add(point);
145     }
146
147     public void addConfigurationPoint(ConfigurationPoint point)
148     {
149         checkStarted();
150
151         _configurationPoints.put(point.getExtensionPointId(), point);
152         
153         addConfigurationPointByType(point);
154     }
155
156     private void addConfigurationPointByType(ConfigurationPoint point)
157     {
158         String JavaDoc key = point.getConfigurationType().getName();
159
160         List JavaDoc l = (List JavaDoc) _configurationPointsByTypeName.get(key);
161
162         if (l == null)
163         {
164             l = new LinkedList JavaDoc();
165             _configurationPointsByTypeName.put(key, l);
166         }
167
168         l.add(point);
169     }
170
171     /**
172      * @see org.apache.hivemind.internal.RegistryInfrastructure#getServicePoint(java.lang.String, org.apache.hivemind.internal.Module)
173      */

174     public ServicePoint getServicePoint(String JavaDoc serviceId, Module module)
175     {
176         checkShutdown();
177         ServicePoint result = (ServicePoint) _servicePoints.get(serviceId);
178         if (result == null)
179         {
180             if (serviceId.indexOf('.') == -1)
181             {
182                 final List JavaDoc possibleMatches = getMatchingServiceIds(serviceId);
183                 if (!possibleMatches.isEmpty())
184                 {
185                     final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
186                     for (Iterator JavaDoc i = possibleMatches.iterator(); i.hasNext();)
187                     {
188                         final String JavaDoc matching = (String JavaDoc) i.next();
189                         sb.append('\"');
190                         sb.append(matching);
191                         sb.append('\"');
192                         if (i.hasNext())
193                         {
194                             sb.append(", ");
195                         }
196                     }
197                     throw new ApplicationRuntimeException(ImplMessages.unqualifiedServicePoint(
198                             serviceId,
199                             sb.toString()));
200                 }
201             }
202             throw new ApplicationRuntimeException(ImplMessages.noSuchServicePoint(serviceId));
203         }
204
205         if (!result.visibleToModule(module))
206             throw new ApplicationRuntimeException(ImplMessages.serviceNotVisible(serviceId, module));
207
208         return result;
209     }
210
211     private List JavaDoc getMatchingServiceIds(String JavaDoc serviceId)
212     {
213         final List JavaDoc possibleMatches = new LinkedList JavaDoc();
214         for (Iterator JavaDoc i = _servicePoints.values().iterator(); i.hasNext();)
215         {
216             final ServicePoint servicePoint = (ServicePoint) i.next();
217             if (servicePoint.getExtensionPointId().equals(
218                     servicePoint.getModule().getModuleId() + "." + serviceId))
219             {
220                 possibleMatches.add(servicePoint.getExtensionPointId());
221             }
222         }
223         return possibleMatches;
224     }
225
226     public Object JavaDoc getService(String JavaDoc serviceId, Class JavaDoc serviceInterface, Module module)
227     {
228         ServicePoint point = getServicePoint(serviceId, module);
229
230         return point.getService(serviceInterface);
231     }
232
233     public Object JavaDoc getService(Class JavaDoc serviceInterface, Module module)
234     {
235         String JavaDoc key = serviceInterface.getName();
236
237         List JavaDoc servicePoints = (List JavaDoc) _servicePointsByInterfaceClassName.get(key);
238
239         if (servicePoints == null)
240             servicePoints = Collections.EMPTY_LIST;
241
242         ServicePoint point = null;
243         int count = 0;
244
245         Iterator JavaDoc i = servicePoints.iterator();
246         while (i.hasNext())
247         {
248             ServicePoint sp = (ServicePoint) i.next();
249
250             if (!sp.visibleToModule(module))
251                 continue;
252
253             point = sp;
254
255             count++;
256         }
257
258         if (count == 0)
259             throw new ApplicationRuntimeException(ImplMessages
260                     .noServicePointForInterface(serviceInterface));
261
262         if (count > 1)
263             throw new ApplicationRuntimeException(ImplMessages.multipleServicePointsForInterface(
264                     serviceInterface,
265                     servicePoints));
266
267         return point.getService(serviceInterface);
268     }
269
270     public ConfigurationPoint getConfigurationPoint(String JavaDoc configurationId, Module module)
271     {
272         checkShutdown();
273
274         ConfigurationPoint result = (ConfigurationPoint) _configurationPoints.get(configurationId);
275
276         if (result == null)
277             throw new ApplicationRuntimeException(ImplMessages.noSuchConfiguration(configurationId));
278
279         if (!result.visibleToModule(module))
280             throw new ApplicationRuntimeException(ImplMessages.configurationNotVisible(
281                     configurationId,
282                     module));
283
284         return result;
285     }
286
287     public Object JavaDoc getConfiguration(String JavaDoc configurationId, Module module)
288     {
289         ConfigurationPoint point = getConfigurationPoint(configurationId, module);
290
291         return point.getConfiguration();
292     }
293
294     /**
295      * @see org.apache.hivemind.internal.RegistryInfrastructure#getConfiguration(java.lang.Class, org.apache.hivemind.internal.Module)
296      */

297     public Object JavaDoc getConfiguration(Class JavaDoc configurationType, Module module)
298     {
299         String JavaDoc key = configurationType.getName();
300
301         List JavaDoc configurationPoints = (List JavaDoc) _configurationPointsByTypeName.get(key);
302
303         if (configurationPoints == null)
304             configurationPoints = Collections.EMPTY_LIST;
305
306         ConfigurationPoint point = null;
307         int count = 0;
308
309         Iterator JavaDoc i = configurationPoints.iterator();
310         while (i.hasNext())
311         {
312             ConfigurationPoint cp = (ConfigurationPoint) i.next();
313
314             if (!cp.visibleToModule(module))
315                 continue;
316
317             point = cp;
318
319             count++;
320         }
321
322         if (count == 0)
323             throw new ApplicationRuntimeException(ImplMessages
324                     .noConfigurationPointForType(configurationType));
325
326         if (count > 1)
327             throw new ApplicationRuntimeException(ImplMessages.multipleConfigurationPointsForType(
328                     configurationType,
329                     configurationPoints));
330
331         return point.getConfiguration();
332     }
333
334     public String JavaDoc toString()
335     {
336         ToStringBuilder builder = new ToStringBuilder(this);
337
338         builder.append("locale", _locale);
339
340         return builder.toString();
341     }
342
343     public void setShutdownCoordinator(ShutdownCoordinator coordinator)
344     {
345         _shutdownCoordinator = coordinator;
346     }
347
348     /**
349      * Invokes {@link ShutdownCoordinator#shutdown()}, then releases the coordinator, modules and
350      * variable sources.
351      */

352     public synchronized void shutdown()
353     {
354         checkShutdown();
355
356         ServiceSerializationHelper.setServiceSerializationSupport(null);
357
358         // Allow service implementations and such to shutdown.
359

360         ShutdownCoordinator coordinatorService = (ShutdownCoordinator) getService(
361                 "hivemind.ShutdownCoordinator",
362                 ShutdownCoordinator.class,
363                 null);
364
365          coordinatorService.shutdown();
366
367         // TODO: Should this be moved earlier?
368

369         _shutdown = true;
370
371         // Shutdown infrastructure items, such as proxies.
372

373         _shutdownCoordinator.shutdown();
374
375         _servicePoints = null;
376         _servicePointsByInterfaceClassName = null;
377         _configurationPointsByTypeName = null;
378         _configurationPoints = null;
379         _shutdownCoordinator = null;
380         _serviceModelFactories = null;
381         _threadEventNotifier = null;
382         _serviceTokens = null;
383
384         // It is believed that the cache held by PropertyUtils can affect application shutdown
385
// and reload in some servlet containers (such as Tomcat); this should clear that up.
386

387         PropertyUtils.clearCache();
388         
389         synchronized (HiveMind.INTROSPECTOR_MUTEX)
390         {
391             Introspector.flushCaches();
392         }
393     }
394
395     /**
396      * Technically, this should be a synchronized method, but the _shutdown variable hardly ever
397      * changes, and the consequences are pretty minimal. See HIVEMIND-104.
398      */

399
400     private void checkShutdown()
401     {
402         if (_shutdown)
403             throw new ApplicationRuntimeException(HiveMindMessages.registryShutdown());
404     }
405
406     private void checkStarted()
407     {
408         if (_started)
409             throw new IllegalStateException JavaDoc(ImplMessages.registryAlreadyStarted());
410     }
411
412     /**
413      * Starts up the Registry after all service and configuration points have been defined. This
414      * locks down the Registry so that no further extension points may be added. This method may
415      * only be invoked once.
416      * <p>
417      * This instance is stored into
418      * {@link ServiceSerializationHelper#setServiceSerializationSupport(ServiceSerializationSupport)}.
419      * This may cause errors (and incorrect behavior) if multiple Registries exist in a single JVM.
420      * <p>
421      * In addition, the service <code>hivemind.Startup</code> is obtained and <code>run()</code>
422      * is invoked on it. This allows additional startup, provided in the
423      * <code>hivemind.Startup</code> configuration point, to be executed.
424      */

425     public void startup()
426     {
427         checkStarted();
428
429         ServiceSerializationHelper.setServiceSerializationSupport(this);
430
431         _started = true;
432
433         Runnable JavaDoc startup = (Runnable JavaDoc) getService("hivemind.Startup", Runnable JavaDoc.class, null);
434
435         startup.run();
436     }
437
438     public synchronized ServiceModelFactory getServiceModelFactory(String JavaDoc name)
439     {
440         if (_serviceModelFactories == null)
441             readServiceModelFactories();
442
443         ServiceModelFactory result = (ServiceModelFactory) _serviceModelFactories.get(name);
444
445         if (result == null)
446             throw new ApplicationRuntimeException(ImplMessages.unknownServiceModel(name));
447
448         return result;
449     }
450
451     private void readServiceModelFactories()
452     {
453         Map JavaDoc sm = (Map JavaDoc) getConfiguration("hivemind.ServiceModels", null);
454
455         _serviceModelFactories = new HashMap JavaDoc();
456
457         Iterator JavaDoc i = sm.values().iterator();
458
459         while (i.hasNext())
460         {
461             ServiceModelContribution smc = (ServiceModelContribution) i.next();
462
463             String JavaDoc name = smc.getName();
464
465             _serviceModelFactories.put(name, smc.getFactory());
466         }
467     }
468
469     public synchronized void cleanupThread()
470     {
471         if (_threadEventNotifier == null)
472             _threadEventNotifier = (ThreadEventNotifier) getService(
473                     "hivemind.ThreadEventNotifier",
474                     ThreadEventNotifier.class,
475                     null);
476
477         _threadEventNotifier.fireThreadCleanup();
478     }
479
480     public boolean containsConfiguration(String JavaDoc configurationId, Module module)
481     {
482         checkShutdown();
483
484         ConfigurationPoint result = (ConfigurationPoint) _configurationPoints.get(configurationId);
485
486         return result != null && result.visibleToModule(module);
487     }
488
489     public boolean containsService(Class JavaDoc serviceInterface, Module module)
490     {
491         checkShutdown();
492
493         String JavaDoc key = serviceInterface.getName();
494
495         List JavaDoc servicePoints = (List JavaDoc) _servicePointsByInterfaceClassName.get(key);
496
497         if (servicePoints == null)
498             return false;
499
500         int count = 0;
501
502         Iterator JavaDoc i = servicePoints.iterator();
503         while (i.hasNext())
504         {
505             ServicePoint point = (ServicePoint) i.next();
506
507             if (point.visibleToModule(module))
508                 count++;
509         }
510
511         return count == 1;
512     }
513
514     public boolean containsService(String JavaDoc serviceId, Class JavaDoc serviceInterface, Module module)
515     {
516         checkShutdown();
517
518         ServicePoint point = (ServicePoint) _servicePoints.get(serviceId);
519
520         if (point == null)
521             return false;
522
523         return point.visibleToModule(module)
524                 && point.getServiceInterface().equals(serviceInterface);
525     }
526
527     public ErrorHandler getErrorHander()
528     {
529         return _errorHandler;
530     }
531
532     public Object JavaDoc getServiceFromToken(ServiceToken token)
533     {
534         Defense.notNull(token, "token");
535
536         checkShutdown();
537
538         String JavaDoc serviceId = token.getServiceId();
539
540         ServicePoint sp = (ServicePoint) _servicePoints.get(serviceId);
541
542         return sp.getService(Object JavaDoc.class);
543     }
544
545     public synchronized ServiceToken getServiceTokenForService(String JavaDoc serviceId)
546     {
547         Defense.notNull(serviceId, "serviceId");
548
549         checkShutdown();
550
551         if (_serviceTokens == null)
552             _serviceTokens = new HashMap JavaDoc();
553
554         ServiceToken result = (ServiceToken) _serviceTokens.get(serviceId);
555
556         if (result == null)
557         {
558             result = new ServiceToken(serviceId);
559             _serviceTokens.put(serviceId, result);
560         }
561
562         return result;
563     }
564
565     /**
566      * Sets the current RI up as the ServiceSerializationSupport. Any service proxy tokens that are
567      * de-serialized will find their proxies within this Registry.
568      *
569      * @since 1.1
570      */

571
572     public void setupThread()
573     {
574         ServiceSerializationHelper.setServiceSerializationSupport(this);
575     }
576
577     public Module getModule(String JavaDoc moduleId)
578     {
579         return (Module) _modules.get(moduleId);
580     }
581
582     /**
583      * @see org.apache.hivemind.internal.RegistryInfrastructure#getServiceIds(java.lang.Class)
584      */

585     public List JavaDoc getServiceIds(Class JavaDoc serviceInterface)
586     {
587         final List JavaDoc serviceIds = new LinkedList JavaDoc();
588         if( serviceInterface == null )
589         {
590             return serviceIds;
591         }
592         for (Iterator JavaDoc i = _servicePoints.values().iterator(); i.hasNext();)
593         {
594             final ServicePoint servicePoint = (ServicePoint) i.next();
595
596             if (serviceInterface.getName().equals( servicePoint.getServiceInterfaceClassName() )
597                     && servicePoint.visibleToModule(null))
598             {
599                 serviceIds.add(servicePoint.getExtensionPointId());
600             }
601
602         }
603         return serviceIds;
604     }
605
606 }
Popular Tags