001package 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 022import org.apache.avalon.framework.configuration.Configuration; 023import org.apache.avalon.framework.configuration.ConfigurationException; 024import org.apache.avalon.framework.context.Context; 025import org.apache.avalon.framework.logger.Logger; 026import org.apache.avalon.framework.parameters.Parameters; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.fulcrum.yaafi.framework.role.RoleEntry; 029import org.apache.fulcrum.yaafi.framework.util.ToStringBuilder; 030import 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 039public 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 /* (non-Javadoc) 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 /* (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}