KickJava   Java API By Example, From Geeks To Geeks.

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


1 // Copyright 2007 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
18 import java.util.ArrayList JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Locale JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.apache.hivemind.ErrorHandler;
26 import org.apache.hivemind.HiveMind;
27 import org.apache.hivemind.ShutdownCoordinator;
28 import org.apache.hivemind.definition.ConfigurationPointDefinition;
29 import org.apache.hivemind.definition.Contribution;
30 import org.apache.hivemind.definition.ContributionContext;
31 import org.apache.hivemind.definition.ImplementationConstructionContext;
32 import org.apache.hivemind.definition.ImplementationConstructor;
33 import org.apache.hivemind.definition.ModuleDefinition;
34 import org.apache.hivemind.definition.RegistryDefinition;
35 import org.apache.hivemind.definition.ServicePointDefinition;
36 import org.apache.hivemind.definition.impl.ModuleDefinitionHelper;
37 import org.apache.hivemind.definition.impl.ModuleDefinitionImpl;
38 import org.apache.hivemind.impl.servicemodel.PooledServiceModelFactory;
39 import org.apache.hivemind.impl.servicemodel.PrimitiveServiceModelFactory;
40 import org.apache.hivemind.impl.servicemodel.SingletonServiceModelFactory;
41 import org.apache.hivemind.impl.servicemodel.ThreadedServiceModelFactory;
42 import org.apache.hivemind.internal.AbstractServiceImplementationConstructor;
43 import org.apache.hivemind.internal.ServiceModel;
44 import org.apache.hivemind.service.Autowiring;
45 import org.apache.hivemind.service.AutowiringStrategy;
46 import org.apache.hivemind.service.ClassFactory;
47 import org.apache.hivemind.service.InterfaceSynthesizer;
48 import org.apache.hivemind.service.ThreadEventNotifier;
49 import org.apache.hivemind.service.ThreadLocalStorage;
50 import org.apache.hivemind.service.ThreadLocale;
51 import org.apache.hivemind.service.impl.AutowiringByTypeStrategy;
52 import org.apache.hivemind.service.impl.AutowiringImpl;
53 import org.apache.hivemind.service.impl.AutowiringStrategyContribution;
54 import org.apache.hivemind.service.impl.ClassFactoryImpl;
55 import org.apache.hivemind.service.impl.EagerLoader;
56 import org.apache.hivemind.service.impl.InterfaceSynthesizerImpl;
57 import org.apache.hivemind.service.impl.ThreadEventNotifierImpl;
58 import org.apache.hivemind.service.impl.ThreadLocalStorageImpl;
59 import org.apache.hivemind.service.impl.ThreadLocaleImpl;
60
61 /**
62  * Loads the core HiveMind services into a registry definition.
63  *
64  * @author Achim Huegen
65  */

