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

org.coos.javaframe.TraceObject Maven / Gradle / Ivy

There is a newer version: 1.3.1
Show newest version
/**
 * COOS - Connected Objects Operating System (www.connectedobjects.org).
 *
 * Copyright (C) 2009 Telenor ASA and Tellu AS. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * 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 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 program.  If not, see .
 *
 * You may also contact one of the following for additional information:
 * Telenor ASA, Snaroyveien 30, N-1331 Fornebu, Norway (www.telenor.no)
 * Tellu AS, Hagalokkveien 13, N-1383 Asker, Norway (www.tellu.no)
 */
package org.coos.javaframe;

import java.util.Calendar;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import org.coos.actorframe.XmlBuilder;
import org.coos.actorframe.messages.AFConstants;
import org.coos.javaframe.messages.AFPropertyMsg;
import org.coos.javaframe.messages.ActorMsg;
import org.coos.javaframe.messages.Message;

/**
 * This class contains information for transition of a state machine. The trace level may be set both on state machine level and
 * what part of the transition to be logged. This trace specification can be set by sending Actor messages to a state machine.
 * 
 * @author Geir Melby, Tellu AS
 */
public class TraceObject implements AFConstants {

    private static int counter = 0;
    private int transitionId = 0;

    protected ActorMsg inputSignal; // The input signal that triggered the transition
    private String inputSignalSender;
    private String inputSignalReceiver;
    private long inputSignalMsgRef;
    protected String currentState; // The state of the state machine before the
    // transition
    protected String newState; // The state after the transition. May be same
    // as currentState.
    String task; // Text written by the transition.
    protected Vector outputSignals; // Output signals that are sent during the
    // transition
    protected Hashtable timers; // Output signals that are sent during the
    // transition
    Vector errors; // Errors set during the transition
    Vector warnings; // Warnings set during the transition
    Hashtable portOutSignals; // Signals sent out of the Port.
    Hashtable portInSignals; // Signals received by the Port.
    String portTask; // Task executed in the Port
    boolean traceFlag = true;

    /* Defined trace categories that shall be traces for this actor */
    int traceCategories;
    /* Defined trace levels that shall be traced for this actor */
    int traceLevel;
    /* Used to format the timestamp. */
    Calendar timeFormatter;

    private Logger logger;

    private StateMachine curfsm = null;

    /**
     * Used when automatic testing is performed to avoid unnecessary print outs
     */
    private boolean outputDisabled = false;

    public TraceObject() {
        initTrace("org.coos.actorframe");
    }

    /**
     * @deprecated not used
     */
    public TraceObject(StateMachine curfsm) {
        initTrace(curfsm.getClass().toString());
        this.curfsm = curfsm;
    }

    /**
     * @deprecated not used
     */
    public TraceObject(ActorAddress actor) {
        String ac = actor.getActorID();
        initTrace(ac.replace('/', '.'));
    }

    /**
     * @deprecated not used
     */
    public TraceObject(ActorAddress actor, ActorMsg inputSignal, String currentState) {
        initTrace(actor.getActorID().replace('/', '.'));
    }

    /*
     * Called from the constructors
     */
    private void initTrace(String loggerName) {
        outputSignals = new Vector();
        portOutSignals = new Hashtable();
        portInSignals = new Hashtable();
        timeFormatter = Calendar.getInstance();
        logger = LoggerFactory.getLogger(loggerName);
    }

    public void traceInit(int traceCategories, int traceLevel, String loggerName) {
        task = "";
        outputSignals.removeAllElements();
        if (warnings != null) {
            warnings.removeAllElements();
        }
        if (errors != null) {
            errors.removeAllElements();
        }

        transitionId = counter++;
        // These trace option may be overridden later when instance is read from
        // the entity bean
        this.traceCategories = traceCategories;
        this.traceLevel = traceLevel;
        logger = LoggerFactory.getLogger(loggerName);
    }

    public void traceInit(StateMachine curfsm) {
        task = "";
        outputSignals.removeAllElements();
        inputSignal = null;
        portTask = "";
        portOutSignals.clear();
        portInSignals.clear();
        if (warnings != null) {
            warnings.removeAllElements();
        }
        if (errors != null) {
            errors.removeAllElements();
        }
        transitionId = counter++;
        // These trace option may be overridden later when instance is read from
        // the entity bean
        this.curfsm = curfsm;
        traceLevel = curfsm.getTraceLevel();
    }

    /**
     * @return current StateMachine that is holding this traceObject
     */
    public StateMachine getCurrentStateMachine() {
        return curfsm;
    }

    /**
     * @return the transitionId
     */
    public int getTransitionId() {
        return transitionId;
    }

    protected int getTraceFormat() {
        if (curfsm == null) {
            return ApplicationSpec.TRACE_FORMAT_TEXT;
        }
        return curfsm.getApplicationSpec().getTraceFormat();
    }

    /**
     * @return the logger
     */
    public Logger getLogger() {
        return logger;
    }

