1 package org.apache.fulcrum.yaafi.framework.component;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.avalon.framework.configuration.Configuration;
23 import org.apache.avalon.framework.configuration.ConfigurationException;
24 import org.apache.avalon.framework.context.Context;
25 import org.apache.avalon.framework.logger.Logger;
26 import org.apache.avalon.framework.parameters.Parameters;
27 import org.apache.avalon.framework.service.ServiceManager;
28 import org.apache.fulcrum.yaafi.framework.role.RoleEntry;
29 import org.apache.fulcrum.yaafi.framework.util.ReadWriteLock;
30 import org.apache.fulcrum.yaafi.framework.util.ToStringBuilder;
31 import org.apache.fulcrum.yaafi.framework.util.Validate;
32
33 /**
34 * This class implements am abstract base service component singleton with
35 * an arbitrary lifecycle.
36 *
37 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
38 */
39
40 public abstract class ServiceComponentImpl
41 implements ServiceComponent
42 {
43 /** the information from the role configuration file */
44 private RoleEntry roleEntry;
45
46 /** the actual implementation class of the service component */
47 private Class implementationClazz;
48
49 /** the instance of the implementation class of the service component */
50 private Object instance;
51
52 /** the proxy of the instance if any */
53 private Object proxy;
54
55 /** the Avalon logger of the container */
56 private Logger parentLogger;
57
58 /** the Avalon logger to be passed to the service component instance */
59 private Logger logger;
60
61 /** The Avalon ServiceManager passed to the service component instance */
62 private ServiceManager serviceManager;
63
64 /** The Avalon Context passed to the service component instance */
65 private Context context;
66
67 /** The Avalon Configuration passed to the service component instance */
68 private Configuration configuration;
69
70 /** The Avalon Parameters passed to the service component instance */
71 private Parameters parameters;
72
73 /** read/write lock to snychronize access to services */
74 private ReadWriteLock readWriteLock;
75
76 /**
77 * Constructor to parse the configuration.
78 *
79 * @param roleEntry The information extracted from the role configuration file
80 * @param parentLogger the logger of the service container
81 * @param logger The logger for the service instance
82 * @param readWriteLock the read/write lock to synchronize access to services
83 */
84 public ServiceComponentImpl(
85 RoleEntry roleEntry, Logger parentLogger, Logger logger, ReadWriteLock readWriteLock )
86 {
87 Validate.notNull( roleEntry, "roleEntry" );
88 Validate.notNull( parentLogger, "parentLogger" );
89 Validate.notNull( logger, "logger" );
90 Validate.notNull( readWriteLock, "readWriteLock" );
91
92 this.roleEntry = roleEntry;
93 this.parentLogger = parentLogger;
94 this.logger = logger;
95 this.readWriteLock = readWriteLock;
96 }
97
98
99
100
101
102 /**
103 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#loadImplemtationClass(java.lang.ClassLoader)
104 */
105 public void loadImplemtationClass(ClassLoader classLoader)
106 throws ClassNotFoundException
107 {
108 ClassLoader currClassLoader = null;
109
110 if( classLoader != null )
111 {
112 currClassLoader = classLoader;
113 }
114 else
115 {
116 currClassLoader = this.getClass().getClassLoader();
117 }
118
119 try
120 {
121 this.implementationClazz = currClassLoader.loadClass(
122 this.getRoleEntry().getImplementationClazzName()
123 );
124 }
125
126 catch(ClassNotFoundException e)
127 {
128 String msg = "Failed to load the implementation class "
129 + this.getRoleEntry().getImplementationClazzName();
130
131 this.getParentLogger().error(msg,e);
132
133 throw e;
134 }
135 }
136
137 /**
138 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#getInstance()
139 */
140 public Object getInstance()
141 throws Exception
142 {
143 if( this.isInstantiated() == false )
144 {
145 this.createInstance();
146 this.incarnateInstance();
147 }
148
149 return this.getRawInstance(true);
150 }
151
152 /**
153 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#incarnate()
154 */
155 public void incarnate() throws Exception
156 {
157 try
158 {
159 if( this.isEarlyInit() )
160 {
161 this.getInstance();
162 }
163 }
164 catch(Throwable t)
165 {
166 String msg = "Failed initialize "
167 + this.getRoleEntry().getImplementationClazzName();
168
169 throw new ConfigurationException(msg,t);
170 }
171 }
172
173 /**
174 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#reconfigure()
175 */
176 public abstract void reconfigure() throws Exception;
177
178 /**
179 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#decommision()
180 */
181 public void decommision() throws Exception
182 {
183 this.instance = null;
184 this.proxy = null;
185 }
186
187 /**
188 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#dispose()
189 */
190 public void dispose()
191 {
192 this.roleEntry = null;
193 this.implementationClazz = null;
194 this.instance = null;
195 this.proxy = null;
196 this.parentLogger = null;
197 this.logger = null;
198 this.serviceManager = null;
199 this.context = null;
200 this.configuration = null;
201 this.parameters = null;
202 this.readWriteLock = null;
203 }
204
205 /**
206 * @param logger The logger to set.
207 */
208 public void setLogger(Logger logger)
209 {
210 this.logger = logger;
211 }
212
213 /**
214 * @param context The context to set.
215 */
216 public void setContext(Context context)
217 {
218 this.context = context;
219 }
220
221 /**
222 * @param serviceManager The serviceManager to set.
223 */
224 public void setServiceManager(ServiceManager serviceManager)
225 {
226 this.serviceManager = serviceManager;
227 }
228
229 /**
230 * @param configuration The configuration to set.
231 */
232 public void setConfiguration(Configuration configuration)
233 {
234 this.configuration = configuration;
235 }
236
237 /**
238 * @param parameters The parameters to set.
239 */
240 public void setParameters(Parameters parameters)
241 {
242 this.parameters = parameters;
243 }
244
245
246
247
248
249 /**
250 * @return Return true if the service is created on startup
251 */
252 public boolean isEarlyInit()
253 {
254 return this.getRoleEntry().isEarlyInit();
255 }
256
257 /**
258 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponent#getName()
259 */
260 public String getName()
261 {
262 return this.getRoleEntry().getName();
263 }
264
265 /**
266 * @return Returns the roleEntry.
267 */
268 public RoleEntry getRoleEntry()
269 {
270 return roleEntry;
271 }
272
273 /**
274 * @return Returns the logger.
275 */
276 public Logger getLogger()
277 {
278 return this.logger;
279 }
280
281 /**
282 * @return Returns the parentLogger.
283 */
284 public Logger getParentLogger()
285 {
286 return parentLogger;
287 }
288
289 /**
290 * @return Returns the implementationClazz.
291 */
292 public Class getImplementationClazz()
293 {
294 return this.implementationClazz;
295 }
296
297 /**
298 * @return Returns the configuration.
299 */
300 public Configuration getConfiguration()
301 {
302 return configuration;
303 }
304
305 /**
306 * @return Returns the context.
307 */
308 public Context getContext()
309 {
310 return context;
311 }
312
313 /**
314 * @return Returns the paramaters.
315 */
316 public Parameters getParamaters()
317 {
318 return parameters;
319 }
320
321 /**
322 * @return Returns the serviceManager.
323 */
324 public ServiceManager getServiceManager()
325 {
326 return serviceManager;
327 }
328
329 /**
330 * @return the shorthand of the service
331 */
332 public String getShorthand()
333 {
334 return roleEntry.getShorthand();
335 }
336
337
338
339
340
341 /**
342 * @see java.lang.Object#toString()
343 */
344 public String toString()
345 {
346 ToStringBuilder toStringBuilder = new ToStringBuilder(this);
347 toStringBuilder.append("roleEntry",this.roleEntry);
348 toStringBuilder.append("instance",this.instance);
349 toStringBuilder.append("proxy",this.proxy);
350 return toStringBuilder.toString();
351 }
352
353 /**
354 * @return Returns <b>true</b> if the service instance was already instantiated.
355 */
356 protected final boolean isInstantiated()
357 {
358 return ( this.instance != null ? true : false );
359 }
360
361 /**
362 * Create an instance of the service component implementation class
363 *
364 * @throws InstantiationException th
365 * @throws IllegalAccessException
366 */
367 protected Object createInstance()
368 throws InstantiationException, IllegalAccessException
369 {
370 if( this.getParentLogger().isDebugEnabled() )
371 {
372 this.getParentLogger().debug( "Instantiating the implementation class for " + this.getShorthand() );
373 }
374
375 this.instance = this.implementationClazz.newInstance();
376 this.proxy = null;
377 return this.instance;
378 }
379
380 /**
381 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponent#incarnate()
382 */
383 protected abstract void incarnateInstance() throws Exception;
384
385 /**
386 * Get either the original service object or the dynamic proxy
387 *
388 * @return Returns the raw instance, i.e. does not incarnate
389 * the instance.
390 */
391 protected Object getRawInstance(boolean useProxy)
392 {
393 if( useProxy && (this.proxy != null) )
394 {
395 return this.proxy;
396 }
397 else
398 {
399 return this.instance;
400 }
401 }
402
403 /**
404 * @param proxy the service proxy instance
405 */
406 protected void setProxyInstance(Object proxy)
407 {
408 this.proxy = proxy;
409 }
410
411 /**
412 * @return Returns the readWriteLock.
413 */
414 protected final ReadWriteLock getReadWriteLock()
415 {
416 return readWriteLock;
417 }
418 }