/*
 * $Id: Message.java,v 1.7 2006/02/06 15:32:50 rampil Exp $
 * Copyright (c) 2004 LOGICAL-PARADOX.ORG
 */
package org.logical_paradox.rss.dsr;

import java.io.Serializable;
import java.util.Stack;

/**
 * 複数のDSR間でメッセージを交換する際に使用されるオブジェクト
 * このメッセージのメンバーは全てシリアル化可能でなければならない
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.7 $
 */
public class Message implements Serializable, Cloneable {
	/** シリアルバージョンUID */
	private static final long serialVersionUID = -165920728326655367L;
	/** サービス発見プロトコル(発見)*/
	public static final int MSG_TYPE_CD_DISCOVER = 10;
	/** サービス発見プロトコル(トレース)*/
	public static final int MSG_TYPE_CD_TRACE = 20;

	/** 探索相手の名称 */
	private String targetName;
	/** 発見対象サービスID */
	private int discoverType;
	/** 探索の深さ */
	private int traceLevel;
	/** 現在の探索深度 */
	private int currentLevel;

	/** このメッセージがたどってきた経路 */
	private Stack<Route> route;

	/**
	 * コンストラクタ
	 */
	public Message() {
		route = new Stack<Route>();
	}

	/**
	 * コピーコンストラクタ
	 * @param msg 元のメッセージ
	 */
	@SuppressWarnings("unchecked")
	public Message(Message msg) {
		route = (Stack<Route>)msg.route.clone();
		targetName = msg.targetName == null ? null : msg.targetName;
		discoverType = msg.discoverType;
		traceLevel = msg.getTraceLevel();
		currentLevel = msg.getCurrentLevel();
	}
	/**
	 * 探索相手の名称を設定する
	 * @param name 探索相手の名称
	 */
	public void setTargetName(String name) {
		targetName = name;
	}
	/**
	 * 探索相手の名称を返す
	 * @return 探索相手の名称
	 */
	public String getTargetName() {
		return targetName;
	}
	/**
	 * 探索の深さを設定する
	 * @param tl 探索の深さ(0以下:無制限)
	 */
	public void setTraceLevel(int tl) {
		traceLevel = tl;
	}
	/**
	 * 探索の深さを返す
	 * @return 探索の深さ(0以下:無制限)
	 */
	public int getTraceLevel() {
		return traceLevel;
	}
	/**
	 * 発見対象サービスIDを設定する
	 * @param dt 発見対象サービスID
	 */
	public void setDiscoverType(int dt) {
		discoverType = dt;
	}
	/**
	 * 発見対象サービスIDを返す
	 * @return 発見対象サービスID
	 */
	public int getDiscoverType() {
		return discoverType;
	}
	/**
	 * 経路情報を追加する
	 * @param r 経路情報
	 */
	public void push(Route r) throws AlreadyTracedException {
		route.push(r);
	}
	/**
	 * 経路情報を1つ返す
	 * @return 経路情報
	 */
	public Route pop() {
		return (Route)route.pop();
	}
	/**
	 * 現在の探索深度を増加させる
	 */
	public void incrementLevel() {
		currentLevel++;
	}

	/**
	 * 現在の探索深度を返す
	 * @return 探索深度
	 */
	public int getCurrentLevel() {
		return currentLevel;
	}
}
