/**
 * @(#)WebFileRobo.java
 * Copyright 2001 Nomura Research Institute, LTD. All rights reserved.
 * RIDUAL : Web File Robo
 * @author  Intelligent Technology Inc.
 * @version 1.00 2002/08/23
 */
package jp.co.nri.rid.web;

import	java.net.*;
import	java.io.*;
import	java.util.*;

/**
 * ファイルを1ずつダウンロードするスレッド
 */
public class WebDownloadRobo extends Thread{
	private Vector				myDownloadQueue;
	private	WebDownloadQueueMap	myQueueMap;
	private	Hashtable			myDownloadLog;
	private	WebFile				myWebFile;
	private	WebRoboState		myState;
	private WebMessages			myMessages;
	
	public	long				SleepTime	= 4000;	// 4sec
	
	/**
	 * コンストラクタ
	 * @since	1.00
	 */
	public WebDownloadRobo(WebRoboState state ,Vector downloadQueue ,WebDownloadQueueMap map ,Hashtable downloadLog ,String host ,String dir ,WebMessages messages){
		myDownloadQueue	= downloadQueue;
		myQueueMap		= map;
		myDownloadLog	= downloadLog;
		myMessages		= messages;
		myWebFile		= new WebFile(host.toLowerCase());
		
		myState = state;
	}
	
	public void setSaveDir(File dir ,File outside){
		myWebFile.setSaveDir(dir);
		
		// outsideはどうする？
	}
	
	public void setRootPath(String path){	myWebFile.setRootPath(path); }
	
	/**
	 * WebDownloadQueueMapにキューがひとつも登録されておらず、defaultQueueも登録されていない場合、NullPointerExceptionをスローする。
	 * @since	1.00
	 */
	public void run(){
		Vector	defaultQueue= myQueueMap.getDefaultQueue();
		boolean	isEmptyMap	= (0<myQueueMap.size()) ? false : true;
		
		while(!myState.stopping){
			if(0 >= myDownloadQueue.size()){
				try{ sleep(SleepTime); }catch(InterruptedException e){}
				continue;
			}
			
			myState.alive++;
			
			try{
				Object obj = myDownloadQueue.remove(0);
				DownloadProperty property = null;				
				try{
					if(obj instanceof DownloadProperty){
						property = (DownloadProperty)obj;
						if(!myWebFile.setURL(property.parent ,property.url)) continue;
					}
					else{
						if(obj instanceof String){
							if(!myWebFile.setURL((String)obj)) continue;
						} else continue;
					}
					
				}catch(MalformedURLException e){	// URL作成エラー
					myMessages.add(myMessages.BadURLDR ,obj.toString());
					continue;
				}
				URL url = myWebFile.getURL();
				
				if(null==url){	// ファイル名を省略しているが、ファイル名が分からなかった。
					myMessages.add(myMessages.DefaultFileNotFoundDR ,obj.toString());
					continue;
				}
				
//				if(!url.getHost().toLowerCase().equals(myHost))	continue;	// ダウンロードしないホスト
				
				File file = myWebFile.fusionPath();
				if(null==file)	continue;									// ダウンロードしないディレクトリ
				
				// キュー取得
				Vector queue = isEmptyMap ? defaultQueue : myQueueMap.get(getExtension(file).toLowerCase());	// セーブしないモードをどうする？ 拡張子	++++
				if(null==queue)	continue;	// ダウンロードしない拡張子
				
				// ログ書き込み	ダウンロード済みチェックにも使う
				synchronized(myDownloadLog){
					if(myDownloadLog.containsKey(url))	continue;
					myDownloadLog.put(url ,url);
				}
				
				// ダウンロード
				try{
					int httpstat = myWebFile.save();
					if(HttpURLConnection.HTTP_OK == httpstat){
						/* t3-nishimura@nri modification start */
						if (getExtension(file).equalsIgnoreCase("swf")
							&& property != null) {
							/* swf の場合は参照元ページをリンクの起点とする */
							queue.add(new ScanProperty(property.parent,
													   myWebFile.getURL(),
													   file));
						} else {
							queue.add(new ScanProperty(myWebFile.getURL() ,file));	// キューに追加	// セーブしないモードをどうする？	++++
						}
						/* t3-nishimura@nri modification end */
					}
					else{
						myDownloadLog.remove(url);
						myMessages.add(myMessages.SaveFileNotFoundDR ,"HTTP-STATUS="+httpstat+" "+url.toString());
					}
				}
				catch(FileNotFoundException e){
					myDownloadLog.remove(url);
					myMessages.add(myMessages.SaveFileNotFoundDR ,url.toString());
				}
				catch(IOException e){
					myDownloadLog.remove(url);
					myMessages.add(myMessages.SaveIOErrorDR ,url.toString());
				}
			}
			catch(ArrayIndexOutOfBoundsException e){} // 先に他のスレッドに取られた。
			finally{ myState.alive--; }
		}
	}
	
	private String getExtension(File file){ return getExtension(file.getName()); }
	private String getExtension(String name){
		int ix = name.lastIndexOf('.');
		if(0 > ix)					return ".";
		if(name.length()-1 <= ix)	return ".";
		return name.substring(ix+1);
	}
}
