All Downloads are FREE. Search and download functionalities are using the official Maven repository.

oms3.Notification Maven / Gradle / Ivy

There is a newer version: 0.10.8
Show newest version
/*
 * $Id$
 * 
 * This software is provided 'as-is', without any express or implied
 * warranty. In no event will the authors be held liable for any damages
 * arising from the use of this software.
 * 
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 * 
 *  1. The origin of this software must not be misrepresented; you must not
 *     claim that you wrote the original software. If you use this software
 *     in a product, an acknowledgment in the product documentation would be
 *     appreciated but is not required.
 * 
 *  2. Altered source versions must be plainly marked as such, and must not be
 *     misrepresented as being the original software.
 * 
 *  3. This notice may not be removed or altered from any source
 *     distribution.
 */
package oms3;

import java.util.EventListener;
import java.util.EventObject;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.event.EventListenerList;

/** Event Notification class. This class handles
 *  Allows the 
 *
 * @author Olaf David ([email protected])
 * @version $Id$ 
 */
public class Notification {

    EventListenerList ll = new EventListenerList();
    
    Controller c;
    /* avoid Event object creation and fire(..) calls if no listeners. */
    boolean shouldFire = false;
    
//    private static Notification instance;
//    
//    public static final Notification instance() {
//        if (instance == null) {
//            instance = new Notification();
//        }
//        return instance;
//    }

    protected static final Logger log = Logger.getLogger("oms3.sim");

    Notification(Controller c) {
        this.c = c;
    }

    final boolean shouldFire() {
        return shouldFire;
    }

    Controller getController() {
        return c;
    }

    void addListener(Listener l) {
        if (log.isLoggable(Level.CONFIG)) {
            log.config("Adding Notification Listener " + l);
        }
        ll.add(Listener.class, l);
        shouldFire = true;
    }

    void removeListener(Listener l) {
        if (log.isLoggable(Level.CONFIG)) {
            log.config("Removing Notification Listener " + l);
        }
        ll.remove(Listener.class, l);
        shouldFire = ll.getListenerCount() > 0;
    }

    private void fire(Type t, EventObject E) {
        Object[] listeners = ll.getListenerList();
        for (int i = listeners.length - 2; i >= 0; i -= 2) {
            ((Listener) listeners[i + 1]).notice(t, E);
        }
    }

    void fireWait(ComponentAccess w) {
        if (shouldFire) {
            fire(Type.WAITING, new ComponentEvent(c, w.getComponent()));
        }
    }

    void fireStart(ComponentAccess w) {
        if (shouldFire) {
            fire(Type.EXECUTING, new ComponentEvent(c, w.getComponent()));
        }
    }

    void fireFinnish(ComponentAccess w) {
        if (shouldFire) {
            fire(Type.FINISHED, new ComponentEvent(c, w.getComponent()));
        }
    }

    void fireException(ComponentException E) {
        if (shouldFire) {
            fire(Type.EXCEPTION, new ExceptionEvent(c, E));
        }
    }

//    void fireConnect(Access srcAccess, Access destAccess) {
//        if (shouldFire) {
//            fire(Type.CONNECT, new ConnectEvent(c, srcAccess, destAccess));
//        }
//    }

//    void fireMapIn(Access srcAccess, Access destAccess) {
//        if (shouldFire) {
//            fire(Type.MAPIN, new ConnectEvent(c, srcAccess, destAccess));
//        }
//    }

//    void fireMapOut(Access srcAccess, Access destAccess) {
//        if (shouldFire) {
//            fire(Type.MAPOUT, new ConnectEvent(c, srcAccess, destAccess));
//        }
//    }

    void fireIn(DataflowEvent e) {
        fire(Type.IN, e);
    }

    void fireOut(DataflowEvent e) {
        fire(Type.OUT, e);
    }

    /** 
     * Notification Types. Thoes values classify an event object.
     */
    public enum Type {