66 public class CoreServicesProvider implements RegistryProvider
67 {
68     private ModuleDefinitionHelper helper;
69
70     public void process(RegistryDefinition registryDefinition, ErrorHandler errorHandler)
71
72     {
73         DefaultClassResolver resolver = new DefaultClassResolver();
74
75         // For the sake of backward compatibility add the core
76
// to an existing module that may have been created by the XmlRegistryProvider
77
// This way the core services and the hivemodule.xml from the xml package share
78
// the same module name "hivemind"
79

80         ModuleDefinition md = registryDefinition.getModule("hivemind");
81         if (md == null)
82         {
83             md = new ModuleDefinitionImpl("hivemind", HiveMind.getClassLocation(getClass(), resolver),
84                     resolver, null);
85             registryDefinition.addModule(md);
86         }
87
88         // The cast to ModuleDefinitionImpl is save, since we exactly now the origin
89
helper = new ModuleDefinitionHelper((ModuleDefinitionImpl) md);
90         
91         addClassFactory(md);
92
93         addThreadEventNotifier(md);
94
95         addThreadLocalStorage(md);
96
97         addThreadLocale(md);
98         
99         addStartup(md);
100
101         addEagerLoad(md);
102         
103         addShutdownCoordinator(md);
104
105         addInterfaceSynthesizer(md);
106         
107         addServiceModelConfiguration();
108         
109         addAutowiring(md);
110         
111         addAutowiringStrategiesConfiguration();
112     }
113
114     /**
115      * Wrapper around Javassist used to dynamically create classes such as service interceptors.
116      */

117     private void addClassFactory(ModuleDefinition md)
118     {
119         ServicePointDefinition spd = helper.addServicePoint("ClassFactory", ClassFactory.class.getName());
120         helper.addSimpleServiceImplementation(spd, ClassFactoryImpl.class.getName(), ServiceModel.PRIMITIVE);
121     }
122
123     /**
124      * Service used by other services to be alerted when a thread is cleaned up (typically, at the
125      * end of a request or transaction).
126      */

127     private void addThreadEventNotifier(ModuleDefinition md)
128     {
129         ServicePointDefinition spd = helper.addServicePoint(
130                 "ThreadEventNotifier",
131                 ThreadEventNotifier.class.getName());
132         helper.addSimpleServiceImplementation(
133                 spd,
134                 ThreadEventNotifierImpl.class.getName(),
135                 ServiceModel.SINGLETON);
136     }
137
138     /**
139      * Service which manages a thread-local map of data items. This can be used for temporary
140      * storage of information when local variables can't be used. All stored items are released when
141      * the thread is cleaned up. Note: this service should be considered deprecated; use the
142      * threaded service model instead.
143      */

144     private void addThreadLocalStorage(ModuleDefinition md)
145     {
146         ServicePointDefinition spd = helper.addServicePoint(
147                 "ThreadLocalStorage",
148                 ThreadLocalStorage.class.getName());
149         helper.addSimpleServiceImplementation(spd, ThreadLocalStorageImpl.class.getName(), ServiceModel.THREADED);
150     }
151
152     /**
153      * Stores the locale for the current thread. The default is determined when the Registry is
154      * first constructed. This locale is used for any messages.
155      */

156     private void addThreadLocale(ModuleDefinition md)
157     {
158         ServicePointDefinition spd = helper.addServicePoint("ThreadLocale", ThreadLocale.class.getName());
159
160         // Define inline implementation constructor
161
ImplementationConstructor constructor = new AbstractServiceImplementationConstructor(md.getLocation())
162         {
163
164             public Object JavaDoc constructCoreServiceImplementation(ImplementationConstructionContext context)
165             {
166                 // Get the Locale from the registry
167
Locale JavaDoc defaultLocale = context.getDefiningModule().getLocale();
168                 return new ThreadLocaleImpl(defaultLocale);
169             }
170
171         };
172
173         helper.addServiceImplementation(spd, constructor, ServiceModel.THREADED);
174     }
175     
176     /**
177      * A source of event notifications for when the Registry is shutdown.
178      */

179     private void addShutdownCoordinator(ModuleDefinition md)
180     {
181         ServicePointDefinition spd = helper.addServicePoint("ShutdownCoordinator", ShutdownCoordinator.class.getName());
182         helper.addSimpleServiceImplementation(spd, ShutdownCoordinatorImpl.class.getName(), ServiceModel.SINGLETON);
183     }
184     
185     /**
186      * Service that performs eager loading of other services. This service is contributed into the hivemind.Startup configuration.
187      */

188     private void addEagerLoad(ModuleDefinition md)
189     {
190         ServicePointDefinition spd = helper.addServicePoint("EagerLoad", Runnable JavaDoc.class.getName());
191
192         // Define inline implementation constructor, that wires the EagerLoad configuration
193
ImplementationConstructor constructor = new AbstractServiceImplementationConstructor(md.getLocation())
194         {
195             public Object JavaDoc constructCoreServiceImplementation(ImplementationConstructionContext context)
196             {
197                 EagerLoader result = new EagerLoader();
198                 result.setServicePoints((List JavaDoc) context.getConfiguration("EagerLoad"));
199                 return result;
200             }
201         };
202         helper.addServiceImplementation(spd, constructor, ServiceModel.PRIMITIVE);
203         
204         // Configuration to which services may be contributed. The corresponding services are instantiated eagerly, as the Registry is started.
205
// The order in which services are instantiated is not specified.
206

207         helper.addConfigurationPoint("EagerLoad", List JavaDoc.class.getName());
208     }
209
210     /**
211      * A service which is used to bootstrap HiveMind; it obtains the hivemind.Startup configuration and runs each
212      * Runnable object or service within as the last step of the Registry construction phase.
213      * Note that the execution order is arbitrary and the startup objects are NOT executed in separate threads.
214      */

215     private void addStartup(ModuleDefinition md)
216     {
217         ServicePointDefinition spd = helper.addServicePoint("Startup", Runnable JavaDoc.class.getName());
218
219         // Define inline implementation constructor, that wires the Startup configuration
220
ImplementationConstructor constructor = new AbstractServiceImplementationConstructor(md.getLocation())
221         {
222             public Object JavaDoc constructCoreServiceImplementation(ImplementationConstructionContext context)
223             {
224                 StartupImpl result = new StartupImpl();
225                 result.setRunnables((List JavaDoc) context.getConfiguration("Startup"));
226                 return result;
227             }
228         };
229         helper.addServiceImplementation(spd, constructor, ServiceModel.PRIMITIVE);
230         
231         // A configuration to which startup objects may be contributed (as objects or services).
232
// Startup objects must implement the java.lang.Runnable interface. Order of execution is expliclitly NOT defined.
233

234         ConfigurationPointDefinition cpd = helper.addConfigurationPoint("Startup", List JavaDoc.class.getName());
235         
236         final List JavaDoc services = getDefaultStartupServices();
237         helper.addContributionDefinition(cpd, new Contribution() {
238
239             public void contribute(ContributionContext context)
240             {
241                 List JavaDoc contribution = new ArrayList JavaDoc();
242                 for (Iterator JavaDoc iterServices = services.iterator(); iterServices.hasNext();)
243                 {
244                     String JavaDoc serviceName = (String JavaDoc) iterServices.next();
245                     contribution.add(context.getService(serviceName, Runnable JavaDoc.class));
246                 }
247                 context.mergeContribution(contribution);
248             }});
249     }
250     
251     /**
252      * Defines service models, providing a name and a class for each.
253      */

254     private void addServiceModelConfiguration()
255     {
256
257         ConfigurationPointDefinition cpd = helper.addConfigurationPoint("ServiceModels",
258                 Map JavaDoc.class.getName());
259         
260         final List JavaDoc serviceModels = getDefaultServiceModels();
261         helper.addContributionDefinition(cpd, new Contribution() {
262
263             public void contribute(ContributionContext context)
264             {
265                 Map JavaDoc contribution = new HashMap JavaDoc();
266                 for (Iterator JavaDoc iterServiceModels = serviceModels.iterator(); iterServiceModels.hasNext();)
267                 {
268                     ServiceModelContribution contrib = (ServiceModelContribution) iterServiceModels.next();
269                     contribution.put(contrib.getName(), contrib);
270                 }
271                 context.mergeContribution(contribution);
272             }});
273     }
274     
275     /**
276      * Returns default startup services for addition to "Startup" configuration.
277      */

278     private List JavaDoc getDefaultStartupServices()
279     {
280         List JavaDoc result = new ArrayList JavaDoc();
281         result.add("hivemind.EagerLoad");
282         return result;
283     }
284
285     /**
286      * Returns default service Models as instances of {@link ServiceModelContribution}.
287      */

288     private List JavaDoc getDefaultServiceModels()
289     {
290         List JavaDoc result = new ArrayList JavaDoc();
291         result.add(new ServiceModelContribution(ServiceModel.PRIMITIVE, new PrimitiveServiceModelFactory()));
292         result.add(new ServiceModelContribution(ServiceModel.SINGLETON, new SingletonServiceModelFactory()));
293         result.add(new ServiceModelContribution(ServiceModel.POOLED, new PooledServiceModelFactory()));
294         result.add(new ServiceModelContribution(ServiceModel.THREADED, new ThreadedServiceModelFactory()));
295         return result;
296     }
297
298     /**
299      * Synthesizes a service interface from an ordinary JavaBean.
300      */

301     private void addInterfaceSynthesizer(ModuleDefinition md)
302     {
303         ServicePointDefinition spd = helper.addServicePoint("InterfaceSynthesizer", InterfaceSynthesizer.class.getName());
304
305         // Define inline implementation constructor
306
ImplementationConstructor constructor = new AbstractServiceImplementationConstructor(md.getLocation())
307         {
308             public Object JavaDoc constructCoreServiceImplementation(ImplementationConstructionContext context)
309             {
310                 InterfaceSynthesizerImpl result = new InterfaceSynthesizerImpl();
311                 // Manual wiring of the class factory
312
result.setClassFactory((ClassFactory) context.getService(ClassFactory.class));
313                 return result;
314             }
315         };
316
317         helper.addServiceImplementation(spd, constructor, ServiceModel.SINGLETON);
318     }
319     
320     /**
321       * Service that wires properties of object with services defined in the registry.
322       */

323     private void addAutowiring(ModuleDefinition md)
324     {
325         ServicePointDefinition spd = helper.addServicePoint("Autowiring", Autowiring.class.getName());
326
327         // Define inline implementation constructor, that wires the AutowiringStrategies configuration
328
ImplementationConstructor constructor = new AbstractServiceImplementationConstructor(md.getLocation())
329         {
330             public Object JavaDoc constructCoreServiceImplementation(ImplementationConstructionContext context)
331             {
332                 List JavaDoc strategies = (List JavaDoc) context.getConfiguration("AutowiringStrategies");
333                 Autowiring result = new AutowiringImpl(context.getRegistry(), strategies, context.getDefiningModule().getErrorHandler());
334                 return result;
335             }
336         };
337         helper.addServiceImplementation(spd, constructor, ServiceModel.PRIMITIVE);
338
339     }
340     
341     /**
342      * Defines service models, providing a name and a class for each.
343      */

344     private void addAutowiringStrategiesConfiguration()
345     {
346
347         ConfigurationPointDefinition cpd = helper.addConfigurationPoint("AutowiringStrategies", List JavaDoc.class.getName());
348         
349         final List JavaDoc serviceModels = getDefaultAutowiringStrategies();
350         helper.addContributionDefinition(cpd, new Contribution() {
351
352             public void contribute(ContributionContext context)
353             {
354                 List JavaDoc contribution = new ArrayList JavaDoc();
355                 contribution.addAll(serviceModels);
356                 context.mergeContribution(contribution);
357             }});
358     }
359
360     /**
361      * Returns default service Models as instances of {@link AutowiringStrategyContribution}.
362      */

363     private List JavaDoc getDefaultAutowiringStrategies()
364     {
365         List JavaDoc result = new ArrayList JavaDoc();
366         result.add(new AutowiringStrategyContribution(new AutowiringByTypeStrategy(), AutowiringStrategy.BY_TYPE, null, null));
367         return result;
368     }
369
370  }
371
Popular Tags