| 1 17 18 package org.sape.carbon.core.component.proxy; 19 20 import java.lang.reflect.InvocationTargetException ; 21 import java.lang.reflect.Method ; 22 import java.util.ArrayList ; 23 import java.util.Arrays ; 24 import java.util.HashMap ; 25 import java.util.List ; 26 import java.util.Map ; 27 28 import org.sape.carbon.core.component.Component; 29 import org.sape.carbon.core.component.FunctionalInterface; 30 import org.sape.carbon.core.util.reflection.ClassUtil; 31 import org.sape.carbon.core.util.reflection.GenericProxy; 32 import org.sape.carbon.core.util.thread.ReadWriteLock; 33 import org.sape.carbon.core.util.thread.ReentrantWriterPreferenceReadWriteLock; 34 35 import org.apache.commons.logging.Log; 36 import org.apache.commons.logging.LogFactory; 37 38 39 61 public class DefaultComponentProxyInvocationHandler 62 extends GenericProxy 63 implements ComponentProxyInvocationHandler { 64 65 66 71 protected Map delegatesByInterface = new HashMap (); 72 73 79 protected List interceptors = new ArrayList (); 80 81 85 protected Interceptor headInterceptor; 86 87 88 private static Method GET_COMPONENT_NAME_METHOD; 89 90 91 private Log log = 92 LogFactory.getLog(this.getClass()); 93 94 95 96 static { 97 try { 98 GET_COMPONENT_NAME_METHOD = 99 Component.class.getMethod( 100 "getComponentName", 101 new Class [] {}); 102 } catch (NoSuchMethodException nsme) { 103 } 105 } 106 107 118 private final ReadWriteLock monitor = 119 new ReentrantWriterPreferenceReadWriteLock(); 120 121 124 protected FunctionalInterface functionalImplementation; 125 126 127 protected String componentName = null; 128 129 137 public void addDecorator(Decorator decorator) { 138 addDelegate( 139 ClassUtil.getSuperInterfaces(decorator.getExposedInterfaces()), 140 decorator); 141 } 142 143 157 public void setFunctionalImplementation( 158 Class [] implementedInterfaces, 159 FunctionalInterface functionalImplementation) { 160 161 addDelegate( 162 implementedInterfaces, 163 functionalImplementation); 164 165 this.functionalImplementation = functionalImplementation; 166 167 } 168 169 170 177 protected void addDelegate( 178 Class [] representedInterfaces, 179 Object delegate) { 180 181 if (log.isTraceEnabled()) { 182 log.trace("Adding delegate [" 183 + delegate.getClass().getName() 184 + "] for interfaces " 185 + Arrays.asList(representedInterfaces)); 186 } 187 188 189 190 191 for (int i = 0; i < representedInterfaces.length; i++) { 192 Class currentInterface = representedInterfaces[i]; 193 194 Object previousDelegate = 196 this.delegatesByInterface.put( 197 currentInterface, 198 delegate); 199 200 if (previousDelegate != null) { 203 204 if (log.isWarnEnabled()) { 205 log.warn( 206 "Multiple delegates represent the same interface. " 207 + "Conflicting delegates: [" 208 + previousDelegate.getClass().getName() 209 + "," 210 + delegate.getClass().getName() 211 + "], using the latter"); 212 } 213 } 214 } 215 216 if (delegate instanceof Interceptor) { 218 if (log.isTraceEnabled()) { 219 log.trace( 220 "Recognized interceptor [" 221 + delegate.getClass().getName() 222 + "], adding to chain."); 223 } 224 addInterceptor((Interceptor) delegate); 225 } 226 } 227 228 233 private void addInterceptor(Interceptor interceptor) { 234 235 if (log.isTraceEnabled()) { 236 log.trace( 237 "Adding Interceptor to chain [" 238 + interceptor.getClass().getName() 239 + "]"); 240 } 241 if (!this.interceptors.isEmpty()) { 242 Interceptor previousInterceptor = 243 (Interceptor) 244 this.interceptors.get(this.interceptors.size() - 1); 245 246 previousInterceptor.setNextInterceptor(interceptor); 247 } 248 249 this.interceptors.add(interceptor); 250 251 if (this.headInterceptor == null) { 252 this.headInterceptor = interceptor; 253 } 254 255 } 256 257 263 public Object getDelegate(Class delegateInterface) { 264 return this.delegatesByInterface.get(delegateInterface); 265 } 266 267 272 public ReadWriteLock getMonitor() { 273 return this.monitor; 274 } 275 276 281 public String getComponentName() { 282 return this.componentName; 283 } 284 285 290 public void setComponentName(String componentName) { 291 this.componentName = componentName; 292 } 293 294 312 protected Object handleInvoke(Object proxy, Method method, Object [] args) 313 throws Throwable { 314 315 if (GET_COMPONENT_NAME_METHOD.equals(method)) { 317 return getComponentName(); 318 } 319 320 Class subjectInterface = method.getDeclaringClass(); 321 322 Object target = getDelegate(subjectInterface); 323 if (target == null) { 324 } 326 327 Invocation invocation = 328 new Invocation( 329 target, 330 method, 331 args, 332 method.getParameterTypes(), 333 target == this.functionalImplementation); 334 335 Object result = null; 336 337 boolean lockAquired = false; 338 if (target == this.functionalImplementation) { 339 this.monitor.readLock().acquire(); 340 lockAquired = true; 341 } 342 343 try { 344 345 result = this.headInterceptor.invoke(invocation); 346 347 } catch (InvocationTargetException ite) { 348 throw ite.getTargetException(); 350 351 } finally { 352 if (lockAquired) { 353 this.monitor.readLock().release(); 354 } 355 } 356 357 return result; 358 } 359 360 366 protected String proxyToString(Object proxy) { 367 return getComponentName(); 368 } 369 370 } 371 | Popular Tags |