Package alt.jiapi.instrumentor

Source Code of alt.jiapi.instrumentor.AbstractInstrumentor

/*
* 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.instrumentor;

import java.util.HashMap;

import org.apache.log4j.Category;

import alt.jiapi.reflect.InstructionList;
import alt.jiapi.reflect.JiapiClass;
import alt.jiapi.reflect.JiapiMethod;

/**
* This abstract class is the base class for all the instrumentors
* used by jiapi code.
*
* @author Mika Riekkinen
* @author Joni Suominen
* @version $Revision: 1.1 $ $Date: 2004/03/15 14:45:06 $
*/
public abstract class AbstractInstrumentor implements ChainInstrumentor {
    private Instrumentation instrumentation;
    private static Category log = alt.jiapi.Runtime.getLogCategory(AbstractInstrumentor.class);
    private AbstractInstrumentor child;

    /**
     * Gets an InstrumentorChain, that needs to be processed before
     * current Instrumentor. If an Instrumentor realizes, that in
     * order for its instrumented code to work it needs some other
     * instrumentation support, it may override this method to provide
     * such extra needs.
     *
     * @return A chain, that is to be processed before current Instrumentor,
     *         or null if there is no need for such pre-processing.
     * @see InstrumentorChain
     */
    public InstrumentorChain preInstrument() {
        return null;
    }

    /**
     * Gets an InstrumentorChain, that needs to be processed after
     * current Instrumentor. Instrumentor may do post-instrumentation
     * to clean up or finalize instrumented code. This method is often
     * called in conjunction with preInstrument().
     *
     * @return A chain, that is to be processed after current Instrumentor,
     *         or null if there is no need for such post-processing.
     * @see InstrumentorChain
     */
    public InstrumentorChain postInstrument() {
        return null;
    }

    /**
     * Instruments given InstructionList. Instrumentor is free to modify
     * InstructionList anyway it sees fit. As long as resulting InstructionList
     * is consistent with all the Java Virtual Machine constraints.<p>
     *
     * Some Instrumentors do not modify given InstructionList, but
     * selects a smaller part, splits it into peaces, and forwards them
     * one by one to the next Instrumentor in chain.<p>
     *
     * Once this method returns, control is transferred back to previous
     * Instrumentor in chain.
     *
     * @see #forward(InstructionList)
     */
    public abstract void instrument(InstructionList il);

    /**
     * This method has a package access. It is called by AbstractInstrumentor
     * itself to forward a chain with given Instrumentation.
     */
    void instrument(InstructionList il, Instrumentation i) {
        log.info("Instrumenting with " + this);
        this.instrumentation = i;
        if (i == null) {
            log.error("Got null instrumentation");
        }

        instrument(il);
    }


    public String toString() {
        return this.getClass().getName();
    }

   

//      private HashMap preInstrumentations = new HashMap();
//      private HashMap postInstrumentations = new HashMap();

    /**
     * Forwards given InstructionList to next Instrumentor in chain.
     *
     * @param il InstructionList to forward
     */
    protected void forward(InstructionList il) {
        if (child != null) {
            JiapiClass jc = getCurrentClass();
            child.setCurrentClass(jc);

            InstrumentorChain pre = child.preInstrument();
            if (pre != null) {
//                    if (preInstrumentations.get(jc.getName()) == null) {
                    log.debug("Pre instrumenting with " + pre);
                    //System.out.println(pre + ", " + il.getDeclaringMethod());
                    pre.instrument(jc);
//                        preInstrumentations.put(jc.getName(), jc);
//                    }
            }
            else {
                log.debug(child + " has no need for pre-instrumentation");
            }

            child.instrument(il, instrumentation);

            InstrumentorChain post = child.postInstrument();
            if (post != null) {
//                  if (postInstrumentations.get(jc.getName()) == null) {
                    log.debug("Post instrumenting with " + post);
                    post.instrument(jc);
//                        postInstrumentations.put(jc.getName(), jc);
//                    }
            }
            else {
                log.debug(child + " has no need for post-instrumentation");
            }
        }
    }


    private JiapiClass currentClass;

    /**
     * Gets the current JiapiClass, that instrumentation applies to.
     *
     * @return current class
     */
    protected JiapiClass getCurrentClass() {
        return currentClass;
    }

    /**
     * Sets the current JiapiClass, that instrumentation applies to.
     * This method is used internally by Jiapi framework.
     * @param clazz A JiapiClass to set
     */
    void setCurrentClass(JiapiClass clazz) {
        this.currentClass = clazz;
    }

    // package access, called by chain
//      void setInstrumentation(Instrumentation i) {
//          this.instrumentation = i;
//      }


    /**
     * Gets an instance of Instrumentation related to this chain.
     * This method should only be called from instrument(InstructionList)
     * method.
     * @return Instrumentation or null, if Instrumentation has not been
     *         triggered.
     */
    public Instrumentation getInstrumentation() {
//          if(instrumentation == null) {
//              instrumentation = new Instrumentation();
//          }
          if(instrumentation == null) {
              log.warn("Instrumentation is null: " + this.getClass());
          }

        return instrumentation;
    }



    // package access for now. Purpose of these methods is to provide
    // all the subsequent instrumentors in same descriptor some data
    // this instrumentor is doing. Like 'just grepped 'test.Foo.foo()'
    void setDescriptorData() {
    }
    Object/*SomeDataType*/ getDescriptorData() {
        return null;
    }


    // package access for now. Purpose of these methods is to provide
    // all the subsequent instrumentors within same context some data
    // this instrumentor is doing. Like 'just grepped 'test.Foo.foo()'
    void setContexData() {
    }
    Object/*SomeDataType*/ getContextData() {
        return null;
    }




    // Package access - used to set/get parent-child relations
    void setChild(AbstractInstrumentor i) {
        this.child = i;
    }

    /**
     * Gets the next Instrumentor in chain.
     */
    ChainInstrumentor getChild() {
        return child;
    }
}
TOP

Related Classes of alt.jiapi.instrumentor.AbstractInstrumentor

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.