    public void setOutputDisabled(boolean outputDisabled) {
        this.outputDisabled = outputDisabled;
    }

    public ActorAddress getActor() {
        if (inputSignal == null) {
            return null;
        }
        return inputSignal.getReceiverRole();
    }

    public ActorMsg getInputSignal() {
        return inputSignal;
    }

    public String getCurrentState() {
        return currentState;
    }

    public String getNewState() {
        return newState;
    }

    public Vector getOutputSignals() {
        return outputSignals;
    }

    public Vector getWarnings() {
        return warnings != null ? warnings : new Vector();
    }

    public Vector getErrors() {
        return errors;
    }

    public Hashtable getPortOutSignals() {
        return portOutSignals;
    }

    public Hashtable getPortInSignals() {
        return portInSignals;
    }

    /* Set current trace level */
    public void traceSetLevel(int level) {
        traceLevel = level;
    }

    public void traceTask(String str) {
        if (/* ((traceCategories & TraceConstants.tcTask) == 0) & */(traceLevel > TraceConstants.tlDebug))
            return; // Ignore trace
        if (task == null || task.equals(""))
            task = str;
        else
            task = task + "; " + str;
    }

    /**
     * 
     * @return String created by calls to traceTask(String)
     */
    public String getTraceTask() {
        return task;
    }

    public void traceSystem(String str) {
        if (!outputDisabled)
            traceOut(TraceConstants.tlInfo, TraceConstants.tcSystem, getTraceHeader() + str);
    }

    public String getTraceHeader() {
        try {
            if (inputSignal != null) {
                StringBuffer str = new StringBuffer();
                str.append("ACTOR: " + inputSignalReceiver);
                str.append(" TRIGGER: " + inputSignal.getMsgId());
                str.append(" STATE: " + currentState);
                str.append(" MESSAGE: ");
                return str.toString();
            }
        } catch (Exception e) {
        }
        return "ACTOR: UNKNOWN MESSAGE: ";
    }

    /**
     * Probably should be removed
     * 
     * @param trace
     */
    public void setTrace(boolean trace) {
        this.traceFlag = trace;
    }

    public void traceOutput(ActorMsg am) {
        outputSignals.addElement(am);
        /*
         * if (!am.getSenderRole().hasActorPort() && ) { outputSignals.addElement(am); } else {
         * addPortOutputSignal(am.getSenderRole().getActorPort(), am); }
         */
    }

    public void traceWarning(String s) {
        if (logger.isWarnEnabled()) {
            logger.log(TraceConstants.tlWarn, getTraceHeader() + s);
        }
        if (traceLevel > TraceConstants.tlWarn)
            return; // Ignore trace
        if (warnings == null) {
            warnings = new Vector();
        }
        warnings.addElement(s);

    }

    public void traceError(String s) {
        if (logger.isErrorEnabled()) {
            logger.log(TraceConstants.tlError, getTraceHeader() + s);
        }
        if (traceLevel > TraceConstants.tlError)
            return; // Ignore trace
        if (errors == null) {
            errors = new Vector();
        }
        errors.addElement(s);

    }

    public void traceOut(int level, String value) {
        traceOut(level, 1, value);
    }

    /**
     * Generate trace, either to "stdout" or "stderr" depending on level and categories, and if trace level specified implies
     * tracing. If "outputDisabled" is false, no print out is done.
     */
    public void traceOut(int level, int categories, String value) {
        if (!outputDisabled && level >= traceLevel) {
            logger.setTraceLevel(traceLevel);
            logger.log(level, categories, value);
        }
    }

    public String getPortString(ActorMsg inp) {
        String s = "";
        if (portOutSignals.isEmpty() && portInSignals.isEmpty())
            return s;

        Enumeration portNames = portInSignals.keys();
        while (portNames.hasMoreElements()) {
            String name = (String) portNames.nextElement();
            if (inp != null)
                s += "  PORT NAME: " + name + "\n";
            Vector in = ((Vector) portInSignals.get(name));
            if (in != null) {
                Enumeration ein = in.elements();
                while (ein.hasMoreElements()) {
                    if (inp != null)
                        s += "  ";
                    s += "  INPUT:  " + (String) ein.nextElement() + "\n";
                }
            }

            Vector out = ((Vector) portOutSignals.get(name));
            if (out != null) {
                Enumeration eout = out.elements();
                while (eout.hasMoreElements()) {
                    if (inp != null)
                        s += "  ";
                    s += "  OUTPUT: " + (String) eout.nextElement() + "\n";
                }
            }
        }

        return s;
    }

