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