//===========================================================================
// 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.commons.beanutils.*;

import java.util.*;

import jp.gr.java_conf.bugslife.form.*;
import jp.gr.java_conf.bugslife.bug.*;
import jp.gr.java_conf.bugslife.user.*;
import jp.gr.java_conf.bugslife.system.*;
import jp.gr.java_conf.bugslife.util.Converter;
/**
 *<PRE>
 * 
 * BugDownloadActionクラス
 *
 *</PRE>
 * @version	0.0
 * @author	鰐川 正寛
 */
public final class BugDownloadAction extends BaseAction 
{
//===========================================================================
// attributes
//===========================================================================
	/**
	 * 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 {
		/*  初期処理
		 */
		HttpSession session = getSession(request);	//sessioの取得
		UserInfo user = (UserInfo)getAttribute(session,"UserInfo");	//ログインユーザの取得
		ActionForward forward = null;
//		BugDownloadForm myForm = (BugDownloadForm)form;
		Collection bugNumbers = (Collection)session.getAttribute("bugNUmberList");
		
		//バグリストを求める
		Collection bugs = BugFinder.findFullBug(bugNumbers);
		
		//ストリームの生成
		PrintWriter out =  response.getWriter();
//		response.setContentType("application/octet-stream");
		response.setContentType("application/unknown");
		String fileName = "buglist." + Converter.getDateString(new Date(), Converter.MMDD);
		response.setHeader("Content-Disposition", "attachment; filename=" + fileName );
//		response.setHeader("Content-Disposition", "inline; filename=" + fileName);
		
		//ヘッダ部の出力
		writeHeader(out);
		
		Iterator ite = bugs.iterator();
		while(ite.hasNext()) {
			
			//データ部の出力
			writeData((FullBug)ite.next(), out);
		}
		
		
		out.flush();
		
		forward = mapping.findForward("success");
		
