/** * Filters the classes to be transformed. * * @param definition the definition * @param classMetaData the meta-data for the class * @param cg the class to filter * @return boolean true if the method should be filtered away */ private boolean classFilter( final AspectWerkzDefinition definition, final ClassMetaData classMetaData, final ClassGen cg) { if (cg.isInterface() || TransformationUtil.hasSuperClass( classMetaData, "org.codehaus.aspectwerkz.attribdef.aspect.Aspect") || TransformationUtil.hasSuperClass( classMetaData, "org.codehaus.aspectwerkz.xmldef.advice.AroundAdvice") || TransformationUtil.hasSuperClass( classMetaData, "org.codehaus.aspectwerkz.xmldef.advice.PreAdvice") || TransformationUtil.hasSuperClass( classMetaData, "org.codehaus.aspectwerkz.xmldef.advice.PostAdvice")) { return true; } String className = cg.getClassName(); if (definition.inExcludePackage(className)) { return true; } if (!definition.inIncludePackage(className)) { return true; } if (definition.hasExecutionPointcut(classMetaData) || definition.hasThrowsPointcut(classMetaData)) { return false; } return true; }
/** * Filters the methods to be transformed. * * @param definition the definition * @param classMetaData the class meta-data * @param method the method to filter * @return boolean */ private boolean methodFilter( final AspectWerkzDefinition definition, final ClassMetaData classMetaData, final MethodMetaData methodMetaData, final Method method) { if (method.isAbstract() || method.isNative() || method.getName().equals("<init>") || method.getName().equals("<clinit>") || method.getName().startsWith(TransformationUtil.ORIGINAL_METHOD_PREFIX) || method.getName().equals(TransformationUtil.GET_META_DATA_METHOD) || method.getName().equals(TransformationUtil.SET_META_DATA_METHOD) || method.getName().equals(TransformationUtil.CLASS_LOOKUP_METHOD) || method.getName().equals(TransformationUtil.GET_UUID_METHOD)) { return true; } else if (definition.hasExecutionPointcut(classMetaData, methodMetaData)) { return false; } else if (definition.hasThrowsPointcut(classMetaData, methodMetaData)) { return false; } else { return true; } }
/** * Makes the member method transformations. * * @param context the transformation context * @param klass the class set. */ public void transformCode(final Context context, final Klass klass) { // loop over all the definitions for (Iterator it = m_definitions.iterator(); it.hasNext(); ) { AspectWerkzDefinition definition = (AspectWerkzDefinition) it.next(); definition.loadAspects(context.getLoader()); final ClassGen cg = klass.getClassGen(); ClassMetaData classMetaData = BcelMetaDataMaker.createClassMetaData(context.getJavaClass(cg)); if (classFilter(definition, classMetaData, cg)) { return; } final InstructionFactory factory = new InstructionFactory(cg); final ConstantPoolGen cpg = cg.getConstantPool(); final Method[] methods = cg.getMethods(); // get the indexes for the <init> methods List initIndexes = new ArrayList(); for (int i = 0; i < methods.length; i++) { if (methods[i].getName().equals("<init>")) { initIndexes.add(new Integer(i)); } } // build and sort the method lookup list final List methodLookupList = new ArrayList(); for (int i = 0; i < methods.length; i++) { MethodMetaData methodMetaData = BcelMetaDataMaker.createMethodMetaData(methods[i]); if (methodFilter(definition, classMetaData, methodMetaData, methods[i])) { continue; } methodLookupList.add(methods[i]); } Collections.sort(methodLookupList, BCELMethodComparator.getInstance()); final Map methodSequences = new HashMap(); final List proxyMethods = new ArrayList(); boolean isClassAdvised = false; for (int i = 0; i < methods.length; i++) { MethodMetaData methodMetaData = BcelMetaDataMaker.createMethodMetaData(methods[i]); // filter the methods if (methodFilter(definition, classMetaData, methodMetaData, methods[i]) || methods[i].isStatic()) { continue; } isClassAdvised = true; final MethodGen mg = new MethodGen(methods[i], cg.getClassName(), cpg); // take care of identification of overloaded methods by inserting a sequence number if (methodSequences.containsKey(methods[i].getName())) { int sequence = ((Integer) methodSequences.get(methods[i].getName())).intValue(); methodSequences.remove(methods[i].getName()); sequence++; methodSequences.put(methods[i].getName(), new Integer(sequence)); } else { methodSequences.put(methods[i].getName(), new Integer(1)); } final int methodLookupId = methodLookupList.indexOf(methods[i]); final int methodSequence = ((Integer) methodSequences.get(methods[i].getName())).intValue(); // handleCallToOverriddenSuperClassMethod(mg, cg, cpg, factory, methodSequence, context); addJoinPointField(cpg, cg, mg, methodSequence); // get the join point controller final String controllerClassName = definition.getJoinPointController(classMetaData, methodMetaData); // advise all the constructors for (Iterator it2 = initIndexes.iterator(); it2.hasNext(); ) { final int initIndex = ((Integer) it2.next()).intValue(); methods[initIndex] = createJoinPointField(cpg, cg, methods[initIndex], methods[i], factory, methodSequence) .getMethod(); } proxyMethods.add( createProxyMethod( cpg, cg, mg, factory, methodLookupId, methodSequence, methods[i].getAccessFlags(), definition.getUuid(), controllerClassName)); methods[i] = addPrefixToMethod(mg, methods[i], methodSequence, definition.getUuid()); mg.setMaxStack(); } if (isClassAdvised) { context.markAsAdvised(); // update the old methods cg.setMethods(methods); // add the proxy methods for (Iterator it2 = proxyMethods.iterator(); it2.hasNext(); ) { cg.addMethod((Method) it2.next()); } } } }