/*  OpenOlap viewer
 *  パッケージ名：openolap.viewer.controller
 *  ファイル：GetReportInfoCommand.java
 *  説明：レポート情報をXML形式で出力します。
 *
 *  作成日: 2004/01/09
 */
package openolap.viewer.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import openolap.viewer.Axis;
import openolap.viewer.AxisLevel;
import openolap.viewer.Dimension;
import openolap.viewer.Edge;
import openolap.viewer.Measure;
import openolap.viewer.MeasureMember;
import openolap.viewer.Report;
import openolap.viewer.User;
import openolap.viewer.common.CommonSettings;
import openolap.viewer.common.CommonUtils;
import openolap.viewer.common.StringUtil;
import openolap.viewer.dao.DAOFactory;
import openolap.viewer.dao.DimensionMemberDAO;

/**
 *  クラス：GetReportInfoCommand
 *  説明：レポート情報をXML形式で出力します。
 */
public class GetReportInfoCommand implements Command {

	// ********** インスタンス変数 **********

	/** RequestHelperオブジェクト */
	private RequestHelper requestHelper = null;

	// ********** メソッド **********

	/**
	 * レポート情報をXML形式で出力します。<br>
	 * JSPへdispatchを行わずに直接XMLを出力するため、nullを戻す。
	 * @param helper RequestHelperオブジェクト
	 * @param commonSettings アプリケーションの共通設定オブジェクト
	 * @return null
	 * @exception ServletException 処理中に例外が発生した
	 * @exception IOException 処理中に例外が発生した
	 */
	public String execute(RequestHelper helper, CommonSettings commonSettings)
		throws ServletException, IOException {

			this.requestHelper = helper;
			HttpServletRequest request = this.requestHelper.getRequest();
			HttpSession session = this.requestHelper.getRequest().getSession();

			Report report = (Report) session.getAttribute("report");
			User user = (User) session.getAttribute("user");

			Connection conn = null;
			DAOFactory daoFactory = DAOFactory.getDAOFactory();
			conn = daoFactory.getConnection();

			try {

				// XMLを出力
				this.outputXML(report, user, conn);

			} catch (SQLException e) {
				e.printStackTrace();
			} catch (Exception e) { 
				e.printStackTrace();
			} finally {
				if(conn != null){
					try {
						conn.close();
					} catch (SQLException e) {
						e.printStackTrace();
					}
				}
			}

			return null;

	}

	// ********** private メソッド **********

	/**
	 * デフォルトメンバーキーがnullの場合、"NA"に変換する。
	 * @param defaultMemKey デフォルトメンバーキー
	 * @return デフォルトメンバーキー
	 */
	private String changeDefaultMemberKey(String defaultMemKey) {
		if(defaultMemKey == null) { 
			return "NA";
		} else {
			return defaultMemKey;
		}
	}

