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 }