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.messages.AFConstants;
import org.coos.javaframe.messages.ActorMsg;

/**
 * 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 transistion
 * 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 ActorAddress actor; // Actor address for the state machine that
	// this transition belongs to.
	protected ActorMsg inputSignal; // The input signal that triggered the
	// transition
	protected String currentState; // The state of the state machine before the
	// transition
	protected String newState; // The state after the transistion. 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 transsition
	Vector warnings; // Warnings set during the transsition
	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;

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

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

	public TraceObject(StateMachine curfsm) {
		initTrace(curfsm.getClass().toString());
	}

	public TraceObject(ActorAddress actor) {
		String ac = actor.getActorID();
		initTrace(ac.replace('/', '.'));
	}

	public TraceObject(ActorAddress actor, ActorMsg inputSignal, String currentState) {
		initTrace(actor.getActorID().replace('/', '.'));
		// Added by Ronnie Nessa
	}

	/*
	 * 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
		traceLevel = curfsm.getTraceLevel();
	}

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

	public ActorAddress getActor() {
		return actor;
	}

	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.equals(""))
			task = str;
		else
			task = task + ";  " + str;
	}

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

	public String getTraceHeader() {
		if (actor != null) {
			StringBuffer str = new StringBuffer();
			str.append("ACTOR: " + actor.toString());
			str.append(" TRIGGER: " + inputSignal.getMsgId());
			str.append(" STATE: " + currentState);
			str.append(" MESSAGE: ");
			return str.toString();
		} else
			return " method getTraceHeader failed, actor is null";
	}

	/**
	 * 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() {
		StringBuffer sb = new StringBuffer("\n");
		sb.append("START TRANSITION NO: " + transitionId);
		sb.append(" ACTOR: " + actor.toString());
		if (actor.hasActorPort()) {
			// port execution, get the first
			sb.append(" PORT: " + actor.getActorPort() + "\n");
		}

		if (inputSignal != null) {
			String sn = inputSignal.messageName();

			if (sn != null && inputSignal.messageName().equals(ROUTER_UPDATE_TIMER_MSG)) {
				return "";
			}
			/*
			 * sb.append("START TRANSITION NO: " + transitionId + " ACTOR: " +
			 * actor.toString() + " TRIGGER: " + inputSignal.messageName() +
			 * " CURRENT STATE: " + filterStateName(currentState) +
			 * " NEXT STATE: " + filterStateName(newState) + "\n" + "  INPUT:  "
			 * + inputSignal.messageContent() + "\n");
			 */

			sb.append(" TRIGGER: " + inputSignal.messageName());
			sb.append(" CURRENT STATE: " + filterStateName(currentState));
			sb.append(" NEXT STATE: " + filterStateName(newState) + "\n");
			sb.append("  INPUT:  " + inputSignal.messageContent() + "\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 (!actor.hasActorPort()) {
			sb.append("END TRANSITION ACTOR: \n");
		} else {
			sb.append("END TRANSITION PORT: \n");
		}
		sb.append("-------------------------------------------------------------------->");
		return sb.toString();
	}

	public void setActor(ActorAddress actor) {
		this.actor = 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;
	}

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

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

	protected 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;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy