001 package org.apache.fulcrum.yaafi.framework.component;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import org.apache.avalon.framework.configuration.Configuration;
023 import org.apache.avalon.framework.configuration.ConfigurationException;
024 import org.apache.avalon.framework.context.Context;
025 import org.apache.avalon.framework.logger.Logger;
026 import org.apache.avalon.framework.parameters.Parameters;
027 import org.apache.avalon.framework.service.ServiceManager;
028 import org.apache.fulcrum.yaafi.framework.role.RoleEntry;
029 import org.apache.fulcrum.yaafi.framework.util.ToStringBuilder;
030 import org.apache.fulcrum.yaafi.framework.util.Validate;
031
032 /**
033 * This class implements am abstract base service component singleton with
034 * an arbitrary lifecycle.
035 *
036 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
037 */
038
039 public abstract class ServiceComponentImpl
040 implements ServiceComponent
041 {
042 /** the information from the role configuration file */
043 private RoleEntry roleEntry;
044
045 /** the actual implementation class of the service component */
046 private Class implementationClazz;
047
048 /** the instance of the implementation class of the service component */
049 private Object instance;
050
051 /** the proxy of the instance if any */
052 private Object proxy;
053
054 /** the Avalon logger of the container */
055 private Logger parentLogger;
056
057 /** the Avalon logger to be passed to the service component instance */
058 private Logger logger;
059
060 /** The Avalon ServiceManager passed to the service component instance */
061 private ServiceManager serviceManager;
062
063 /** The Avalon Context passed to the service component instance */
064 private Context context;
065
066 /** The Avalon Configuration passed to the service component instance */
067 private Configuration configuration;
068
069 /** The Avalon Parameters passed to the service component instance */
070 private Parameters parameters;
071
072 /**
073 * Constructor to parse the configuration.
074 *
075 * @param roleEntry The information extracted from the role configuration file
076 * @param parentLogger the logger of the service container
077 * @param logger The logger for the service instance
078 */
079 public ServiceComponentImpl(
080 RoleEntry roleEntry, Logger parentLogger, Logger logger)
081 {
082 Validate.notNull( roleEntry, "roleEntry" );
083 Validate.notNull( parentLogger, "parentLogger" );
084 Validate.notNull( logger, "logger" );
085
086 this.roleEntry = roleEntry;
087 this.parentLogger = parentLogger;
088 this.logger = logger;
089 }
090
091 /////////////////////////////////////////////////////////////////////////
092 // Service Component Lifecycle Implementation
093 /////////////////////////////////////////////////////////////////////////
094
095 /**
096 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#loadImplemtationClass(java.lang.ClassLoader)
097 */
098 public void loadImplemtationClass(ClassLoader classLoader)
099 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 /**
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 /**
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 /**
167 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponentLifecycle#reconfigure()
168 */
169 public abstract void reconfigure() throws Exception;
170
171 /**
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 /**
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 /**
198 * @param logger The logger to set.
199 */
200 public void setLogger(Logger logger)
201 {
202 this.logger = logger;
203 }
204
205 /**
206 * @param context The context to set.
207 */
208 public void setContext(Context context)
209 {
210 this.context = context;
211 }
212
213 /**
214 * @param serviceManager The serviceManager to set.
215 */
216 public void setServiceManager(ServiceManager serviceManager)
217 {
218 this.serviceManager = serviceManager;
219 }
220
221 /**
222 * @param configuration The configuration to set.
223 */
224 public void setConfiguration(Configuration configuration)
225 {
226 this.configuration = configuration;
227 }
228
229 /**
230 * @param parameters The parameters to set.
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 /**
250 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponent#getName()
251 */
252 public String getName()
253 {
254 return this.getRoleEntry().getName();
255 }
256
257 /**
258 * @return Returns the roleEntry.
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 paramaters.
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 /**
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 * @throws InstantiationException th
357 * @throws IllegalAccessException
358 */
359 protected Object createInstance()
360 throws InstantiationException, IllegalAccessException
361 {
362 if( this.getParentLogger().isDebugEnabled() )
363 {
364 this.getParentLogger().debug( "Instantiating the implementation class for " + this.getShorthand() );
365 }
366
367 this.instance = this.implementationClazz.newInstance();
368 this.proxy = null;
369 return this.instance;
370 }
371
372 /**
373 * @see org.apache.fulcrum.yaafi.framework.component.ServiceComponent#incarnate()
374 */
375 protected abstract void incarnateInstance() throws Exception;
376
377 /**
378 * Get either the original service object or the dynamic proxy
379 *
380 * @return Returns the raw instance, i.e. does not incarnate
381 * the instance.
382 */
383 protected Object getRawInstance(boolean useProxy)
384 {
385 if( useProxy && (this.proxy != null) )
386 {
387 return this.proxy;
388 }
389 else
390 {
391 return this.instance;
392 }
393 }
394
395 /**
396 * @param proxy the service proxy instance
397 */
398 protected void setProxyInstance(Object proxy)
399 {
400 this.proxy = proxy;
401 }
402 }