Package org.codehaus.aspectwerkz.cflow

Source Code of org.codehaus.aspectwerkz.cflow.CflowBinding

/**************************************************************************************

* Copyright (c) Jonas Bon�r, Alexandre Vasseur. All rights reserved.                 *

* http://aspectwerkz.codehaus.org                                                    *

* ---------------------------------------------------------------------------------- *

* The software in this package is published under the terms of the LGPL license      *

* a copy of which has been included with this distribution in the license.txt file.  *

**************************************************************************************/

package org.codehaus.aspectwerkz.cflow;



import org.codehaus.aspectwerkz.expression.ExpressionInfo;

import org.codehaus.aspectwerkz.definition.SystemDefinition;

import org.codehaus.aspectwerkz.definition.AspectDefinition;

import org.codehaus.aspectwerkz.definition.AdviceDefinition;

import org.codehaus.aspectwerkz.reflect.impl.java.JavaClassInfo;

import org.codehaus.aspectwerkz.reflect.ClassInfo;

import org.codehaus.aspectwerkz.reflect.MethodInfo;

import org.codehaus.aspectwerkz.aspect.AdviceType;



import java.util.List;

import java.util.ArrayList;



/**

* A Cflow binding represents an extracted cflow or cflowbelow subexpression

* <p/>

* For a given pointcut "pcA and cflowA or cflowbelowB", we will extract two bindings.

* The m_cflowID must be unique on a per cflow sub expresion basis ie JVM wide.

* <p/>

* Note: CflowBinding hashcode depends on Cflow_ID (sub expr) + isCflowBelow only.

*

* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>

*/

public class CflowBinding {



    /**

     * the base implementation that hosts the cflow advices

     */

    private final static ClassInfo ABSTRACT_CFLOWCLASS = JavaClassInfo.getClassInfo(AbstractCflowSystemAspect.class);

    private final static MethodInfo CFLOW_ENTER_ADVICE;

    private final static MethodInfo CFLOW_EXIT_ADVICE;

    static {

        MethodInfo enter = null;

        MethodInfo exit = null;

        for (int i = 0; i < ABSTRACT_CFLOWCLASS.getMethods().length; i++) {

            MethodInfo methodInfo = ABSTRACT_CFLOWCLASS.getMethods()[i];

            if (methodInfo.getName().equals("enter")) {

                enter = methodInfo;

            } else if (methodInfo.getName().equals("exit")) {

                exit = methodInfo;

            }

        }

        if (enter == null || exit == null) {

            throw new Error("Could not gather cflow advices from " + AbstractCflowSystemAspect.class);

        } else {

            CFLOW_ENTER_ADVICE = enter;

            CFLOW_EXIT_ADVICE = exit;

        }

    }



    /**

     * cflow unique id

     */

    private int m_cflowID;



    /**

     * pointcut that represents this cflow sub-expression

     */

    private ExpressionInfo m_cflowSubExpression;



    /**

     * pointcut that represents the containing expression

     */

    private ExpressionInfo m_outerExpression;



    /**

     * marker if this binding is a cflow below, not used at the moment

     */

    private boolean m_isCflowBelow;



    /**

     * Cosntructs a new cflow binding

     *

     * @param cflowID

     * @param cflowSubExpression

     * @param isCflowBelow

     */

    public CflowBinding(int cflowID, ExpressionInfo cflowSubExpression, ExpressionInfo outerExpression, boolean isCflowBelow) {

        m_cflowID = cflowID;

        m_cflowSubExpression = cflowSubExpression;

        m_outerExpression = outerExpression;

        m_isCflowBelow = isCflowBelow;

    }



    /**

     * @return the sub expression

     */

    public ExpressionInfo getExpression() {

        return m_cflowSubExpression;

    }



    /**

     * Extract the cflow bindings from any pointcut

     * This includes both cflow and cflowbelow

     *

     * @param expressionInfo the pointcut expression frow where to extract the cflow bindings

     * @return a list of CflowBinding, can be empty

     */

    public static List getCflowBindingsForCflowOf(ExpressionInfo expressionInfo) {

        List cflowBindings = new ArrayList();

        if (expressionInfo != null) {

            expressionInfo.getCflowAspectExpression().populateCflowAspectBindings(cflowBindings);

        }

        return cflowBindings;

    }



    /**

     * Create an aspect definition for this cflow binding in the given system.

     * The cflow jit aspects will gets compiled and loaded

     *

     * @param systemDefinition

     * @param loader

     * @return the cflow aspect definition

     */

    public AspectDefinition getAspectDefinition(SystemDefinition systemDefinition, ClassLoader loader) {

        String aspectName = CflowCompiler.getCflowAspectClassName(m_cflowID);



        // check if we have already register this aspect

        // TODO: it may happen that the aspect gets register somewhere up in the hierarchy ??

        // it is optim only



        // TODO: how to do this class define lazyly and not pass in a classloader ?

        // could be done in the JIT jp clinit when 1+ advice has a cflow binding

        Class aspectClass = CflowCompiler.compileCflowAspectAndAttachToClassLoader(loader, m_cflowID);

        ClassInfo cflowAspectInfo = JavaClassInfo.getClassInfo(aspectClass);



        AspectDefinition aspectDef = new AspectDefinition(

                aspectName.replace('/', '.'),

                cflowAspectInfo,

                systemDefinition

        );

        aspectDef.addBeforeAdviceDefinition(

                new AdviceDefinition(

                        CFLOW_ENTER_ADVICE.getName(),

                        AdviceType.BEFORE,

                        null,

                        aspectName,

                        aspectName,

                        m_cflowSubExpression,

                        CFLOW_ENTER_ADVICE,

                        aspectDef

                )

        );

        aspectDef.addAfterAdviceDefinition(

                new AdviceDefinition(

                        CFLOW_EXIT_ADVICE.getName(),

                        AdviceType.AFTER_FINALLY,

                        null,

                        aspectName,

                        aspectName,

                        m_cflowSubExpression,

                        CFLOW_EXIT_ADVICE,

                        aspectDef

                )

        );



        return aspectDef;

    }



    public boolean isCflowBelow() {

        return m_isCflowBelow;

    }



    public int getCflowID() {

        return m_cflowID;

    }



    public boolean equals(Object o) {

        if (this == o) return true;

        if (!(o instanceof CflowBinding)) return false;



        final CflowBinding cflowBinding = (CflowBinding) o;



        if (m_cflowID != cflowBinding.m_cflowID) return false;

        if (m_isCflowBelow != cflowBinding.m_isCflowBelow) return false;



        return true;

    }



    public int hashCode() {

        int result;

        result = m_cflowID;

        result = 29 * result + (m_isCflowBelow ? 1 : 0);

        return result;

    }

}

TOP

Related Classes of org.codehaus.aspectwerkz.cflow.CflowBinding

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.