package com.ema.common.utils;

import cn.hutool.core.util.StrUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.expression.MethodBasedEvaluationContext;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * 注解工具类
 */
public class AnnotationUtil {


    /**
     * 获取注解
     */
    public static <T extends Annotation> T getAnnotation(ProceedingJoinPoint joinPoint, Class<T> annotationClass) throws NoSuchMethodException {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        return method.getAnnotation(annotationClass);
    }

    /**
     * 解析el表达式
     *
     * @param expression
     * @param joinPoint
     * @return
     */
    public static String analyzeEl(String expression, ProceedingJoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        // 如果没有#号，则直接返回方法名和表达式
        if (!StrUtil.contains(expression, "#")) {
            return method.getName() + ":" + expression;
        }
        // 解析表达式
        DefaultParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
        //定义上下文对象基于方法的执行上下文会将参数自动添加到当前执行上下文的变量中
        // 但是访问就必须通过#前缀，这是与根对象的区别
        MethodBasedEvaluationContext context = new MethodBasedEvaluationContext(joinPoint.getTarget(), method, joinPoint.getArgs(), parameterNameDiscoverer);
        ExpressionParser parser = new SpelExpressionParser();
        return method.getName() + ":" + parser.parseExpression(expression).getValue(context, String.class);
    }
}
