ru.frostman.web.aop.AopEnhancer.java Source code

Java tutorial

Introduction

Here is the source code for ru.frostman.web.aop.AopEnhancer.java

Source

/******************************************************************************
 * WebJavin - Java Web Framework.                                             *
 *                                                                            *
 * Copyright (c) 2011 - Sergey "Frosman" Lukjanov, me@frostman.ru             *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License");            *
 * you may not use this file except in compliance with the License.           *
 * You may obtain a copy of the License at                                    *
 *                                                                            *
 * http://www.apache.org/licenses/LICENSE-2.0                                 *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 ******************************************************************************/

package ru.frostman.web.aop;

import com.google.common.collect.Lists;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import ru.frostman.web.aop.thr.AopException;

import java.util.List;

/**
 * @author slukjanov aka Frostman
 */
public class AopEnhancer {
    private static final String METHOD_INVOCATION = "ru.frostman.web.aop.MethodInvocation";
    private static final String METHOD_INTERCEPTOR = "ru.frostman.web.aop.AopMethodInterceptor";
    private static final String METHOD_INTERCEPTORS = "ru.frostman.web.aop.MethodInterceptors";

    public static void enhance(CtClass ctClass, List<MethodInterceptor> methodInterceptors) {
        try {
            for (CtMethod method : ctClass.getDeclaredMethods()) {
                if (method.getAnnotation(Interceptor.class) != null) {
                    continue;
                }

                List<MethodInterceptor> interceptors = Lists.newLinkedList();

                for (MethodInterceptor interceptor : methodInterceptors) {
                    if (interceptor.matches(method)) {
                        interceptors.add(interceptor);
                    }
                }

                if (interceptors.size() == 0) {
                    continue;
                }

                CtMethod wrappedMethod = new CtMethod(method, ctClass, null);
                String wrappedName = "$javin$" + method.getName();
                wrappedMethod.setName(wrappedName);
                ctClass.addMethod(wrappedMethod);

                StringBuilder body = new StringBuilder("{");

                body.append(METHOD_INVOCATION).append(" mi = new ").append(METHOD_INVOCATION).append("(")
                        .append("\"").append(ctClass.getName()).append("\", ");

                if (Modifier.isStatic(method.getModifiers())) {
                    body.append("null");
                } else {
                    body.append("$0");
                }
                body.append(", \"").append(method.getName()).append("\", new Class");

                CtClass[] parameterTypes = method.getParameterTypes();

                if (parameterTypes.length != 0) {
                    body.append("[]{");
                    int i = 0;
                    for (CtClass argType : parameterTypes) {
                        body.append(argType.getName()).append(".class");

                        if (i < parameterTypes.length - 1) {
                            body.append(", ");
                        }
                        i++;
                    }
                    body.append("}");
                } else {
                    body.append("[0]");
                }

                body.append(", $args, new ").append(METHOD_INTERCEPTOR).append("[]{");

                int i = 0;
                for (MethodInterceptor methodInterceptor : interceptors) {
                    body.append(METHOD_INTERCEPTORS).append(".getInterceptor(\"")
                            .append(methodInterceptor.getName()).append("\")");

                    if (i < interceptors.size() - 1) {
                        body.append(", ");
                    }
                    i++;
                }

                body.append("});");

                if (!method.getReturnType().equals(CtClass.voidType)) {
                    body.append("return ");
                }
                body.append("($r) mi.proceed();}");

                method.setBody(body.toString());
            }
        } catch (Exception e) {
            throw new AopException("Exception while aop enhancing: " + ctClass, e);
        }
    }
}