KickJava   Java API By Example, From Geeks To Geeks.

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


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.util.Collection JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.hivemind.ApplicationRuntimeException;
24 import org.apache.hivemind.HiveMind;
25 import org.apache.hivemind.Orderable;
26 import org.apache.hivemind.ShutdownCoordinator;
27 import org.apache.hivemind.definition.ImplementationConstructor;
28 import org.apache.hivemind.definition.ImplementationDefinition;
29 import org.apache.hivemind.definition.InterceptorDefinition;
30 import org.apache.hivemind.definition.ServicePointDefinition;
31 import org.apache.hivemind.events.RegistryShutdownListener;
32 import org.apache.hivemind.internal.Module;
33 import org.apache.hivemind.internal.ServiceModel;
34 import org.apache.hivemind.internal.ServiceModelFactory;
35 import org.apache.hivemind.order.Orderer;
36 import org.apache.hivemind.service.InterfaceSynthesizer;
37 import org.apache.hivemind.util.ToStringBuilder;
38
39 /**
40  * Abstract implementation of {@link org.apache.hivemind.internal.ServicePoint}. Provides some of
41  * the machinery for creating new service instances, delegating most of it to the
42  * {@link org.apache.hivemind.internal.ServiceModel} instace for the service.
43  *
44  * @author Howard Lewis Ship
45  */

