//===========================================================================
// package
//===========================================================================
package jp.gr.java_conf.bugslife.action;

//===========================================================================
// import
//===========================================================================
import java.io.*;
import java.util.Locale;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.commons.logging.*;
import org.apache.struts.action.*;
import org.apache.struts.util.*;
import org.apache.struts.upload.FormFile;
import org.apache.commons.beanutils.*;

import java.util.*;
import jp.gr.java_conf.bugslife.selections.*;
import jp.gr.java_conf.bugslife.user.*;
import jp.gr.java_conf.bugslife.bug.*;
import jp.gr.java_conf.bugslife.form.*;
import jp.gr.java_conf.bugslife.util.Converter;
import jp.gr.java_conf.bugslife.system.*;
/**
 *<PRE>
 * 
 * BugDetail5Actionクラス
 *
 *</PRE>
 * @version	0.0
 * @author	鰐川 正寛
 */
public final class BugAttachmentAction extends BaseAction 
{
//===========================================================================
// attributes
//===========================================================================
	/**
	 * Form
	 */
	BugAttachmentForm m_form;
	/**
	 * session
	 */
	HttpSession m_session;
	/**
	 * Bug
	 */
	Bug m_bug = null;
	/**
	 * Bug
	 */
	UserInfo m_logonUser;
	/**
	 * Log
	 */
	private Log log = LogFactory.getLog(this.getClass().getName());
//===========================================================================
// methods
//===========================================================================
	/**
	 * exevute
	 *
	 * @param mapping The ActionMapping used to select this instance
	 * @param actionForm The optional ActionForm bean for this request (if any)
	 * @param request The HTTP request we are processing
	 * @param response The HTTP response we are creating
	 *
	 * @exception Exception if business logic throws an exception
	 */
	public ActionForward doAction(ActionMapping mapping,
				 ActionForm form,
				 HttpServletRequest request,
				 HttpServletResponse response)
				throws Exception {
		
		ActionForward forward = null;
		/*
		 * 初期処理
		 */
		m_form = (BugAttachmentForm)form;	//formの取得
		m_session = getSession(request);	//sessioの取得
		m_logonUser = (UserInfo)getAttribute(m_session,"UserInfo");	//ログインユーザの取得
		
		String action = m_form.getAction();
		//debug
		log.debug("action = " + action);
		
		//表示の場合
		if (action.equals("show")){
			
			//セッションより取得
			m_bug = (Bug)m_session.getAttribute("bug");
			
			if (m_bug == null) {
				//バグインスタンスの取得
				m_bug = new Bug(m_form.getBno());
				//バグインスタンスのセット
				m_session.setAttribute("bug", m_bug);
			} else {
				//故障番号が一致しない
				if (m_bug.getBno() != m_form.getBno()) {
					//バグインスタンスの取得
					m_bug = new Bug(m_form.getBno());
					//バグインスタンスのセット
					m_session.setAttribute("bug", m_bug);
				}
			}
			
			//showへ遷移
			forward = mapping.findForward("show");
			
			
		//削除の場合
		} else if (action.equals("delete")) {
			
			Attachment at = Attachment.getAttachment(m_form.getAno());
			
			//ファイルの削除
			removeFile(at);
			
			at.delete(m_logonUser.getUno());		//削除
			
			m_form.setMessageKey("success.delete");
			
			//successへ遷移
			forward = mapping.findForward("success");
			
		//ダウンロードの場合
		} else if (action.equals("download")) {
			
			Attachment at = Attachment.getAttachment(m_form.getAno());
			
			//ファイルの送信
			sendFile(at, response);
			
			//successへ遷移
			forward = mapping.findForward("success");
			
		//更新の場合
		} else {
			//セッションより取得
			m_bug = (Bug)m_session.getAttribute("bug");
			
			//チェック
			ActionErrors errors = m_form.validate(mapping, request);
			if (!errors.empty()) {
				 saveErrors(request, errors);
				return (new ActionForward(mapping.getInput()));
			}
			
			//
			//添付ファイルの作成
			//
			Attachment at = new Attachment();
			
			//bno
			at.setBno(m_bug.getBno());
			
			//ファイルを取得する。
			FormFile file = m_form.getFile();
			
			//ファイルタイプの決定
			byte type = checkFileType(m_form.getFileType(), file.getFileName());
			at.setFileType(type);
			
			//mime type 
			//ファイルタイプをセットするとmimetypeが自動的にセットされるが、
			//タイプがその他であれば、指定されたMIME_TYPEをセットする
			if (type == Attachment.TYPE_OTHER) {
				at.setMimeType(m_form.getMimeType());
			}
			//ファイル名
			at.setFileName(file.getFileName());
			//サイズ
			at.setSize(file.getFileSize());
			//付加情報
			at.setInfo(m_form.getInfo());
			
			at.insert(m_logonUser.getUno());		//追加
			
			//これでファイル番号が確定するので、ファイルを保存する。
			
			saveFile(at, file);
			
			//フォームの内容をリセットする。
			m_form.reset(mapping, request);
			
			m_form.setMessageKey("success.upload");
			
			//successへ遷移
			forward = mapping.findForward("success");
			
		}
		//バグインスタンスのセット
		m_session.setAttribute("bug", m_bug);
		
		// Forward control to the specified success URI
		return forward;
	}
	/**
	 * ファイルの削除
	 */
	private void removeFile(Attachment at) {
		
		//ファイル名を作る
		Sysconf sysconf = Sysconf.getSysconf();
		String path = sysconf.getAttachPath() + "file" + at.getAnoString() + ".arc";
		
		//debug
		log.debug("path = " + path);
		
		File file = new File(path);
		if (! file.delete()) {
			throw new BLRuntimeException("attachment file delete error file = "+ file);
		}
	}
	/**
	 * ファイルの保存
	 */
	private void saveFile(Attachment at, FormFile file) {
		
		try {
			InputStream in = file.getInputStream();
			
			//ファイル名を作る
			Sysconf sysconf = Sysconf.getSysconf();
			String path = sysconf.getAttachPath() + "file" + at.getAnoString() + ".arc";
			
			//debug
			log.debug("path = " + path);
			
			//write the file to the file specified
			OutputStream out = new FileOutputStream(path);
			int bytesRead = 0;
			byte[] buffer = new byte[8192];
			while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
				out.write(buffer, 0, bytesRead);
			}
			out.close();
			in.close();
		} catch (IOException ioe) {
			throw new BLRuntimeException("attachment file save error", ioe);
		}
	}
	/**
	 * ファイルの読み込み
	 *
	 * 以下のURLを参照
	 * http://www.rfs.jp/sitebuilder/perl/03/01_02.html
	 * http://www.studyinghttp.net/headers.html
	 */
	private void sendFile(Attachment at, HttpServletResponse response) {
		
		InputStream in = null;
		ServletOutputStream out =  null;
		try {
			
			response.setContentType(at.getMimeType());
			String fileName = new String(at.getFileName().getBytes(), "ISO-8859-1");
//			response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
			response.setHeader("Content-Disposition", "inline; filename=" + fileName);
			
			out = response.getOutputStream();
			
			//ファイル名を作る
			Sysconf sysconf = Sysconf.getSysconf();
			String path = sysconf.getAttachPath() + "file" + at.getAnoString() + ".arc";
			
			//debug
			log.debug("path = " + path);
			
			//write the file to the file specified
			in = new FileInputStream(path);
			
			int bytesRead = 0;
			byte[] buffer = new byte[8192];
			while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
				out.write(buffer, 0, bytesRead);
			}
			out.flush();
			in.close();
		} catch (IOException ioe) {
			if (out != null) {
				try {
					out.close();
					response.resetBuffer();
				} catch (IOException ioee) {
					//無視
				}
			}
			throw new BLRuntimeException("attachment file read error", ioe);
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException ioe) {
					//無視
				}
			}
		}
	}
	/**
	 * ファイルタイプの決定
	 *
	 */
	private byte checkFileType(String typeString, String fileName) {
		
		byte type = Byte.parseByte(typeString);
		
		//バイナリの場合、ファイルの拡張子を見てファイルタイプを決定する
		if (type == Attachment.TYPE_BINARY) {
			
			//拡張子を探す
			int extPos = fileName.lastIndexOf(".");
			//ファイルの拡張子あり
			if (extPos != -1) {
				String ext = fileName.substring(extPos + 1);
				if (ext.equalsIgnoreCase("doc")) {
					type = Attachment.TYPE_WORD;
				} else if (ext.equalsIgnoreCase("xls")) {
					type = Attachment.TYPE_EXEL;
				} else if (ext.equalsIgnoreCase("zip")) {
					type = Attachment.TYPE_ZIP;
				} else if (ext.equalsIgnoreCase("lzh")) {
					type = Attachment.TYPE_LZH;
				} else if (ext.equalsIgnoreCase("gif")) {
					type = Attachment.TYPE_GIF;
				} else if (ext.equalsIgnoreCase("jpg")) {
					type = Attachment.TYPE_JPEG;
				} else if (ext.equalsIgnoreCase("jpeg")) {
					type = Attachment.TYPE_JPEG;
				} else if (ext.equalsIgnoreCase("log")) {
					type = Attachment.TYPE_TEXT;
				} else if (ext.equalsIgnoreCase("csv")) {
					type = Attachment.TYPE_TEXT;
				} else if (ext.equalsIgnoreCase("txt")) {
					type = Attachment.TYPE_TEXT;
				}
			}
		}
		
		return type;
	}
}
