/*
 * $Id: RSSNavigatorConfig.java,v 1.3 2005/06/21 16:18:34 rampil Exp $
 * Copyright (c) 2005 LOGICAL-PARADOX.ORG
 */
package org.logical_paradox.rss.robot;

import java.io.IOException;

import org.logical_paradox.rss.RSSIllegalConfigException;
import org.logical_paradox.rss.RSSNullValueException;
import org.logical_paradox.rss.RSSValueFormatException;
import org.logical_paradox.rss.dsync.RSSSyncConfig;
import org.logical_paradox.rss.router.algorithm.RoutingAlgorithm;

/**
 * RSSNavigatorConfig
 * RSS Web探索ナビゲーターの設定を監督するクラスの設定ファイル
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.3 $
 */
public class RSSNavigatorConfig extends RSSSyncConfig {
	public static final boolean NAVIMODE_DISTRIB = true;		// 分散システムとして動作させる
	public static final boolean NAVIMODE_STANDALONE = false;	// スタンドアローンで動作させる

	/** デフォルトのUser-Agent値 */
	private String cfgHttpUserAgent = "RSS-agent/1b (http://www.logical-paradox.org/)";
	/** 探索ロック最大保有制限数 */
	private int cfgKeepLocks = 300;
	/** 未処理URL最大保有制限数 */
	private int cfgKeepUrls = 1600;
	/** 未処理URL転送数/回 */
	private int cfgUnTracedURLSendCnt = 20;
	/** 探索URL数 */
	private int cfgDebugTraceURLs = 50;
	/** 実行ログ出力スイッチ */
	private boolean cfgNaviSwRunLog = false;
	/** 実行ログファイル名 */
	private String cfgNavigatorRunLogFilename = "rssnavigator.run.log";
	/** 動作モード(standalone: 単体動作 / distrib: 分散協調動作) */
	private boolean cfgNavigationMode = true;
	/** 探索中のURL表示/非表示設定 */
	private boolean cfgEchoURL = true;
	/** 探索開始URL */
	private String cfgRoot = "";
	/** サイトロック有効期限 */
	private long cfgSiteLockExpire = 1000 * 60 * 5;
	/** 経路決定アルゴリズム */
	private RoutingAlgorithm cfgRoutingAlgorithm = null;
	/** 遅延同期間隔 */
	private int cfgNavigatorSyncInterval = 10000;
	/** 接続先分散サービスレジストリ名 */
	private String cfgDistServRegURL;

	/**
	 * コンストラクタ
	 * @param fn コンフィグファイル名
	 * @throws IOException コンフィグファイルの読み込みに失敗
	 * @throws RSSIllegalConfigException コンフィグファイルの内容が不正
	 */
	public RSSNavigatorConfig(String fn) throws IOException, RSSIllegalConfigException {
		super(fn);
		String errmsg = checkResourceVariables();
		if(errmsg != null) {
			throw new RSSIllegalConfigException(errmsg);
		}
	}

	/**
	 * 分散サービスレジストリDSRのURLを返す
	 * @return URL
	 */
	public String getDistServRegURL() {
		return cfgDistServRegURL;
	}
	/**
	 * 探索中のURL表示/非表示設定を返す
	 * @return true:表示 / false:非表示
	 */
	public boolean getEchoURL() {
		return cfgEchoURL;
	}
	/**
	 * User-Agentを返す
	 * @return User-Agent
	 */
	public String getHttpUserAgent() {
		return cfgHttpUserAgent;
	}
	/**
	 * 探索URL数を返す
	 * @return 探索URL数(0:無制限)
	 */
	public int getDebugTraceURLs() {
		return cfgDebugTraceURLs;
	}
	/**
	 * 探索ロック最大保有制限数を返す
	 * @return 探索ロック最大保有制限数
	 */
	public int getKeepLocks() {
		return cfgKeepLocks;
	}
	/**
	 * 未処理URL最大保有制限数を返す
	 * @return 未処理URL最大保有制限数
	 */
	public int getKeepUrls() {
		return cfgKeepUrls;
	}
	/**
	 * 未処理URL転送数/回を返す
	 * @return 未処理URL転送数/回
	 */
	public int getUnTracedURLSendCnt() {
		return cfgUnTracedURLSendCnt;
	}
	/**
	 * 実行ログ出力スイッチを返す
	 * @return true:出力する / false:出力しない
	 */
	public boolean getNaviSwRunLog() {
		return cfgNaviSwRunLog;
	}
	/**
	 * 実行ログファイル名を返す
	 * @return 実行ログファイル名
	 */
	public String getNavigatorRunLogFilename() {
		return cfgNavigatorRunLogFilename;
	}
	/**
	 * 動作モードを返す
	 * @return true:分散システム / false:standalone
	 */
	public boolean getNavigationMode() {
		return cfgNavigationMode;
	}
	/**
	 * 探索開始URLを返す
	 * @return 探索開始URL
	 */
	public String getRoot() {
		return cfgRoot;
	}
	/**
	 * サイトロック有効期限を返す
	 * @return サイトロック有効期限
	 */
	public long getSiteLockExpire() {
		return cfgSiteLockExpire;
	}
	/**
	 * 経路決定アルゴリズムを返す
	 * @return 経路決定アルゴリズム
	 */
	public RoutingAlgorithm getRoutingAlgorithm() {
		return cfgRoutingAlgorithm;
	}
	/**
	 * 遅延同期間隔を返す
	 * @return 遅延同期間隔
	 */
	public int getNavigatorSyncInterval() {
		return cfgNavigatorSyncInterval;
	}

