1 17 18 package org.sape.carbon.core.config.interceptor; 19 20 import java.lang.reflect.InvocationTargetException ; 21 import java.lang.reflect.Method ; 22 import java.util.ArrayList ; 23 import java.util.Collection ; 24 25 import org.apache.commons.logging.Log; 26 import org.apache.commons.logging.LogFactory; 27 28 import org.sape.carbon.core.component.Component; 29 import org.sape.carbon.core.component.ComponentConfiguration; 30 import org.sape.carbon.core.component.lifecycle.LifecycleInterceptor; 31 import org.sape.carbon.core.component.proxy.ComponentProxyInvocationHandler; 32 import org.sape.carbon.core.component.proxy.Decorator; 33 import org.sape.carbon.core.component.proxy.Interceptor; 34 import org.sape.carbon.core.component.proxy.Invocation; 35 import org.sape.carbon.core.config.Config; 36 import org.sape.carbon.core.config.ConfigurationException; 37 import org.sape.carbon.core.config.node.Node; 38 import org.sape.carbon.core.config.node.NodeNotFoundException; 39 import org.sape.carbon.core.config.node.event.NodeEventListener; 40 import org.sape.carbon.core.util.reflection.GenericProxy; 41 42 59 public class DefaultConfigurationInterceptor 60 extends GenericProxy 61 implements ConfigurationInterceptor, Interceptor, NodeEventListener { 62 63 private Log log = LogFactory.getLog(this.getClass()); 64 65 66 protected ComponentConfiguration liveConfiguration; 67 68 72 protected ComponentConfiguration workingConfiguration = null; 73 74 75 protected ComponentProxyInvocationHandler proxyInvocationHandler; 76 77 78 protected Component thisComponent; 79 80 81 protected Interceptor nextInterceptor; 82 83 private Thread persistingThread = null; 84 85 94 protected DefaultConfigurationInterceptor( 95 ComponentConfiguration componentConfiguration, 96 ComponentProxyInvocationHandler proxyInvocationHandler, 97 ConfigurationInterceptorConfiguration config) { 98 99 this.liveConfiguration = componentConfiguration; 100 this.proxyInvocationHandler = proxyInvocationHandler; 101 102 if (config.isAutoRefreshComponent()) { 103 try { 104 Config.getInstance().addNodeListener( 105 componentConfiguration.getConfigurationName(), 106 this); 107 } catch (NodeNotFoundException nnfe) { 108 if (log.isWarnEnabled()) { 109 log.warn( 110 "Could not register component [" + 111 componentConfiguration.getConfigurationName() + 112 "] as a listener for its own configuration", 113 nnfe); 114 } 115 } 116 } 117 } 118 119 125 public Class [] getExposedInterfaces() { 126 return new Class [] { 127 ConfigurationInterceptor.class, 128 this.liveConfiguration.getConfigurationInterface()}; 129 } 130 131 136 public void setNextInterceptor(Interceptor interceptor) { 137 this.nextInterceptor = interceptor; 138 } 139 140 143 public void setComponentReference(Component component) { 144 this.thisComponent = component; 145 } 146 147 151 154 public synchronized void persistConfiguration() 155 throws ConfigurationException { 156 157 try { 158 this.persistingThread = Thread.currentThread(); 159 160 Config.getInstance().storeConfiguration( 161 this.liveConfiguration.getConfigurationName(), 162 this.liveConfiguration); 163 164 } finally { 165 this.persistingThread = null; 166 } 167 } 168 169 172 public synchronized void revertConfiguration() { 173 174 this.workingConfiguration = null; 175 176 configureComponent( 177 (ComponentConfiguration) 178 Config. 179 getInstance(). 180 fetchWritableConfiguration( 181 this.liveConfiguration.getConfigurationName())); 182 } 183 184 187 public synchronized void applyConfiguration() { 188 if (this.workingConfiguration != null) { 189 ComponentConfiguration newConfiguration = this.workingConfiguration; 190 this.workingConfiguration = null; 191 192 configureComponent(newConfiguration); 193 } 194 } 195 196 203 public synchronized ComponentConfiguration getWorkingConfiguration() { 204 initializeWorkingConfiguration(); 205 return (ComponentConfiguration) this.workingConfiguration.clone(); 206 } 207 208 215 public synchronized ComponentConfiguration getLiveConfiguration() { 216 return (ComponentConfiguration) this.liveConfiguration.clone(); 217 } 218 219 222 public void refreshConfiguration() { 223 try { 224 Config 225 .getInstance() 226 .fetchNode(this.liveConfiguration.getConfigurationName()) 227 .refresh(); 228 229 } catch (NodeNotFoundException nnfe) { 230 throw new ConfigurationInterceptorException( 231 this.getClass(), 232 "Component's configuration node no longer exists", 233 nnfe); 234 } 235 236 revertConfiguration(); 237 } 238 239 243 253 public Object invoke(Invocation invocation) throws Throwable { 254 255 Object returnValue = this.nextInterceptor.invoke(invocation); 261 262 if (CONFIGURE_METHOD.equals(invocation.getMethod())) { 263 ComponentConfiguration newConfig = 264 (ComponentConfiguration) 265 invocation.getMethodArguments()[0]; 266 267 synchronized (this) { 272 this.liveConfiguration = 275 (ComponentConfiguration) newConfig.clone(); 276 } 277 } 278 279 return returnValue; 280 } 281 282 289 public synchronized void nodeChanged(Node changedNode) { 290 if (this.persistingThread != Thread.currentThread()) { 291 292 ComponentConfiguration newConfig = (ComponentConfiguration) 293 Config.getInstance().fetchWritableConfiguration( 294 this.liveConfiguration.getConfigurationName()); 295 296 configureComponent(newConfig); 297 } 298 } 299 300 301 public void nodeRemoved(String removedNodeName) { 302 } 304 305 309 331 protected Object handleInvoke(Object proxy, Method m, Object [] args) 332 throws Throwable { 333 334 try { 335 if (UNSUPPORTED_OPERATIONS.contains(m.getName())) { 336 throw new UnsupportedOperationException (m.toString()); 337 } 338 339 if (INVOKE_METHOD.equals(m)) { 340 return invoke((Invocation) args[0]); 341 342 } else if (ConfigurationInterceptor.class.isAssignableFrom(m.getDeclaringClass()) 343 || Decorator.class.isAssignableFrom(m.getDeclaringClass())) { 344 345 return m.invoke(this, args); 346 347 } else if (m.getDeclaringClass().isAssignableFrom( 348 this.liveConfiguration.getConfigurationInterface())) { 349 350 synchronized (this) { 351 352 355 if (m.getName().startsWith(GET) 356 || m.getName().startsWith(IS)) { 357 return m.invoke(this.liveConfiguration, args); 360 361 } else { 362 initializeWorkingConfiguration(); 365 return m.invoke(this.workingConfiguration, args); 366 } 367 } 368 369 } else { 370 throw new ConfigurationInterceptorException( 371 this.getClass(), 372 "method not supported: " + m); 373 } 374 375 } catch (IllegalArgumentException iae) { 376 throw new ConfigurationInterceptorException( 377 this.getClass(), 378 "Caught IllegalArgumentException", 379 iae); 380 381 } catch (IllegalAccessException iae) { 382 throw new ConfigurationInterceptorException( 383 this.getClass(), 384 "Caught IllegalAccessException", 385 iae); 386 387 } catch (InvocationTargetException ite) { 388 throw ite.getTargetException(); 390 } 391 392 } 393 394 397 private void initializeWorkingConfiguration() { 398 if (this.workingConfiguration == null) { 399 this.workingConfiguration = 400 (ComponentConfiguration) this.liveConfiguration.clone(); 401 } 402 } 403 404 409 private void configureComponent(ComponentConfiguration newConfiguration) { 410 LifecycleInterceptor lifecycleAssistant = 411 (LifecycleInterceptor) this.thisComponent; 412 413 lifecycleAssistant.configureComponent(newConfiguration); 414 } 415 416 420 421 private static final String SET = "set"; 422 423 424 private static final String GET = "get"; 425 426 427 private static final String IS = "is"; 428 429 430 private static final String CLONE = "clone"; 431 432 433 private static final String GET_DATA_STRUCTURE = "getDataStructure"; 434 435 436 private static final String SET_NAME = "setConfigurationName"; 437 438 439 private static final Collection UNSUPPORTED_OPERATIONS = new ArrayList (); 440 441 442 private static final Method CONFIGURE_METHOD; 443 444 445 private static final Method INVOKE_METHOD; 446 static { 447 UNSUPPORTED_OPERATIONS.add(CLONE); 448 UNSUPPORTED_OPERATIONS.add(GET_DATA_STRUCTURE); 449 UNSUPPORTED_OPERATIONS.add(SET_NAME); 450 451 try { 452 CONFIGURE_METHOD = 453 LifecycleInterceptor.class.getMethod( 454 "configureComponent", 455 new Class [] {ComponentConfiguration.class}); 456 INVOKE_METHOD = 457 Interceptor.class.getMethod( 458 "invoke", 459 new Class [] {Invocation.class}); 460 } catch (NoSuchMethodException nsme) { 461 throw new ConfigurationInterceptorException( 462 DefaultConfigurationInterceptor.class, 463 "caught NoSuchMethodException creating Method object " 464 + "representing LifecycleInterceptor.configureComponent", 465 nsme); 466 } 467 } 468 469 } | Popular Tags |