Package alt.jiapi.event

Source Code of alt.jiapi.event.FieldEventProducer

/*
* 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 alt.jiapi.InstrumentationContext;
import alt.jiapi.InstrumentationDescriptor;

import alt.jiapi.instrumentor.ChainInstrumentor;
import alt.jiapi.instrumentor.InstrumentorChain;

import alt.jiapi.instrumentor.FieldAccessStrategy;
import alt.jiapi.instrumentor.HeadInstrumentor;
import alt.jiapi.instrumentor.Hook;
import alt.jiapi.instrumentor.MethodDispatcherInstrumentor;
import alt.jiapi.instrumentor.MethodCallInstrumentor;
import alt.jiapi.instrumentor.GrepInstrumentor;
import alt.jiapi.instrumentor.TailInstrumentor;

/**
* This class registers itself to Jiapi runtime and tracks field
* accesses. That is, gets and sets. When either event happens it will
* notify each listeners that has been registered.
*
* @author Mika Riekkinen
* @author Joni Suominen
* @version $Revision: 1.10 $ $Date: 2004/03/21 12:50:07 $
*/
public class FieldEventProducer extends EventProducer {
    private List listeners = new ArrayList();


    /**
     * Constructor. Resolution is set to '*', which indicates all field
     * accesses are trapped.
     *
     * @param id Instrumentation decsriptor, that this FieldEventProducer
     *        registers itself to.
     */
    public FieldEventProducer(InstrumentationDescriptor id) {
        this(id, "*");
    }

    /**
     * Constructor. Given resolution is compared to name of the field,
     * and if it matches, a FieldEvent is produced.
     *
     * @param id Instrumentation decsriptor, that this FieldEventProducer
     *        registers itself to.
     * @param resolution Resolution that is used in deciding whether or not
     *        an event should be produced.
     */
    public FieldEventProducer(InstrumentationDescriptor id, String resolution) {
        super(resolution);
        id.addInstrumentor(new FieldEventInstrumentor(this));

        if (true) {
            return;
        }

        try {
//             InstrumentationContext ctx = new InstrumentationContext();
            ChainInstrumentor setDispatcher = new MethodDispatcherInstrumentor();

            GrepInstrumentor grepWriteAccess =
            // Following line fixes bug that we instrument
            // on field accesses that were synthesized by Jiapi itself.
                new GrepInstrumentor(new FieldAccessStrategy("*__jiapi_field*", true, FieldAccessStrategy.WRITE_ACCESS));

            grepWriteAccess.setResolutions(getResolutions());

            ChainInstrumentor afterSet = new TailInstrumentor();
            ChainInstrumentor callFieldSet =
                new MethodCallInstrumentor(new FieldSetHook(this));
           
            InstrumentorChain setChain = new InstrumentorChain();
            setChain.add(setDispatcher);
            setChain.add(grepWriteAccess);
            setChain.add(afterSet);
            setChain.add(callFieldSet);


            ChainInstrumentor getDispatcher = new MethodDispatcherInstrumentor();
            GrepInstrumentor grepReadAccess =
            // Following commented line fixes bug that we instrument
            // on field accesses that were synthesized by Jiapi itself.
                  new GrepInstrumentor(new FieldAccessStrategy("*__jiapi_field*", true, FieldAccessStrategy.READ_ACCESS));

            grepReadAccess.setResolutions(getResolutions());

            ChainInstrumentor beforeRead = new HeadInstrumentor();
            ChainInstrumentor callFieldGet =
                new MethodCallInstrumentor(new FieldGetHook(this));

            InstrumentorChain getChain = new InstrumentorChain();
            getChain.add(getDispatcher);
            getChain.add(grepReadAccess);
            getChain.add(beforeRead);
            getChain.add(callFieldGet);


            id.addInstrumentor(getChain);
            id.addInstrumentor(setChain);
        } catch (Exception e) {
            // NOTE! Fix exception handling.
            e.printStackTrace();
        }
    }


    /**
     * Adds a FieldListener.
     * @param fl a FieldListener
     */
    public synchronized void addFieldListener(FieldListener fl) {
        listeners.add(fl);
    }

    /**
     * Removes a FieldListener.
     * @param fl a FieldListener
     */
    public synchronized void removeFieldListener(FieldListener fl) {
        listeners.remove(fl);
    }

    /**
     * This method is called by the Jiapi runtime. It should not be called
     * by others.
     */
    public void fieldGet(Object sourceObject, String fieldName) {
        if (!isProtected(sourceObject)) {
            fireFieldGetEvent(sourceObject, fieldName);
        }
    }
   
    /**
     * This method is called by the Jiapi runtime. It should not be called
     * by others.
     */
    public void fieldSet(Object sourceObject, String fieldName) {
        if (!isProtected(sourceObject)) {
            fireFieldSetEvent(sourceObject, fieldName);
        }
    }

    /**
     * Fires an event when a field has been accessed(set).
     *
     * @param sourceObject
     * @param fieldName Name of the field
     */
    protected synchronized void fireFieldSetEvent(Object sourceObject,
                                                  String fieldName) {
        Iterator i = listeners.iterator();
        FieldEvent event = new FieldEvent(this, sourceObject, fieldName,
                                          FieldEvent.FIELD_SET);
       
        while (i.hasNext()) {
            FieldListener fl = (FieldListener)i.next();
            fl.fieldSet(event);
        }
    }

    /**
     * Fires an event when a field has been accessed(get).
     *
     * @param sourceObject
     * @param fieldName Name of the field
     */
    protected synchronized void fireFieldGetEvent(Object sourceObject,
                                                  String fieldName) {
        Iterator i = listeners.iterator();
        FieldEvent event = new FieldEvent(this, sourceObject, fieldName,
                                          FieldEvent.FIELD_GET);

        while (i.hasNext()) {
            FieldListener fl = (FieldListener)i.next();
            fl.fieldGet(event);
        }
    }
}
TOP

Related Classes of alt.jiapi.event.FieldEventProducer

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.