	/**
	 * パラメータ確認メソッド
	 * @return エラーメッセージ
	 */
	protected String checkResourceVariables() {
		String errmsg = super.checkResourceVariables();			// 同期デーモンcfgのチェックメソッドを呼び出す

		if(getProperty("HTTP_USER_AGENT") != null) {
			cfgHttpUserAgent = getProperty("HTTP_USER_AGENT");
		}

		cfgDistServRegURL = getProperty("RSS_DSR");
		if(cfgDistServRegURL == null) {
			errmsg += "RSS_DSRが指定されていません\n";
		}

		try {
			cfgKeepLocks = getPropertyAsInt("KEEP_LOCKS");
		} catch(RSSValueFormatException vfe) {
			errmsg += "KEEP_LOCKSの値が不正です\n";
		} catch(RSSNullValueException ne) {}

		try {
			cfgKeepUrls = getPropertyAsInt("KEEP_URLS");
		} catch(RSSValueFormatException vfe) {
			errmsg += "KEEP_URLSの値が不正です\n";
		} catch(RSSNullValueException ne) {}

		try {
			cfgUnTracedURLSendCnt = getPropertyAsInt("UNTRACED_URL_SEND_CNT");
		} catch(RSSValueFormatException vfe) {
			errmsg += "UNTRACED_URL_SEND_CNTの値が不正です\n";
		} catch(RSSNullValueException ne) {}

		try {
			cfgDebugTraceURLs = getPropertyAsInt("DEBUG_TRACE_URLS");
		} catch(RSSValueFormatException vfe) {
			errmsg += "DEBUG_TRACE_URLSの値が不正です";
		} catch(RSSNullValueException ne) {}

		try {
			cfgNaviSwRunLog = getPropertyAsBool("NAVI_SW_RUNLOG");
		} catch(RSSValueFormatException vfe) {
			errmsg += "NAVI_SW_RUNLOGの値が不正です";
		} catch(RSSNullValueException ne) {}

		try {
			cfgEchoURL = getPropertyAsBool("ECHO_URL");
		} catch(RSSValueFormatException vfe) {
			errmsg += "ECHO_URLの値が不正です";
		} catch(RSSNullValueException ne) {}

		cfgNavigatorRunLogFilename = getProperty("NAVIGATOR_RUNLOG_FILENAME");
		String cfgSNavigationMode = getProperty("NAVIGATION_MODE");
		if(cfgSNavigationMode == null || cfgSNavigationMode.trim().toUpperCase().equals("DISTRIB")) {
			cfgNavigationMode = NAVIMODE_DISTRIB;
		} else if(cfgSNavigationMode.trim().toUpperCase().equals("STANDALONE")) {
			cfgNavigationMode = NAVIMODE_STANDALONE;
		} else {
			errmsg += "NAVIGATION_MODEが不正です";
		}

		cfgRoot = getProperty("ROOT");

		try {
			cfgSiteLockExpire = getPropertyAsInt("SITELOCK_EXPIRE");
			if(cfgSiteLockExpire < 0) {
				// ロックの有効期限はマイナスに設定することはできない
				throw new RSSValueFormatException();
			}
		} catch(RSSValueFormatException vfe) {
			errmsg += "SITELOCK_EXPIREは0以上に設定してください\n";
		} catch(RSSNullValueException ne) {}

		try {
			cfgNavigatorSyncInterval = getPropertyAsInt("NAVIGATOR_SYNC_INTERVAL");
			if(cfgNavigatorSyncInterval < 500) {
				// 同期のタイミングは0.5秒以下に設定することはできない
				throw new RSSValueFormatException();
			}
		} catch(RSSValueFormatException vfe) {
			errmsg += "NAVIGATOR_SYNC_INTERVALは500以上に設定してください\n";
		} catch(RSSNullValueException ne) {}

		try {
			String algorithm = getProperty("ROUTING_ALGORITHM");
			cfgRoutingAlgorithm = (RoutingAlgorithm)Class.forName(algorithm).newInstance();
		} catch(Exception e) {
			errmsg += "ROUTING_ALGORITHMで定義された経路決定アルゴリズムは，存在しません\n";
		}

		if(errmsg.trim().length() > 0) {
			return errmsg;
		} else {
			return null;
		}
	}
}

// end of RSSNavigatorConfig.java