	/**
	 * レポート情報をXML形式で出力します。
	 * @param report レポートオブジェクト
	 * @param user ユーザーオブジェクト
	 * @param conn Connectionオブジェクト
	 * @exception IOException 処理中に例外が発生した
	 * @exception SQLException レポート情報取得時に例外が発生した
	 */
	private void outputXML(Report report, User user, Connection conn) throws IOException, SQLException {

		this.requestHelper.getResponse().setContentType("text/xml; charset=Shift_JIS");
		PrintWriter out = this.requestHelper.getResponse().getWriter();

		DAOFactory daoFactory = DAOFactory.getDAOFactory();
		DimensionMemberDAO dimMemberDAO = daoFactory.getDimensionMemberDAO(conn);

		// 出力開始
		out.println("<?xml version=\"1.0\" encoding=\"Shift_JIS\"?>");
		out.println("<root>");
			out.println("<OlapInfo>");
				out.println("<ReportInfo>");
					out.println("<Report>");
						out.println("<ReportID>");
							out.println(report.getReportID());
						out.println("</ReportID>");
						out.println("<ReportName>");
							out.println(report.getReportName());
						out.println("</ReportName>");
						out.println("<isNewReport>");
							out.println(CommonUtils.boolToFLG(report.isNewReport()));
						out.println("</isNewReport>");
					out.println("</Report>");
				out.println("</ReportInfo>");
				out.println("<CubeInfo>");
					out.println("<Cube>");
						out.println("<CubeName>");
							out.println(report.getCube().getCubeName());
						out.println("</CubeName>");
					out.println("</Cube>");
				out.println("</CubeInfo>");

			out.println("<AxesInfo>");


			// 軸の配置場所を出力

			Iterator edgeIt = report.getEdgeList().iterator();
			while (edgeIt.hasNext()) {
				Edge edge = (Edge) edgeIt.next();
				Iterator axisIt = edge.getAxisList().iterator();
				out.println(StringUtil.addStartTAGMark(edge.getPosition()));
				while (axisIt.hasNext()) {
					Axis axis = (Axis) axisIt.next();
					out.println("<HierarchyID>" + axis.getId()  + "</HierarchyID>");
				}
				out.println(StringUtil.addEndTAGMark(edge.getPosition()));
			}

			// 軸情報をAxisIDの昇順で出力
			ArrayList axisList = report.getAxilOrderByID();
			Iterator axisIt = axisList.iterator();
			while (axisIt.hasNext()) {
				Axis axis = (Axis) axisIt.next();

				out.println("<HierarchyInfo name=\"" + axis.getName() + "\" id=\""+ axis.getId() +"\">");
				out.println("<DefaultMemberKey>"+ changeDefaultMemberKey(axis.getDefaultMemberKey()) +"</DefaultMemberKey>");
				out.println("<Comment>" + StringUtil.changeNullToEmpty(axis.getComment()) + "</Comment>");

				// メンバーの表示名タイプを出力
				String displayMemberNameType = null;
				if(axis instanceof Dimension) {
					displayMemberNameType = dimMemberDAO.transferMemberDisplayTypeFromModelToXML(((Dimension)axis).getDispMemberNameType());
				} else {
					displayMemberNameType = dimMemberDAO.transferMemberDisplayTypeFromModelToXML(Dimension.DISP_SHORT_NAME);
				}
				out.println("<DisplayMemberType>" + displayMemberNameType + "</DisplayMemberType>");
					
				Iterator levelIt = axis.getAxisLevelList().iterator();
				while (levelIt.hasNext()) {
					AxisLevel axisLevel = (AxisLevel) levelIt.next();
					out.println("<Level>");
						out.println("<LNum>");
							out.println(axisLevel.getLevelNumber());
						out.println("</LNum>");
						out.println("<LName>");
							out.println(axisLevel.getName());
						out.println("</LName>");
						out.println("<Comment>");
							out.println(StringUtil.changeNullToEmpty(axisLevel.getComment()));
						out.println("</Comment>");
					out.println("</Level>");
				}
				out.println("</HierarchyInfo>");

			}

			out.println("</AxesInfo>");
		out.println("</OlapInfo>");

		// ユーザ情報出力
		out.println("<UserInfo>");
			out.println("<UserName>");
				out.println(user.getName());
			out.println("</UserName>");
			out.println("<isAdmin>");
				out.println(CommonUtils.boolToFLG(user.isAdmin()));
			out.println("</isAdmin>");
			out.print("<exportType>");
				out.print(user.getExportFileType());
			out.println("</exportType>");
		out.println("</UserInfo>");

		// 軸メンバ情報出力
		out.println("<Axes>");

			// ディメンションメンバ情報を出力
			dimMemberDAO.outputDimensionMemberAsXML(report,out);

			// メジャー情報を出力
			Measure measure = report.getMeasure();
			Iterator meaMemIt = measure.getAxisMemberList().iterator();
			out.println("<Members name=\"" + measure.getName() + "\" id=\"" + measure.getId() +  "\">");

			while (meaMemIt.hasNext()) {
				MeasureMember measureMember = (MeasureMember) meaMemIt.next();

				if(!measureMember.isSelected()) {	// セレクタで表示対象外とされているメンバ情報は出力しない
					continue;
				}

				out.println("<Member id=\"" + measureMember.getId() + "\">");
				out.println("    <UName>" + measureMember.getUniqueName() + "</UName>");
				out.println("    <Code>" + measureMember.getMeasureName() + "</Code>");
				out.println("    <Caption>" + measureMember.getMeasureName() + "</Caption>");
				out.println("    <Caption2>" + measureMember.getMeasureName() + "</Caption2>");
				out.println("    <LNum>1</LNum>");
				out.println("    <isDrilled>false</isDrilled>");
				out.println("    <isLeaf>true</isLeaf>");
				out.println("</Member>");

			}
			out.println("</Members>");

		out.println("</Axes>");
		out.println("</root>");
	}

}
