@SuppressWarnings("unchecked") private AroundAdvice createAdvice(NamedFunction f, Method mtd) { Function inner = f.getFunction(); if (inner instanceof JavaDefinedFunction) { final M2tAroundAdvice adviceAnn = mtd.getAnnotation(M2tAroundAdvice.class); final M2tPointcut pointcutAnn = adviceAnn.pointcut(); List<NamedFunction> adviceBodyJavaFunctions = null; if ((adviceBodyJavaFunctions = (List<NamedFunction>) _middleEnd .getExecutionContext() .getContributionStateContext() .retrieveState("AdviceBodyJavaDefinedFunctions")) == null) { adviceBodyJavaFunctions = new ArrayList<NamedFunction>(); _middleEnd .getExecutionContext() .getContributionStateContext() .storeState("AdviceBodyJavaDefinedFunctions", adviceBodyJavaFunctions); } adviceBodyJavaFunctions.add(f); String[] paramTypeNames = pointcutAnn.paramTypeNames(); List<Pair<String, AdviceParamType>> paramTypes = new ArrayList<Pair<String, AdviceParamType>>(); for (int i = 0; i < paramTypeNames.length; i++) { String paramTypeName = paramTypeNames[i]; // TODO make subtype inclusion configurable if (!paramTypeName.equals("*")) { final AdviceParamType paramType = new AdviceParamType(_middleEnd.getTypesystem().findType(paramTypeName), true); final Pair<String, AdviceParamType> paramTypePair = new Pair<String, AdviceParamType>("o" + i + 1, paramType); paramTypes.add(paramTypePair); } } AdviceParamType varArgsAdvParamType = new AdviceParamType( _middleEnd.getTypesystem().findType(ObjectType.INSTANCE.getUniqueRepresentation()), true); final ExecutionPointcut pointcut = new ExecutionPointcut( pointcutAnn.namePattern(), paramTypes, pointcutAnn.hasVarArgs(), null); ExpressionBase body = new MethodInvocationExpression( mtd, Arrays.asList(new LocalVarEvalExpression(SyntaxConstants.THIS_JOINPOINT, null)), false, null); final AroundAdvice adv = new AroundAdvice(body, pointcut, true); return adv; } else { throw new IllegalArgumentException( "Advice definition " + f.getName() + " is not a JavaDefinedFunction"); } }
public ParsedResource parseResource(String resourceName) { final ParsedResource result = new ParsedResource(); if (classAsResource(Object.class).equals(resourceName)) return result; // TODO test imports // TODO test advice // TODO guards final Class<?> cls = getCls(resourceName); for (Method mtd : cls.getDeclaredMethods()) { // register only public methods if (!isPublic(mtd)) continue; if (isInfrastructureMethod(mtd, cls)) continue; if (mtd.getAnnotation(M2tNoFunction.class) != null) continue; final boolean isPublicFunction = (mtd.getAnnotation(M2tPrivateFunction.class) == null && mtd.getAnnotation(M2tAroundAdvice.class) == null); final boolean isAroundAdvice = (mtd.getAnnotation(M2tAroundAdvice.class) != null); final QualifiedName functionName = (mtd.getAnnotation(M2tQualifiedName.class) != null) ? new QualifiedName( cls.getCanonicalName().replaceAll("\\.", SyntaxConstants.NS_DELIM), mtd.getName()) : new QualifiedName(mtd.getName()); final NamedFunction f = new NamedFunction( functionName, new JavaDefinedFunction(mtd, null, _middleEnd.getTypesystem())); if (isPublicFunction) { result.getPublicFunctions().add(f); } else if (isAroundAdvice) { result.getAdvice().add(createAdvice(f, mtd)); } else { result.getPrivateFunctions().add(f); } } final M2tImports importsAnn = cls.getAnnotation(M2tImports.class); if (importsAnn != null) { for (M2tImport imp : importsAnn.imports()) { String impResPath = imp.resource().replaceAll("\\.", SyntaxConstants.NS_DELIM); impResPath.replaceAll("/", SyntaxConstants.NS_DELIM); result.getImports().add(new ImportedResource(impResPath, imp.reexport())); } } return result; }