/* */ package org.jboss.aop;
/* */
/* */ import gnu.trove.TLongObjectHashMap;
/* */ import java.lang.reflect.Constructor;
/* */ import java.security.AccessController;
/* */ import java.security.PrivilegedActionException;
/* */ import java.security.PrivilegedExceptionAction;
/* */ import java.util.ArrayList;
/* */ import java.util.Collection;
/* */ import java.util.Iterator;
/* */ import java.util.WeakHashMap;
/* */ import javassist.ClassPool;
/* */ import javassist.CodeConverter;
/* */ import javassist.CtClass;
/* */ import javassist.CtField;
/* */ import javassist.NotFoundException;
/* */ import org.jboss.aop.advice.Interceptor;
/* */ import org.jboss.aop.instrument.DynamicTransformationObserver;
/* */ import org.jboss.aop.instrument.HotSwapper;
/* */ import org.jboss.aop.instrument.Instrumentor;
/* */ import org.jboss.aop.instrument.InstrumentorFactory;
/* */ import org.jboss.aop.instrument.JoinpointClassifier;
/* */ import org.jboss.aop.instrument.JoinpointFullClassifier;
/* */ import org.jboss.aop.instrument.JoinpointStatusUpdate;
/* */ import org.jboss.aop.instrument.JoinpointStatusUpdate.ClassJoinpoints;
/* */
/* */ public class HotSwapStrategy
/* */ implements DynamicAOPStrategy
/* */ {
/* */ private HotSwapper hotSwapper;
/* */ private Collection joinpointUpdates;
/* */ private Instrumentor instrumentor;
/* */
/* */ public HotSwapStrategy(HotSwapper hotSwapper)
/* */ {
/* 69 */ this.hotSwapper = hotSwapper;
/* 70 */ this.joinpointUpdates = new ArrayList();
/* 71 */ this.instrumentor = InstrumentorFactory.getInstrumentor(AspectManager.instance(), getJoinpointClassifier());
/* */ }
/* */
/* */ public synchronized void interceptorChainsUpdated()
/* */ {
/* 83 */ synchronized (this.joinpointUpdates)
/* */ {
/* 85 */ if (!this.joinpointUpdates.isEmpty())
/* */ {
/* 87 */ this.instrumentor.interceptorChainsUpdated(new ArrayList(this.joinpointUpdates), this.hotSwapper);
/* 88 */ this.joinpointUpdates.clear();
/* */ }
/* */ }
/* */ }
/* */
/* */ public JoinpointClassifier getJoinpointClassifier()
/* */ {
/* 100 */ return new JoinpointFullClassifier();
/* */ }
/* */
/* */ public DynamicTransformationObserver getDynamicTransformationObserver(CtClass clazz)
/* */ {
/* 121 */ return new DynamicTransformationTracker(clazz);
/* */ }
/* */
/* */ public InterceptorChainObserver getInterceptorChainObserver(Class clazz)
/* */ {
/* 130 */ ClassPool classPool = AspectManager.instance().findClassPool(clazz.getClassLoader());
/* 131 */ CtClass ctClass = null;
/* */ try
/* */ {
/* 134 */ ctClass = classPool.get(clazz.getName());
/* */ }
/* */ catch (NotFoundException e) {
/* 137 */ throw new RuntimeException("Class " + clazz.getName() + " was not found at class pool.");
/* */ }
/* 139 */ return new JoinpointStatusUpdater(ctClass);
/* */ }
/* */
/* */ private synchronized void newJoinpointUpdate(JoinpointStatusUpdate update)
/* */ {
/* 151 */ synchronized (this.joinpointUpdates)
/* */ {
/* 153 */ this.joinpointUpdates.add(update);
/* */ }
/* */ }
/* */
/* */ private class JoinpointStatusUpdater
/* */ implements InterceptorChainObserver
/* */ {
/* */ private JoinpointStatusUpdate.ClassJoinpoints newlyAdvised;
/* */ private JoinpointStatusUpdate.ClassJoinpoints newlyUnadvised;
/* */ private int instanceInterceptors;
/* */ private WeakHashMap instanceAdvisors;
/* */ private CtClass clazz;
/* */ private int fields;
/* */ private int constructors;
/* */ private int methods;
/* */ private Interceptor[][] fieldReadInterceptors;
/* */ private Interceptor[][] fieldWriteInterceptors;
/* */ private Interceptor[][] constructorInterceptors;
/* */ private TLongObjectHashMap methodInterceptors;
/* */ private int[] constructorIndexMap;
/* */
/* */ public JoinpointStatusUpdater(CtClass clazz)
/* */ {
/* 259 */ this.clazz = clazz;
/* 260 */ this.instanceAdvisors = new WeakHashMap();
/* */ }
/* */
/* */ public synchronized void initialInterceptorChains(Class reflectionClass, Interceptor[][] fieldReadInterceptors, Interceptor[][] fieldWriteInterceptors, Interceptor[][] constructorInterceptors, TLongObjectHashMap methodInterceptors)
/* */ {
/* 270 */ Constructor[] declaredConstructors = null;
/* 271 */ if (System.getSecurityManager() == null)
/* */ {
/* 273 */ declaredConstructors = reflectionClass.getDeclaredConstructors();
/* */ }
/* */ else
/* */ {
/* */ try
/* */ {
/* 279 */ declaredConstructors = (Constructor[])AccessController.doPrivileged(new PrivilegedExceptionAction(reflectionClass)
/* */ {
/* */ public Constructor[] run()
/* */ throws Exception
/* */ {
/* 284 */ return this.val$reflectionClass.getDeclaredConstructors();
/* */ }
/* */ });
/* */ }
/* */ catch (PrivilegedActionException e) {
/* 290 */ throw new RuntimeException("Error retrieving declared constructors of " + reflectionClass.getName(), e.getException());
/* */ }
/* */
/* */ }
/* */
/* 296 */ this.constructorIndexMap = new int[declaredConstructors.length];
/* 297 */ int javassistIndex = 0;
/* 298 */ for (int reflectionIndex = 0; reflectionIndex < declaredConstructors.length; reflectionIndex++)
/* */ {
/* 300 */ Class[] params = declaredConstructors[reflectionIndex].getParameterTypes();
/* 301 */ if ((params.length > 0) && (params[(params.length - 1)].getName().equals("javassist.runtime.Inner")))
/* */ {
/* 303 */ this.constructorIndexMap[reflectionIndex] = -1;
/* */ }
/* */ else
/* */ {
/* 308 */ this.constructorIndexMap[reflectionIndex] = (javassistIndex++);
/* */ }
/* */ }
/* */
/* 312 */ this.fieldReadInterceptors = fieldReadInterceptors;
/* 313 */ this.fieldWriteInterceptors = fieldWriteInterceptors;
/* 314 */ this.constructorInterceptors = constructorInterceptors;
/* 315 */ this.methodInterceptors = methodInterceptors;
/* 316 */ this.fields = fieldReadInterceptors.length;
/* 317 */ this.constructors = constructorInterceptors.length;
/* 318 */ this.methods = methodInterceptors.size();
/* 319 */ this.newlyAdvised = new JoinpointStatusUpdate.ClassJoinpoints(this.fields, this.constructors, this.methods);
/* 320 */ this.newlyUnadvised = new JoinpointStatusUpdate.ClassJoinpoints(this.fields, this.constructors, this.methods);
/* */ }
/* */
/* */ public synchronized void interceptorChainsUpdated(Interceptor[][] newFieldReadInterceptors, Interceptor[][] newFieldWriteInterceptors, Interceptor[][] newConstructorInterceptors, TLongObjectHashMap newMethodInterceptors)
/* */ {
/* 330 */ if (this.instanceInterceptors == 0)
/* */ {
/* 332 */ long[] methodKeys = this.methodInterceptors.keys();
/* 333 */ for (int i = 0; i < methodKeys.length; i++)
/* */ {
/* 335 */ long key = methodKeys[i];
/* 336 */ MethodInfo oldMethodInfo = (MethodInfo)this.methodInterceptors.get(key);
/* 337 */ MethodInfo newMethodInfo = (MethodInfo)newMethodInterceptors.get(key);
/* 338 */ if ((oldMethodInfo.getInterceptorChain().isEmpty()) && (!newMethodInfo.getInterceptorChain().isEmpty()))
/* */ {
/* 340 */ this.newlyAdvised.methodExecutions.add(newMethodInfo);
/* */ } else {
/* 342 */ if ((oldMethodInfo.getInterceptorChain().isEmpty()) || (!newMethodInfo.getInterceptorChain().isEmpty()))
/* */ continue;
/* 344 */ this.newlyUnadvised.methodExecutions.add(newMethodInfo);
/* */ }
/* */ }
/* 347 */ fillNewStateCollections(this.fieldReadInterceptors, newFieldReadInterceptors, this.newlyAdvised.fieldReads, this.newlyUnadvised.fieldReads, null);
/* 348 */ fillNewStateCollections(this.fieldWriteInterceptors, newFieldWriteInterceptors, this.newlyAdvised.fieldWrites, this.newlyUnadvised.fieldWrites, null);
/* 349 */ fillNewStateCollections(this.constructorInterceptors, newConstructorInterceptors, this.newlyAdvised.constructorExecutions, this.newlyUnadvised.constructorExecutions, this.constructorIndexMap);
/* 350 */ HotSwapStrategy.this.newJoinpointUpdate(getJoinpointStatusUpdate());
/* */ }
/* 352 */ this.fieldReadInterceptors = newFieldReadInterceptors;
/* 353 */ this.fieldWriteInterceptors = newFieldWriteInterceptors;
/* 354 */ this.constructorInterceptors = newConstructorInterceptors;
/* 355 */ this.methodInterceptors = newMethodInterceptors;
/* */ }
/* */
/* */ public synchronized void instanceInterceptorAdded(InstanceAdvisor instanceAdvisor)
/* */ {
/* 364 */ instanceInterceptorsAdded(instanceAdvisor, 1);
/* */ }
/* */
/* */ public synchronized void instanceInterceptorsAdded(InstanceAdvisor instanceAdvisor, int howMany)
/* */ {
/* 373 */ updateInstanceInterceptorsTable(instanceAdvisor, howMany);
/* 374 */ updateAdvisenessStatus(this.newlyAdvised);
/* 375 */ this.instanceInterceptors += howMany;
/* 376 */ HotSwapStrategy.this.interceptorChainsUpdated();
/* */ }
/* */
/* */ public synchronized void instanceInterceptorRemoved(InstanceAdvisor instanceAdvisor)
/* */ {
/* 385 */ instanceInterceptorsRemoved(instanceAdvisor, 1);
/* */ }
/* */
/* */ public synchronized void instanceInterceptorsRemoved(InstanceAdvisor instanceAdvisor, int howMany)
/* */ {
/* 394 */ updateInstanceInterceptorsTable(instanceAdvisor, -howMany);
/* 395 */ this.instanceInterceptors -= howMany;
/* 396 */ updateAdvisenessStatus(this.newlyUnadvised);
/* 397 */ HotSwapStrategy.this.interceptorChainsUpdated();
/* */ }
/* */
/* */ public synchronized void allInstanceInterceptorsRemoved(InstanceAdvisor instanceAdvisor)
/* */ {
/* 406 */ if (this.instanceAdvisors.containsKey(instanceAdvisor))
/* */ {
/* 408 */ this.instanceAdvisors.remove(instanceAdvisor);
/* */ }
/* 410 */ if (this.instanceInterceptors == 0)
/* 411 */ return;
/* 412 */ this.instanceInterceptors = 0;
/* 413 */ for (Iterator iterator = this.instanceAdvisors.values().iterator(); iterator.hasNext(); )
/* */ {
/* 415 */ Integer interceptors = (Integer)iterator.next();
/* 416 */ this.instanceInterceptors += interceptors.intValue();
/* */ }
/* 418 */ if (this.instanceInterceptors > 0)
/* 419 */ return;
/* 420 */ updateAdvisenessStatus(this.newlyUnadvised);
/* 421 */ HotSwapStrategy.this.interceptorChainsUpdated();
/* */ }
/* */
/* */ private JoinpointStatusUpdate getJoinpointStatusUpdate()
/* */ {
/* 430 */ JoinpointStatusUpdate update = new JoinpointStatusUpdate();
/* 431 */ update.clazz = this.clazz;
/* 432 */ update.newlyAdvisedJoinpoints = this.newlyAdvised;
/* 433 */ update.newlyUnadvisedJoinpoints = this.newlyUnadvised;
/* 434 */ this.newlyAdvised = new JoinpointStatusUpdate.ClassJoinpoints(this.fields, this.constructors, this.methods);
/* 435 */ this.newlyUnadvised = new JoinpointStatusUpdate.ClassJoinpoints(this.fields, this.constructors, this.methods);
/* 436 */ return update;
/* */ }
/* */
/* */ private void fillNewStateCollections(Interceptor[][] interceptors, Interceptor[][] newInterceptors, Collection newlyAdvised, Collection newlyUnadvised, int[] indexMap)
/* */ {
/* 451 */ if (this.instanceInterceptors > 0)
/* 452 */ return;
/* 453 */ for (int i = 0; i < interceptors.length; i++) {
/* 454 */ Interceptor[] oldInterceptorsChain = interceptors[i];
/* 455 */ Interceptor[] newInterceptorsChain = newInterceptors[i];
/* 456 */ boolean interceptedBefore = (oldInterceptorsChain != null) && (oldInterceptorsChain.length > 0);
/* 457 */ boolean interceptedNow = (newInterceptorsChain != null) && (newInterceptorsChain.length > 0);
/* 458 */ if ((!interceptedBefore) && (interceptedNow))
/* */ {
/* 460 */ if (indexMap != null)
/* */ {
/* 462 */ if (indexMap[i] == -1)
/* */ continue;
/* 464 */ newlyAdvised.add(new Integer(indexMap[i]));
/* */ }
/* */ else
/* */ {
/* 469 */ newlyAdvised.add(new Integer(i));
/* */ }
/* */ }
/* */ else {
/* 473 */ if ((!interceptedBefore) || (interceptedNow))
/* */ continue;
/* 475 */ if (indexMap != null)
/* */ {
/* 477 */ if (indexMap[i] == -1)
/* */ continue;
/* 479 */ newlyUnadvised.add(new Integer(indexMap[i]));
/* */ }
/* */ else
/* */ {
/* 484 */ newlyUnadvised.add(new Integer(i));
/* */ }
/* */ }
/* */ }
/* */ }
/* */
/* */ private void updateInstanceInterceptorsTable(InstanceAdvisor instanceAdvisor, int interceptorsAdded)
/* */ {
/* 499 */ if (this.instanceAdvisors.containsKey(instanceAdvisor))
/* */ {
/* 501 */ Integer interceptors = (Integer)this.instanceAdvisors.get(instanceAdvisor);
/* 502 */ this.instanceAdvisors.put(instanceAdvisor, new Integer(interceptors.intValue() + interceptorsAdded));
/* */ }
/* */ else
/* */ {
/* 506 */ this.instanceAdvisors.put(instanceAdvisor, new Integer(interceptorsAdded));
/* */ }
/* */ }
/* */
/* */ private void updateAdvisenessStatus(JoinpointStatusUpdate.ClassJoinpoints joinpoints)
/* */ {
/* 518 */ if (this.instanceInterceptors == 0)
/* */ {
/* 520 */ long[] methodKeys = this.methodInterceptors.keys();
/* 521 */ for (int i = 0; i < methodKeys.length; i++)
/* */ {
/* 523 */ long key = methodKeys[i];
/* 524 */ MethodInfo methodInfo = (MethodInfo)this.methodInterceptors.get(key);
/* 525 */ if (!methodInfo.getInterceptorChain().isEmpty())
/* */ continue;
/* 527 */ joinpoints.methodExecutions.add(methodInfo);
/* */ }
/* */
/* 530 */ findUnadvisedJoinpoints(this.fieldReadInterceptors, joinpoints.fieldReads);
/* 531 */ findUnadvisedJoinpoints(this.fieldWriteInterceptors, joinpoints.fieldWrites);
/* 532 */ findUnadvisedJoinpoints(this.constructorInterceptors, joinpoints.constructorExecutions);
/* 533 */ HotSwapStrategy.this.newJoinpointUpdate(getJoinpointStatusUpdate());
/* */ }
/* */ }
/* */
/* */ private void findUnadvisedJoinpoints(Interceptor[][] interceptors, Collection joinpointsFound)
/* */ {
/* 544 */ for (int i = 0; i < interceptors.length; i++)
/* */ {
/* 546 */ if ((interceptors[i] != null) && (interceptors[i].length != 0))
/* */ continue;
/* 548 */ joinpointsFound.add(new Integer(i));
/* */ }
/* */ }
/* */ }
/* */
/* */ private class DynamicTransformationTracker
/* */ implements DynamicTransformationObserver
/* */ {
/* */ private CtClass clazz;
/* */ private Collection fieldReads;
/* */ private Collection fieldWrites;
/* */ private boolean constructor;
/* */
/* */ public DynamicTransformationTracker(CtClass clazz)
/* */ {
/* 177 */ this.clazz = clazz;
/* 178 */ this.fieldReads = new ArrayList();
/* 179 */ this.fieldWrites = new ArrayList();
/* 180 */ this.constructor = false;
/* */ }
/* */
/* */ public void fieldReadDynamicalyWrapped(CtField field)
/* */ {
/* 192 */ this.fieldReads.add(field);
/* */ }
/* */
/* */ public void fieldWriteDynamicalyWrapped(CtField field)
/* */ {
/* 204 */ this.fieldWrites.add(field);
/* */ }
/* */
/* */ public void constructorDynamicalyWrapped()
/* */ {
/* 215 */ this.constructor = true;
/* */ }
/* */
/* */ public void transformationFinished(CtClass clazz, CodeConverter converter)
/* */ {
/* 223 */ if ((this.constructor) || (!this.fieldReads.isEmpty()) || (!this.fieldWrites.isEmpty()))
/* */ {
/* 225 */ HotSwapStrategy.this.instrumentor.convertProcessedClasses(HotSwapStrategy.this.hotSwapper, clazz, this.fieldReads, this.fieldWrites, this.constructor);
/* */ }
/* */ }
/* */ }
/* */ }
/* Location: /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name: org.jboss.aop.HotSwapStrategy
* JD-Core Version: 0.6.0
*/