Package alt.jiapi.event

Source Code of alt.jiapi.event.EventProducer

/*
* 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 alt.jiapi.Rule;

/**
* Base class for event producers.
*
* @author Mika Riekkinen
* @author Joni Suominen
* @version $Revision: 1.9 $ $Date: 2004/03/22 09:04:17 $
*/
public class EventProducer {
    private String[] resolutions;
    private Rule[] rules;

    /**
     * IdentityList is used for locks to avoid StackOverflow
     * in cases where the lock object implements hashCode method
     * which has been instrumented.
     */
    private IdentityList locks = new IdentityList();

    /**
     * Empty constructor. This constructor will set up resolution
     * to its default value "*".
     */
    public EventProducer() {
        this(new String[] {"*"});
    }

    /**
     * This constructor will set up resolution to given value.
     *
     * @param resolution A resolution that is to be used.
     */
    public EventProducer(String resolution) {
        this(new String[] {resolution});
    }

    /**
     * This constructor will set up resolution to given values.
     *
     * @param resolution A resolutions that is to be used.
     */
    public EventProducer(String[] resolutions) {
        this.resolutions = resolutions;
        this.rules = new Rule[resolutions.length];

        for (int i = 0; i < rules.length; i++) {
            try {
                rules[i] = new Rule(resolutions[i]);
            }
            catch(Exception e) {
                System.out.println("Invalid rule: " + e);
            }
        }
    }


    /**
     * Matches a given String into resolution String this EventProducer has.
     * If at least one resolution matches, a true is returned.
     */
    public boolean match(String s) {
        for (int i = 0; i < rules.length; i++) {
            if (rules[i].match(s) == true) {
                return true;
            }
        }

        return false;
    }


    /**
     * Get the resolutions of this EventProducer.
     *
     * @return An array of Strings. Each String represents one
     *         resolution String, that is used in matching.
     */
    public String[] getResolutions() {
        return resolutions;
    }

    /**
     * Checks whether a given sourceObject is in protected mode.
     * if sourceObject is in protected mode, corresponding JiapiEvent
     * should not be fired.
     *
     * @param sourceObject sourceObject to check
     */
    public boolean isProtected(Object sourceObject) {
        return locks.contains(sourceObject);
    }

    /**
     * Checks whether a given JiapiEvent is in protected mode.
     * if JiapiEvent is in protected mode, that event should not
     * be fired.
     *
     * @param je JiapiEvent to check
     */
    public boolean isProtected(JiapiEvent je) {
        Object sourceObject = je.getSourceObject();
        return locks.contains(sourceObject);
    }

    /**
     * This method protects application from entering into
     * recursive event loop. This situation may occur, if a method
     * has been instrumented, and instrumentation produces an
     * event. If that method is called, directly or indirectly,
     * with the aid of JiapiEvent, application will enter to an
     * endless event loop, eventually crashing Virtual Machine.<p>
     *
     * Calling this method prevents <code>EventProducer</code>
     * from producing further events for the same sourceObject.
     * This protection mechanism allows applications to call
     * methods of sourceObject and targetObject without worrying
     * about event loops.<p>
     *
     * To enable events again, one will have to release
     * <code>EventProducer</code> with method <code>release</code>.<p>
     *
     * @see #release(JiapiEvent)
     * @see JiapiEvent#protect()
     */
    public void protect(JiapiEvent je) {
        Object sourceObject = je.getSourceObject();
        locks.add(sourceObject);
    }

    /**
     * This method releases <code>EventProducer</code> so, that
     * it is able to produce more events for the sourceObject.
     *
     * @see #protect(JiapiEvent)
     * @see JiapiEvent#release()
     */
    public void release(JiapiEvent je) {
        Object sourceObject = je.getSourceObject();
        locks.remove(sourceObject);
    }
}

/**
* A List-like implementation where reference-equality is used instead
* of object-equality (i.e. == instead of equals()).
* <p>
* Since only a partial List functionality is needed it was easier
* (and safer) not to implement a List or extend AbstractList. This
* way we don't have to care how the unused methods use the
* entries in the set.
*/
class IdentityList {
    private Object []elementData;
    private int elementCount;

    public IdentityList() {
        elementData = new Object[10];
        elementCount = 0;
    }

    public synchronized void add(Object o) {
        checkCapacity();
        elementData[elementCount++] = o;
    }

    public synchronized void remove(Object o) {
        int index = indexOf(o);

        if (index != -1) {
            removeElementAt(index);
        }
    }

    public synchronized boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

    private int indexOf(Object o) {
        for (int i = 0; i < elementCount; i++) {
            if (o == elementData[i]) {
                return i;
            }
        }
       
        return -1;
    }

    private void removeElementAt(int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                     elementCount);
        }
        else if (index < 0) {
            throw new ArrayIndexOutOfBoundsException(index);
        }

        int j = elementCount - index - 1;
        if (j > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, j);
        }

        elementCount--;
        elementData[elementCount] = null;
    }

    private void checkCapacity() {
        int curCapacity = elementData.length;
        if (elementCount >= curCapacity) {
            Object oldData[] = elementData;
            int newCapacity = curCapacity * 2;
            elementData = new Object[newCapacity];
            System.arraycopy(oldData, 0, elementData, 0, elementCount);
        }
    }
}
TOP

Related Classes of alt.jiapi.event.EventProducer

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.