        /**
         * Execution waiting here for all @In to arrive
         * @see ComponentEvent
         */
        WAITING,
        /** A component is about to be executed. 
         * @see ComponentEvent
         */
        EXECUTING,
        /** 
         * A component is done with execution
         * @see ComponentEvent
         */
        FINISHED,
        /** 
         * A components @In field is receiving a value
         * @see ComponentEvent
         */
        IN,
        /** 
         * A components @Out field is providing a value
         * @see ConnectEvent
         */
        OUT,
        /** 
         * Exception was thrown by a component
         * @see ConnectEvent
         */
        EXCEPTION,
        /**
         * An @In field is connected to an out field of a component.
         * @see DataflowEvent
         */
//        CONNECT,
//        /** 
//         * A Component field is mapped to an @In field of
//         * a containing component.
//         * @see DataflowEvent
//         */
//        MAPIN,
//        /** 
//         * A Component field is mapped to an @Out field of
//         * a containing component.
//         * 
//         * @see DataflowEvent
//         */
//        MAPOUT,
//        FIELDIN,
//        FIELDOUT,
//        VALIN
        
    }

    /**
     * Notification Listener.
     */
    public interface Listener extends EventListener {

        /**
         * Called when an event happens.
         * @param t event type
         * @param E the event
         */
        // stateChanged(Type t, EventObject E);
        void notice(Type t, EventObject E);
    }

    /**
     * Connection Event.
     */
    public static class ConnectEvent extends EventObject {

        private static final long serialVersionUID = 1410979580285808419L;
        Access from;
        Access to;

        ConnectEvent(Object src, Access from, Access to) {
            super(src);
            this.from = from;
            this.to = to;
        }

        /**
         * Get the source of the connect event
         * @return the field access object being the connect source
         */
        public Access getFrom() {
            return from;
        }

        /**
         * Get the destination for the connect event.
         *
         * @return the target Field access component.
         */
        public Access getTo() {
            return to;
        }

        @Override
        public String toString() {
            return "Connect: " + from + " -> " + to;
        }
    }

    /**
     * Component Event.
     */
    public static class ComponentEvent extends EventObject {

        private static final long serialVersionUID = -8569599337868335893L;
        Object comp;

        ComponentEvent(Object src, Object comp) {
            super(src);
            this.comp = comp;
        }

        /** Get the component for this event. 
         *
         * @return the component 
         */
        public Object getComponent() {
            return comp;
        }

        @Override
        public String toString() {
            return "Component: " + getComponent();
        }
    }

    /**
     * Exception Event.
     * An exception occured during component execution.
     * 
     */
    public static class ExceptionEvent extends EventObject {

        private static final long serialVersionUID = -1136021018405823527L;
        ComponentException E;

        ExceptionEvent(Object src, ComponentException E) {
            super(src);
            this.E = E;
        }

        /**
         * Get the Component exception.
         * @return the exception
         */
        public ComponentException getException() {
            return E;
        }

        @Override
        public String toString() {
            if (E == null) {
                return "Exception: NULL";
            }
            StringBuffer b = new StringBuffer("\n");
            if (E.getCause() != null) {
                for (StackTraceElement ste : E.getCause().getStackTrace()) {
                    b.append("  " + ste.toString() + "\n");
                }
            }
            return "Exception: " + E.getMessage() + " in '" + E.getSource() + "'" + b.toString();
        }
    }

    /** 
     * Data flow event.
     * 
     */
    public static class DataflowEvent extends EventObject {

        private static final long serialVersionUID = -5551146005283344251L;
        Access data;
        Object value;

        DataflowEvent(Object source, Access data, Object value) {
            super(source);
            this.data = data;
            this.value = value;
        }

        /**
         * Get field access info.
         * Note: if you need to alter the value, do not use the Access object
         * method setFieldValue(). call setValue() on this object instead.
         * @return The field access object
         */
        public Access getAccess() {
            return data;
        }

        /**
         * Get the data value that is passed on @In/@Out
         * @return the data value that is passed around.
         */
        public Object getValue() {
            return value;
        }

        /** This methods allows altering the value being passed from @Out to @In.
         * Call this from within the 'notice' event notification when
         *  you receive this DataflowEvent. An example would be a unit conversion.
         *
         * @param value the altered value.
         */
        public void setValue(Object value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return "Flow: " + data.getComponent() + "@" + data.getField().getName() + " [" + value + "]";
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy