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

org.mobicents.fsm.State Maven / Gradle / Ivy

/*
 * JBoss, Home of Professional Open Source
 * Copyright XXXX, Red Hat Middleware LLC, and individual contributors as indicated
 * by the @authors tag. All rights reserved.
 * See the copyright.txt in the distribution for a full listing
 * of individual contributors.
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License, v. 2.0.
 * This program is distributed in the hope that it will be useful, but WITHOUT A
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License,
 * v. 2.0 along with this distribution; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 */

package org.mobicents.fsm;

import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

/**
 * Implements single state of the FSM.
 * 
 * @author kulikov
 */
public class State implements Runnable {
    
    private String name;
    private FSM fsm;
    
    private ArrayList transitions = new ArrayList();
    protected long timeout;
    private long activated;
    
    private StateEventHandler enterEventHandler;
    private StateEventHandler exitEventHandler;
        
    protected State(FSM fsm, String name) {
        this.name = name;
        this.fsm = fsm;
        this.timeout = 0;
    }
    
    public void setOnEnter(StateEventHandler handler) {
        this.enterEventHandler = handler;
    }
    
    public void setOnExit(StateEventHandler handler) {
        this.exitEventHandler = handler;
    }
    
    protected void enter() {
        this.activated = System.currentTimeMillis();
        if (this.enterEventHandler != null) {
            this.enterEventHandler.onEvent(this);
//            new Thread(new EnterAction(this)).start();
        }
        
        //if this is end state we have to cancel timer generator
        if (this == fsm.end) {
            fsm.timer.cancel(false);
        }
    }
    
    protected void leave() {
        activated = 0;
        if (this.exitEventHandler != null) {
//            new Thread(new LeaveAction(this)).start();
            this.exitEventHandler.onEvent(this);
        }
        
        //leaving start state? process started and we need to start time marks scheduler
        //for timeout measurement
        if (this == fsm.start) {
            fsm.timer = fsm.scheduler.scheduleAtFixedRate(fsm, 0, 1, TimeUnit.SECONDS);
        }
    }
    
    protected void tick(long now) {
        if (timeout > 0 && activated > 0 && (now - activated) > timeout) {
            try {
                fsm.signal("timeout");
            } catch (UnknownTransitionException e) {
            }
        }
    }
    
    public String getName() {
        return name;
    }
    
    public FSM getFSM() {
        return fsm;
    }
    
    protected void add(Transition t) {
        transitions.add(t);
    }
    
    /**
     * Signals to leave this state over specified transition
     * 
     * @param name the name of the transition.
     */
    public State signal(String name) throws UnknownTransitionException {
        Transition t = find(name);
        if (t != null) {
            return t.process(this);
        }
        throw new UnknownTransitionException(name);
    }
    
    /**
     * Searches transition with specified name.
     * 
     * @param name the name of the transition.
     * @return the transition or null if not found.
     */
    private Transition find(String name) {
        for (Transition t : transitions) {
            if (t.getName().matches(name)) {
                return t;
            }
        }
        return null;
    }
    
    @Override
    public String toString() {
        return name;
    }

    public void run() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    private class EnterAction implements Runnable {
        private State state;
        
        private EnterAction(State state) {
            this.state = state;
        }
        
        public void run() {
            enterEventHandler.onEvent(state);
        }
    }
    
    private class LeaveAction implements Runnable {
        private State state;
        
        private LeaveAction(State state) {
            this.state = state;
        }
        
        public void run() {
            exitEventHandler.onEvent(state);
        }
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy