Package alt.jiapi.event

Source Code of alt.jiapi.event.MethodEventProducer

/*
* Copyright(C) 2001 Mika Riekkinen, Joni Suominen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or(at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

package alt.jiapi.event;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Category;

import alt.jiapi.InstrumentationContext;
import alt.jiapi.InstrumentationDescriptor;
import alt.jiapi.Runtime;

import alt.jiapi.instrumentor.ChainInstrumentor;
import alt.jiapi.instrumentor.InstrumentorChain;
import alt.jiapi.instrumentor.HeadInstrumentor;
import alt.jiapi.instrumentor.Hook;
import alt.jiapi.instrumentor.MethodCallInstrumentor;
import alt.jiapi.instrumentor.MethodDispatcherInstrumentor;
import alt.jiapi.instrumentor.MethodEntryStrategy;
import alt.jiapi.instrumentor.MethodReturnStrategy;
import alt.jiapi.instrumentor.GrepInstrumentor;

/**
* This class registers itself to Jiapi runtime and tracks method
* entries and exits. When either event happens it will notify each
* listeners that has been registered.<p>
*
* If an exception is thrown from a method, the exit event is not produced.
* That is, exit events are produced only for the normal exits from
* methods.
*
* @author Mika Riekkinen
* @author Joni Suominen
* @version $Revision: 1.23 $ $Date: 2004/03/21 12:50:07 $
*/
public class MethodEventProducer extends EventProducer {
//      private static Category log =
//          Runtime.getLogCategory(MethodEventProducer.class);

    private List listeners = new ArrayList();


    /**
     * Constructor. Resolution is set to '*', which indicates all the
     * MethodEvents are produced.
     *
     * @param id Instrumentation decsriptor, that this MethodEventProducer
     *        registers itself to.
     */
    public MethodEventProducer(InstrumentationDescriptor id) {
        this(id, "*");
    }


    /**
     * Creates new MethodEventProducer.
     * Only MethodEvents, that match with given resolution,
     * are produced. Resolution is compared against the name of the
     * method during instrumentation.
     *
     * @param id Instrumentation decsriptor, that this MethodEventProducer
     *        registers itself to.
     * @param resolution Resolution, that is used further to select which
     *        methods will trigger events to be produced.
     */
    public MethodEventProducer(InstrumentationDescriptor id, String resolution) {
        super(resolution);
        if (true) {
            id.addInstrumentor(new MethodEventInstrumentor(this));
            return;
        }

        try {
//             InstrumentationContext ctx = new InstrumentationContext();

            // For method entry traps :
            ChainInstrumentor entryDispatcher = new MethodDispatcherInstrumentor();
            GrepInstrumentor grepEntry =
                new GrepInstrumentor(new MethodEntryStrategy());

//              Instrumentor head0 = new HeadInstrumentor(); // ---

            grepEntry.setResolutions(getResolutions());

            ChainInstrumentor entryCall
                = new MethodCallInstrumentor(new MethodEntryHook(this));

            InstrumentorChain entryChain = new InstrumentorChain();
            entryChain.add(entryDispatcher);
            entryChain.add(grepEntry);
//              entryChain.add(head0);                       // ---
            entryChain.add(entryCall);


            // For method exit traps :
            ChainInstrumentor exitDispatcher = new MethodDispatcherInstrumentor();
            GrepInstrumentor grepExit
                = new GrepInstrumentor(new MethodReturnStrategy());
           
            grepExit.setResolutions(getResolutions());
           
            ChainInstrumentor head = new HeadInstrumentor();
            ChainInstrumentor exitCall =
                new MethodCallInstrumentor(new MethodExitHook(this));
           
            InstrumentorChain exitChain = new InstrumentorChain();
            exitChain.add(exitDispatcher);
            exitChain.add(grepExit);
            exitChain.add(head);
            exitChain.add(exitCall);
               
            // Add chains created
            id.addInstrumentor(entryChain);
            id.addInstrumentor(exitChain);
        }
        catch (Exception e) {
            // NOTE! Fix exception handling.
            e.printStackTrace();
        }
    }


    /**
     * Adds a MethodListener.
     * @param mel a MethodListener
     */
    public synchronized void addMethodListener(MethodListener mel) {
        listeners.add(mel);
    }

    /**
     * Removes a MethodListener.
     * @param mel a MethodListener
     */
    public synchronized void removeMethodListener(MethodListener mel) {
        listeners.remove(mel);
    }

    /**
     * This method is called by the Jiapi runtime. It should not be called
     * by others.
     */
    public void methodEntered(Object sourceObject, String methodName) {
        if (!isProtected(sourceObject)) {
            fireMethodEnterEvent(sourceObject, methodName);
        }
        else {
//              log.debug("sourceObject " + sourceObject +
//                        " was protected. Not firing JiapiEvent.");
        }
    }
   
    /**
     * This method is called by the Jiapi runtime. It should not be called
     * by others.
     */
    public void methodExited(Object sourceObject, String methodName) {
        if (!isProtected(sourceObject)) {
            fireMethodExitEvent(sourceObject, methodName);
        }
        else {
//              log.debug("sourceObject " + sourceObject +
//                        " was protected. Not firing JiapiEvent.");
        }
    }

    /**
     * Fires an event on method entry.
     * @param sourceObject Source Object
     * @param methodName Name of the method
     */
    protected synchronized void fireMethodEnterEvent(Object sourceObject,
                                                     String methodName) {
        Iterator i = listeners.iterator();
        MethodEvent event = new MethodEvent(this, sourceObject, methodName,
                                            MethodEvent.METHOD_ENTERED);
       
        while (i.hasNext()) {
            MethodListener ml = (MethodListener)i.next();
            ml.methodEntered(event);
        }
    }

    /**
     * Fires an event on method exit.
     * @param sourceObject Source Object
     * @param methodName Name of the method
     */
    protected synchronized void fireMethodExitEvent(Object sourceObject,
                                                    String methodName) {
        Iterator i = listeners.iterator();
        MethodEvent event = new MethodEvent(this, sourceObject, methodName,
                                            MethodEvent.METHOD_EXITED);

        while (i.hasNext()) {
            MethodListener ml = (MethodListener)i.next();
            ml.methodExited(event);
        }
    }
}
TOP

Related Classes of alt.jiapi.event.MethodEventProducer

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.