		// Forward control to the specified success URI
		return forward;
	}
	
	private void writeHeader(PrintWriter out) {
		
		StringBuffer sb = new StringBuffer();
		writeObject("故障番号", sb);
		writeObject("故障ID", sb);
		writeObject("タイトル", sb);
		//-------------------------------------------
		//石田　2007/10/09 NO6　insert start 
		//CSV出力に担当者が足りないため項目追加
		writeObject("担当者", sb);
		//石田　2007/10/09 NO6　insert end
		//-------------------------------------------
		writeObject("環境区分", sb);
		writeObject("環境名", sb);
		writeObject("機能区分", sb);
		writeObject("機能名", sb);
		writeObject("画面名", sb);
		writeObject("ブラウザ区分", sb);
		writeObject("ブラウザ名", sb);
		writeObject("OS区分", sb);
		writeObject("OS名", sb);
		writeObject("試験ID", sb);
		writeObject("APバージョン区分", sb);
		writeObject("APバージョン", sb);
		writeObject("DBバージョン区分,", sb);
		writeObject("DBバージョン", sb);
		writeObject("HTMLバージョン区分,", sb);
		writeObject("HTMLバージョン", sb);
		writeObject("仕様バージョン区分", sb);
		writeObject("仕様バージョン", sb);
		writeObject("発行者番号", sb);
		writeObject("発行者名", sb);
		writeObject("発行日", sb);
		writeObject("登録日", sb);
		writeObject("故障度区分", sb);
		writeObject("故障度", sb);
		writeObject("優先度区分", sb);
		writeObject("優先度", sb);
		writeObject("状態", sb);
		writeObject("状態名", sb);
		writeObject("状況", sb);
		writeObject("対処区分", sb);
		writeObject("対処", sb);
		writeObject("目標区分", sb);
		writeObject("目標", sb);
		//-------------------------------------------
		//石田　2007/10/09　NO6 insert start
		//CSV出力に仕様変更ＩＤが足りないため項目追加
		writeObject("仕様変更ＩＤ", sb);
		//石田　2007/10/09 NO6　insert end
		//-------------------------------------------
		writeObject("キーワード１", sb);
		writeObject("キーワード２", sb);
		writeObject("キーワード３", sb);
		writeObject("コンポ１", sb);
		writeObject("コンポ２", sb);
		writeObject("コンポ３", sb);
		writeObject("コンポ４", sb);
		writeObject("コンポ５", sb);
		writeObject("関連ODC", sb);
		writeObject("承認者番号", sb);
		writeObject("承認者", sb);
		writeObject("承認日", sb);
		writeObject("エラー内容区分", sb);
		writeObject("エラー内容", sb);
		writeObject("エラー原因区分", sb);
		writeObject("エラー原因", sb);
		//-------------------------------------------
		//石田　2007/10/09 NO6 insert start
		//CSV出力にエラー機能箇所が足りないため項目追加
		writeObject("エラー機能箇所", sb);
		//石田　2007/10/09 NO6 insert end
		//-------------------------------------------
		writeObject("発生工程区分", sb);
		writeObject("発生工程", sb);
		writeObject("混入工程区分", sb);
		writeObject("混入工程", sb);
		writeObject("摘出すべき工程区分", sb);
		writeObject("摘出すべき工程", sb);
		writeObject("摘出遅延理由区分", sb);
		writeObject("摘出遅延理由", sb);
		writeObject("提供予定日", sb);
		writeObject("分析者番号", sb);
		writeObject("分析者", sb);
		writeObject("分析日", sb);
		writeObject("修正ソース", sb);
		writeObject("修正DOC", sb);
		writeObject("修正者番号", sb);
		writeObject("修正者", sb);
		writeObject("修正日", sb);
		writeObject("提供日", sb);
		writeObject("確認者番号", sb);
		writeObject("確認者", sb);
		writeObject("確認日", sb);
		writeObject("最終更新者番号", sb);
		writeObject("最終更新者", sb);
		writeObject("最終更新日", sb);
		writeObject("故障内容", sb);
		writeObject("方針内容", sb);
		writeObject("解析内容", sb);
		writeObject("修正内容", sb);
		writeObject("確認内容", sb);
		
		out.println(sb.toString());
	}
	private void writeData(FullBug bug, PrintWriter out) {
		
		StringBuffer sb = new StringBuffer();
		
		writeObject(bug.getBno(), sb);
		writeObject(bug.getBid(), sb);
		writeObject(bug.getTitle(), sb);
		//-------------------------------------------
		//石田　2007/10/09 NO6 insert start
		//CSV出力に担当者が足りないため項目追加
		writeObject(bug.getDispatchName(), sb);
		//石田　2007/10/09 NO6 insert end
		//-------------------------------------------
		writeObject(bug.getLocation(), sb);
		writeObject(bug.getLocationString(), sb);
		writeObject(bug.getFunctionName(), sb);
		writeObject(bug.getFunctionNameString(), sb);
		writeObject(bug.getScreen(), sb);
		writeObject(bug.getBrowser(), sb);
		writeObject(bug.getBrowserString(), sb);
		writeObject(bug.getOs(), sb);
		writeObject(bug.getOsString(), sb);
		writeObject(bug.getTid(), sb);
		writeObject(bug.getAppVersion(), sb);
		writeObject(bug.getAppVersionString(), sb);
		writeObject(bug.getDbVersion(), sb);
		writeObject(bug.getDbVersionString(), sb);
		writeObject(bug.getHtmlVersion(), sb);
		writeObject(bug.getHtmlVersionString(), sb);
		writeObject(bug.getSpecVersion(), sb);
		writeObject(bug.getSpecVersionString(), sb);
		writeObject(bug.getIssuer(), sb);
		writeObject(bug.getIssuerName(), sb);
		writeObject(bug.getIssuDate(), sb);
		writeObject(bug.getRegistDate(), sb);
		writeObject(bug.getSeverity(), sb);
		writeObject(bug.getSeverityString(), sb);
		writeObject(bug.getPriority(), sb);
		writeObject(bug.getPriorityString(), sb);
		writeObject(bug.getStatus(), sb);
		writeObject(bug.getStatusString(), sb);
		writeObject(bug.getStatusWhitebord(), sb);
		writeObject(bug.getResolution(), sb);
		writeObject(bug.getResolutionString(), sb);
		writeObject(bug.getMilestone(), sb);
		writeObject(bug.getMilestoneString(), sb);
		//-------------------------------------------
		//石田　2007/10/09 NO6 insert start
		//CSV出力に仕様変更ＩＤが足りないため項目追加
		writeObject(bug.getScid(), sb);
		//石田　2007/10/09 NO6 insert end
		//-------------------------------------------
		writeObject(bug.getKeyword1(), sb);
		writeObject(bug.getKeyword2(), sb);
		writeObject(bug.getKeyword3(), sb);
		writeObject(bug.getCpid1(), sb);
		writeObject(bug.getCpid2(), sb);
		writeObject(bug.getCpid3(), sb);
		writeObject(bug.getCpid4(), sb);
		writeObject(bug.getCpid5(), sb);
		writeObject(bug.getReletedDoc(), sb);
		writeObject(bug.getAuther(), sb);
		writeObject(bug.getAutherName(), sb);
		writeObject(bug.getAuthDate(), sb);
		writeObject(bug.getErrorType(), sb);
		writeObject(bug.getErrorTypeString(), sb);
		writeObject(bug.getErrorCause(), sb);
		writeObject(bug.getErrorCauseString(), sb);
		writeObject(bug.getIssuPno(), sb);
		writeObject(bug.getIssuPnoString(), sb);
		writeObject(bug.getTrainPno(), sb);
		writeObject(bug.getTrainPnoString(), sb);
		writeObject(bug.getShouldFindPno(), sb);
		writeObject(bug.getShouldFindPnoString(), sb);
		writeObject(bug.getErrorDelayReason(), sb);
		writeObject(bug.getErrorDelayReasonString(), sb);
		//-------------------------------------------
		//石田　2007/10/09 NO6 insert start
		//CSV出力にエラー機能箇所が足りないため項目追加
		writeObject(bug.getErrorPoint(), sb);
		//石田　2007/10/09 NO6 insert end
		//-------------------------------------------
		writeObject(bug.getReleaseSchDate(), sb);
		writeObject(bug.getAnalyst(), sb);
		writeObject(bug.getAnalystName(), sb);
		writeObject(bug.getAnalizeDate(), sb);
		writeObject(bug.getUpdateSrc(), sb);
		writeObject(bug.getUpdateDoc(), sb);
		writeObject(bug.getUpdater(), sb);
		writeObject(bug.getUpdaterName(), sb);
		writeObject(bug.getBugUpdateDate(), sb);
		writeObject(bug.getReleaseDate(), sb);
		writeObject(bug.getComfirmer(), sb);
		writeObject(bug.getComfirmerName(), sb);
		writeObject(bug.getComfirmDate(), sb);
		writeObject(bug.getUpdateUno(), sb);
		writeObject(bug.getUpdateUnoName(), sb);
		writeObject(bug.getUpdateDate(), sb);
		writeAddText(bug.getTroubleAddText(), sb);
		writeAddText(bug.getPrincipalAddText(), sb);
		writeAddText(bug.getCauseAddText(), sb);
		writeAddText(bug.getUpdateAddText(), sb);
		writeAddText(bug.getConfirmAddText(), sb);
		
		out.println(sb.toString());
	}
	private void writeObject(Object o ,StringBuffer sb) {
		if (sb.length() > 0) {
			sb.append(",");
		}
		if (o != null) {
			if (o instanceof java.lang.String) {
				String s = (String)o;
				
				sb.append("\"");
				sb.append(convertString(s));
				sb.append("\"");
			} else if (o instanceof java.util.Date) {
				
				sb.append(Converter.getDateString((Date)o));
				
			} else {
				sb.append(o);
			}
		}
	}
	private void writeObject(int i , StringBuffer sb) {
		if (sb.length() > 0) {
			sb.append(",");
		}
		sb.append(i);
	}
	private void writeObject(byte b , StringBuffer sb) {
		if (sb.length() > 0) {
			sb.append(",");
		}
		sb.append(b);
	}
	private void writeObject(long l , StringBuffer sb) {
		if (sb.length() > 0) {
			sb.append(",");
		}
		sb.append(l);
	}
	private void writeAddText(Collection col, StringBuffer sb) {
		if (sb.length() > 0) {
			sb.append(",");
		}
		
		Iterator ite = col.iterator();
		boolean flag = false;
		while (ite.hasNext()) {
			if (flag) {
				sb.append("\n---\n");
			} else {
				sb.append("\"");
				flag = true;
			}
			
			AddText text = (AddText)ite.next();
			StringBuffer buf = new StringBuffer(text.getContent());
			int offset = 0;
			while(offset < buf.length()) {
				char c = buf.charAt(offset);
				
				//"ダブルコーテーションか？
				//その場合、前後を"ダプルコーテーションで囲む
				if (c == '\"') {
					buf.insert(offset,'\"');
					offset += 2;
//					buf.insert(offset,'\"');
//					offset++;
				//改行コード 0x0D0Aをexelでの改行コード0x0Aに変換する。
				//ここでは単純に0x0d(\r)を削除することで実装する
				} else if (c == '\r') {
					buf.delete(offset,offset+1);
					offset++;
				//以外はそのまま
				} else {
					offset++;
				}
			
			}
			sb.append(convertString(buf.toString()));
		}
		if (flag) {
			sb.append("\"");
		}
		
	}
	
	private String convertString(String s) {
		String ss = null;
		
		try {
			ss = new String(s.getBytes(), "ISO_8859-1");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return ss;
	}
}