46 public final class ServicePointImpl extends AbstractExtensionPoint implements
47         ConstructableServicePoint
48 {
49     private Object JavaDoc _service;
50
51     private boolean _building;
52
53     private Class JavaDoc _serviceInterface;
54
55     private Class JavaDoc _declaredInterface;
56
57     private List JavaDoc _orderedInterceptorDefinitions;
58
59     private boolean _interceptorsOrdered;
60
61     private ShutdownCoordinator _shutdownCoordinator;
62
63     private ServiceModel _serviceModelObject;
64     
65     public ServicePointImpl(Module module, ServicePointDefinition definition)
66     {
67         super(module, definition);
68     }
69
70     protected void extendDescription(ToStringBuilder builder)
71     {
72         if (_service != null)
73             builder.append("service", _service);
74
75         builder.append("serviceInterfaceName", getServiceInterfaceClassName());
76         builder.append("serviceModel", getServiceModel());
77         builder.append("interceptorDefinitions", getInterceptorDefinitions());
78
79         if (_building)
80             builder.append("building", _building);
81     }
82
83     public synchronized Class JavaDoc getServiceInterface()
84     {
85         if (_serviceInterface == null)
86             _serviceInterface = lookupServiceInterface();
87
88         return _serviceInterface;
89     }
90
91     public synchronized Class JavaDoc getDeclaredInterface()
92     {
93         if (_declaredInterface == null)
94             _declaredInterface = lookupDeclaredInterface();
95
96         return _declaredInterface;
97     }
98
99     public String JavaDoc getServiceInterfaceClassName()
100     {
101         return getServicePointDefinition().getInterfaceClassName();
102     }
103
104     private Object JavaDoc getInterceptorDefinitions()
105     {
106         return getServicePointDefinition().getInterceptors();
107     }
108
109     private Class JavaDoc lookupDeclaredInterface()
110     {
111         Class JavaDoc result = null;
112
113         try
114         {
115             result = getModule().resolveType(getServiceInterfaceClassName());
116         }
117         catch (Exception JavaDoc ex)
118         {
119             throw new ApplicationRuntimeException(ImplMessages.badInterface(
120                     getServiceInterfaceClassName(),
121                     getExtensionPointId()), getLocation(), ex);
122         }
123
124         return result;
125     }
126
127     private Class JavaDoc lookupServiceInterface()
128     {
129         Class JavaDoc declaredInterface = getDeclaredInterface();
130
131         if (declaredInterface.isInterface())
132             return declaredInterface;
133
134         // Not an interface ... a class. Synthesize an interface from the class itself.
135

136         InterfaceSynthesizer is = (InterfaceSynthesizer) getModule().getService(
137                 HiveMind.INTERFACE_SYNTHESIZER_SERVICE,
138                 InterfaceSynthesizer.class);
139
140         return is.synthesizeInterface(declaredInterface);
141     }
142
143     /**
144      * Invoked by {@link #getService(Class)} to get a service implementation from the
145      * {@link ServiceModel}.
146      * <p>
147      * TODO: I'm concerned that this synchronized method could cause a deadlock. It would take a LOT
148      * (mutually dependent services in multiple threads being realized at the same time).
149      */

150     private synchronized Object JavaDoc getService()
151     {
152         if (_service == null)
153         {
154
155             if (_building)
156                 throw new ApplicationRuntimeException(ImplMessages.recursiveServiceBuild(this));
157
158             _building = true;
159
160             try
161             {
162
163                 ServiceModelFactory factory = getModule().getServiceModelFactory(getServiceModel());
164
165                 _serviceModelObject = factory.createServiceModelForService(this);
166
167                 _service = _serviceModelObject.getService();
168             }
169             finally
170             {
171                 _building = false;
172             }
173         }
174
175         return _service;
176     }
177
178     public Object JavaDoc getService(Class JavaDoc serviceInterface)
179     {
180         Object JavaDoc result = getService();
181
182         if (!serviceInterface.isAssignableFrom(result.getClass()))
183         {
184             throw new ApplicationRuntimeException(ImplMessages.serviceWrongInterface(
185                     this,
186                     serviceInterface), getLocation(), null);
187         }
188
189         return result;
190     }
191
192     public String JavaDoc getServiceModel()
193     {
194         if (getServicePointDefinition() == null)
195             return null;
196
197         return getImplementationDefinition().getServiceModel();
198     }
199
200     public void clearConstructorInformation()
201     {
202         _orderedInterceptorDefinitions = null;
203     }
204
205     // Hm. Does this need to be synchronized?
206

207     /**
208      * @return Ordered list of {@link InterceptorDefinition}s
209      */

210    public List JavaDoc getOrderedInterceptorContributions()
211     {
212         if (!_interceptorsOrdered)
213         {
214             _orderedInterceptorDefinitions = orderInterceptors();
215             _interceptorsOrdered = true;
216         }
217
218         return _orderedInterceptorDefinitions;
219     }
220
221     /**
222      * @return Ordered list of {@link InterceptorDefinition}s
223      */

224     private List JavaDoc orderInterceptors()
225     {
226         Collection JavaDoc interceptorDefinitions = getServicePointDefinition().getInterceptors();
227         if (HiveMind.isEmpty(interceptorDefinitions))
228             return null;
229
230         // Any error logging should go to the extension point
231
// we're constructing.
232

233         Log log = LogFactory.getLog(getExtensionPointId());
234
235         Orderer orderer = new Orderer(log, getModule().getErrorHandler(), ImplMessages
236                 .interceptorContribution());
237
238         Iterator JavaDoc i = interceptorDefinitions.iterator();
239         while (i.hasNext())
240         {
241             InterceptorDefinition sid = (InterceptorDefinition) i.next();
242
243             // Sort them into runtime excecution order. When we build
244
// the interceptor stack we'll apply them in reverse order,
245
// building outward from the core service implementation.
246

247             String JavaDoc precedingNames = null;
248             String JavaDoc followingNames = null;
249             // Check if info about ordering is available
250
if (sid instanceof Orderable) {
251                 Orderable orderable = (Orderable) sid;
252                 precedingNames = orderable.getPrecedingNames();
253                 followingNames = orderable.getFollowingNames();
254             }
255             
256             orderer.add(sid, sid.getName(), precedingNames, followingNames);
257         }
258
259         return orderer.getOrderedObjects();
260     }
261
262     public void setShutdownCoordinator(ShutdownCoordinator coordinator)
263     {
264         _shutdownCoordinator = coordinator;
265     }
266
267     public void addRegistryShutdownListener(RegistryShutdownListener listener)
268     {
269         _shutdownCoordinator.addRegistryShutdownListener(listener);
270     }
271
272     /**
273      * Forces the service into existence.
274      */

275     public void forceServiceInstantiation()
276     {
277         getService();
278
279         _serviceModelObject.instantiateService();
280     }
281
282     /**
283      * Returns the service constructor.
284      */

285
286     public ImplementationConstructor getServiceConstructor()
287     {
288         return getImplementationDefinition().getServiceConstructor();
289     }
290
291     public ImplementationDefinition getImplementationDefinition()
292     {
293         if (getServicePointDefinition().getDefaultImplementation() == null)
294             throw new ApplicationRuntimeException(ImplMessages.servicePointDefinitionWithoutImplementation(getServicePointDefinition()));
295         return getServicePointDefinition().getDefaultImplementation();
296     }
297     
298     /**
299      * @return the service point definition that describes this service point
300      */

301     public ServicePointDefinition getServicePointDefinition()
302     {
303         return (ServicePointDefinition) super.getDefinition();
304     }
305
306
307 }
Popular Tags