    public String toString() {

        // Skip router timer message
        if (inputSignal.messageName() != null && inputSignal.messageName().equals(ROUTER_UPDATE_TIMER_MSG)) {
            return "";
        }

        // XML format

        if (getTraceFormat() == ApplicationSpec.TRACE_FORMAT_XML) {
            return XmlBuilder.toXML(this);
        }

        StringBuffer sb = new StringBuffer("\n");
        sb.append("START TRANSITION NO: " + transitionId);

        if (inputSignal != null) {
            sb.append(" ACTOR: " + inputSignalReceiver);
            if (inputSignal.getReceiverRole().hasActorPort()) {
                // port execution, get the first
                sb.append(" PORT: " + inputSignal.getReceiverRole().getActorPort() + "\n");
            }

            sb.append(" TRIGGER: " + inputSignal.messageName());
            sb.append(" CURRENT STATE: " + filterStateName(currentState));
            sb.append(" NEXT STATE: " + filterStateName(newState) + "\n");
            sb.append("  INPUT:  ");
            inputSignalMessageContent(sb);
            sb.append("\n");
        }
        if (warnings != null) {
            for (int i = 0; i < warnings.size(); i++) {
                String str = (String) warnings.elementAt(i);
                sb.append("  WARNING: " + str + "\n");
            }
        }

        if (errors != null) {
            for (int i = 0; i < errors.size(); i++) {
                String str = (String) errors.elementAt(i);
                sb.append("  ERROR:   " + str + "\n");
            }
        }

        for (int i = 0; i < outputSignals.size(); i++) {
            ActorMsg msg = (ActorMsg) outputSignals.elementAt(i);
            sb.append("  OUTPUT: " + msg.messageContent() + "\n");
        }
        if (!task.equals("")) {
            sb.append("  TASK:    " + task + "\n");
        }
        sb.append(getPortString(inputSignal));

        if (!inputSignal.getReceiverRole().hasActorPort()) {
            sb.append("END TRANSITION ACTOR: \n");
        } else {
            sb.append("END TRANSITION PORT: \n");
        }
        sb.append("-------------------------------------------------------------------->");
        return sb.toString();
    }

    /**
     * @deprecated found from input signal
     * @param actor
     *            actorAddress of actor
     */
    public void setActor(ActorAddress actor) {
    }

    public void addPortOutputSignal(String portname, ActorMsg outsig) {
        if (portOutSignals.containsKey(portname)) {
            Vector out = (Vector) portOutSignals.get(portname);
            out.addElement(outsig.messageContent());
        } else {
            Vector tmp = new Vector();
            tmp.addElement(outsig.messageContent());
            portOutSignals.put(portname, tmp);
        }
    }

    public void addPortInputSignal(String portname, ActorMsg insig) {
        if (portInSignals.containsKey(portname)) {
            Vector out = (Vector) portInSignals.get(portname);
            out.addElement(insig.messageContent());
        } else {
            Vector tmp = new Vector();
            tmp.addElement(insig.messageContent());
            portInSignals.put(portname, tmp);
        }
    }

    public void setInputSignal(ActorMsg inputSignal) {
        this.inputSignal = inputSignal;
        if (inputSignal == null) {
            inputSignalReceiver = "";
            inputSignalSender = "";
            inputSignalMsgRef = 0;
        } else {
            inputSignalMsgRef = inputSignal.getMsgRef();
            if (inputSignal.getReceiverRole() == null) {
                inputSignalReceiver = "";
            } else {
                inputSignalReceiver = inputSignal.getReceiverRole().toString();
            }
            if (inputSignal.getSenderRole() == null) {
                inputSignalSender = "";
            } else {
                inputSignalSender = inputSignal.getSenderRole().toString();
            }
        }
    }

    public long getInputSignalMsgRef() {
        return inputSignalMsgRef;
    }

    public String getInputSignalSender() {
        return inputSignalSender;
    }

    public String getInputSignalReceiver() {
        return inputSignalReceiver;
    }

    public void setCurrentState(String currentState) {
        this.currentState = currentState;
    }

    public void setNewState(String newState) {
        this.newState = newState;
    }

    public String filterStateName(String name) {
        if (name == null) {
            return null;
        }
        int first;
        int last;
        StringBuffer buf;
        while (name.indexOf(':') != -1) {
            buf = new StringBuffer();
            first = name.indexOf(':');
            last = name.indexOf(':', first + 1);
            buf.append(name.substring(0, first));
            buf.append(name.substring(last + 1, name.length()));
            name = buf.toString();
        }
        return name;
    }

    private StringBuffer inputSignalMessageContent(StringBuffer sb) {
        sb.append(" MESSAGE: ID: ").append(inputSignalMsgRef);
        sb.append(" NAME:").append(inputSignal.getSignalName());
        sb.append(" RECEIVER:").append(inputSignalReceiver);
        sb.append(" SENDER:").append(inputSignalSender);
        if (inputSignal instanceof AFPropertyMsg) {
            AFPropertyMsg afMsg = (AFPropertyMsg) inputSignal;
            sb.append(" CONTENT: ");
            sb.append("MsgId: " + afMsg.getMsgId());
            if (afMsg.getProperty() != null) {
                Enumeration en = afMsg.getProperty().keys();

                while (en.hasMoreElements()) {
                    String s = (String) en.nextElement();
                    sb.append(" " + s + ": " + afMsg.getProperty().get(s) + " :");
                }
            }
        }
        return sb;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy