/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * Copyright (C) 2004-2008 Aimluck,Inc.
 * http://aipostyle.com/
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.aimluck.eip.msgboard;

import java.util.ArrayList;
import java.util.List;
import java.util.jar.Attributes;

import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.SelectQuery;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.commons.utils.ALDateUtil;
import com.aimluck.eip.cayenne.om.portlet.EipTMsgboardCategory;
import com.aimluck.eip.cayenne.om.portlet.EipTMsgboardCategoryMap;
import com.aimluck.eip.cayenne.om.security.TurbineUser;
import com.aimluck.eip.common.ALAbstractSelectData;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALData;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.modules.actions.common.ALAction;
import com.aimluck.eip.msgboard.util.MsgboardUtils;
import com.aimluck.eip.orm.DatabaseOrmService;
import com.aimluck.eip.services.accessctl.ALAccessControlConstants;
import com.aimluck.eip.services.accessctl.ALAccessControlFactoryService;
import com.aimluck.eip.services.accessctl.ALAccessControlHandler;
import com.aimluck.eip.util.ALCommonUtils;
import com.aimluck.eip.util.ALEipUtils;

/**
 * 掲示板カテゴリ検索データを管理するクラスです。 <BR>
 * 
 */
public class MsgboardCategorySelectData extends ALAbstractSelectData implements
		ALData {

	/** logger */
	private static final JetspeedLogger logger = JetspeedLogFactoryService
			.getLogger(MsgboardCategorySelectData.class.getName());

	/** カテゴリの総数 */
	private int categorySum;

	/** ログインユーザ ID */
	private int uid;

	/** <code>members</code> 共有メンバー */
	private List members;

	private DataContext dataContext;

	/** 他人のカテゴリ編集権限 */
	private boolean authority_edit;

	/** 他人のカテゴリ削除権限 */
	private boolean authority_delete;

	/**
	 * 
	 * @param action
	 * @param rundata
	 * @param context
	 * @see com.aimluck.eip.common.ALAbstractSelectData#init(com.aimluck.eip.modules.actions.common.ALAction,
	 *      org.apache.turbine.util.RunData,
	 *      org.apache.velocity.context.Context)
	 */
	public void init(ALAction action, RunData rundata, Context context)
			throws ALPageNotFoundException, ALDBErrorException {
		String sort = ALEipUtils.getTemp(rundata, context, LIST_SORT_STR);
		if (sort == null || sort.equals("")) {
			ALEipUtils
					.setTemp(rundata, context, LIST_SORT_STR, "category_name");
			logger.debug("[MsgboardCategorySelectData] Init Parameter. : "
					+ "category_name");
		}

		uid = ALEipUtils.getUserId(rundata);
		dataContext = DatabaseOrmService.getInstance().getDataContext();

		authority_edit = MsgboardUtils
				.CheckPermission(
						rundata,
						context,
						ALAccessControlConstants.VALUE_ACL_UPDATE,
						ALAccessControlConstants.POERTLET_FEATURE_MSGBOARD_CATEGORY_OTHER);

		authority_delete = MsgboardUtils
				.CheckPermission(
						rundata,
						context,
						ALAccessControlConstants.VALUE_ACL_DELETE,
						ALAccessControlConstants.POERTLET_FEATURE_MSGBOARD_CATEGORY_OTHER);

		super.init(action, rundata, context);
	}

	/**
	 * 一覧データを取得します。 <BR>
	 * 
	 * @param rundata
	 * @param context
	 * @return
	 * @see com.aimluck.eip.common.ALAbstractSelectData#selectList(org.apache.turbine.util.RunData,
	 *      org.apache.velocity.context.Context)
	 */
	protected List selectList(RunData rundata, Context context) {
		try {

			SelectQuery query = getSelectQuery(rundata, context);
			buildSelectQueryForListView(query);
			buildSelectQueryForListViewSort(query, rundata, context);

			List list = dataContext.performQuery(query);
			// 件数をセットする．
			categorySum = list.size();
			return buildPaginatedList(list);
		} catch (Exception ex) {
			logger.error("Exception", ex);
			return null;
		}
	}

	/**
	 * 検索条件を設定した SelectQuery を返します。 <BR>
	 * 
	 * @param rundata
	 * @param context
	 * @return
	 */
	private SelectQuery getSelectQuery(RunData rundata, Context context) {
		SelectQuery query = new SelectQuery(EipTMsgboardCategoryMap.class);

		Expression exp1 = ExpressionFactory.noMatchDbExp(
				EipTMsgboardCategoryMap.EIP_TMSGBOARD_CATEGORY_PROPERTY + "."
						+ EipTMsgboardCategory.TURBINE_USER_PROPERTY + "."
						+ TurbineUser.USER_ID_PK_COLUMN, Integer.valueOf(0));
		query.setQualifier(exp1);

		// アクセス制御

		int loginUserId = ALEipUtils.getUserId(rundata);

		ALAccessControlFactoryService aclservice = (ALAccessControlFactoryService) ((TurbineServices) TurbineServices
				.getInstance())
				.getService(ALAccessControlFactoryService.SERVICE_NAME);
		ALAccessControlHandler aclhandler = aclservice
				.getAccessControlHandler();
		boolean hasAclviewOther = aclhandler
				.hasAuthority(
						loginUserId,
						ALAccessControlConstants.POERTLET_FEATURE_MSGBOARD_CATEGORY_OTHER,
						ALAccessControlConstants.VALUE_ACL_LIST);

		Expression exp01 = ExpressionFactory.matchExp(
				EipTMsgboardCategoryMap.EIP_TMSGBOARD_CATEGORY_PROPERTY + "."
						+ EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY,
				MsgboardUtils.PUBLIC_FLG_VALUE_PUBLIC);
		Expression exp02 = ExpressionFactory.matchExp(
				EipTMsgboardCategoryMap.STATUS_PROPERTY,
				MsgboardUtils.STAT_VALUE_OWNER);
		Expression exp03 = ExpressionFactory.matchExp(
				EipTMsgboardCategoryMap.STATUS_PROPERTY,
				MsgboardUtils.STAT_VALUE_ALL);
		Expression exp11 = ExpressionFactory.matchExp(
				EipTMsgboardCategoryMap.EIP_TMSGBOARD_CATEGORY_PROPERTY + "."
						+ EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY,
				MsgboardUtils.PUBLIC_FLG_VALUE_NONPUBLIC);
		Expression exp12 = ExpressionFactory.matchExp(
				EipTMsgboardCategoryMap.USER_ID_PROPERTY, Integer
						.valueOf(ALEipUtils.getUserId(rundata)));

		if (!hasAclviewOther) {
			query.andQualifier((exp01.andExp(exp02.orExp(exp03))).orExp(exp11
					.andExp(exp12)));
		} else {
			query.andQualifier((exp01.andExp(exp02.orExp(exp03))).orExp(exp11
					.andExp(exp02.orExp(exp03))));
		}
		query.setDistinct(true);

		return query;
	}

	/**
	 * 詳細データを取得します。 <BR>
	 * 
	 * @param rundata
	 * @param context
	 * @return
	 * @see com.aimluck.eip.common.ALAbstractSelectData#selectDetail(org.apache.turbine.util.RunData,
	 *      org.apache.velocity.context.Context)
	 */
	protected Object selectDetail(RunData rundata, Context context)
			throws ALPageNotFoundException, ALDBErrorException {
		// オブジェクトモデルを取得
		return MsgboardUtils.getEipTMsgboardCategory(rundata, context, false);
	}

	/**
	 * ResultDataを取得します。（一覧データ） <BR>
	 * 
	 * @param obj
	 * @return
	 * @see com.aimluck.eip.common.ALAbstractSelectData#getListData(java.lang.Object)
	 */
	protected Object getResultData(Object obj) throws ALPageNotFoundException,
			ALDBErrorException {
		MsgboardCategoryResultData rd = new MsgboardCategoryResultData();
		rd.initField();
		try {
			EipTMsgboardCategoryMap record = (EipTMsgboardCategoryMap) obj;
			EipTMsgboardCategory category = record.getEipTMsgboardCategory();

			rd.setCategoryId(category.getCategoryId().intValue());

			rd.setCategoryName(ALCommonUtils.compressString(category
					.getCategoryName(), getStrLength()));

			rd.setNote(category.getNote());
			rd.setOwnerId(category.getTurbineUser().getUserId().longValue());
			// 公開/非公開を設定する．
			rd.setPublicFlag((MsgboardUtils.PUBLIC_FLG_VALUE_PUBLIC)
					.equals(category.getPublicFlag()));
			rd.setOwnerName(ALEipUtils.getUserFullName(category
					.getTurbineUser().getUserId().intValue()));
		} catch (Exception e) {

			// TODO: エラー処理
			logger.error("[MsgboardCategorySelectData]", e);
			throw new ALDBErrorException();
		}
		return rd;
	}

	/**
	 * ResultDataを取得します。（詳細データ） <BR>
	 * 
	 * @param obj
	 * @return
	 * @see com.aimluck.eip.common.ALAbstractSelectData#getResultDataDetail(java.lang.Object)
	 */
	protected Object getResultDataDetail(Object obj)
			throws ALPageNotFoundException, ALDBErrorException {
		MsgboardCategoryResultData rd = new MsgboardCategoryResultData();
		rd.initField();
		try {
			String loginUserStatus = null;

			EipTMsgboardCategory record = (EipTMsgboardCategory) obj;

			// 公開区分
			boolean public_flag = (MsgboardUtils.PUBLIC_FLG_VALUE_PUBLIC)
					.equals(record.getPublicFlag());

			SelectQuery mapquery = new SelectQuery(
					EipTMsgboardCategoryMap.class);
			Expression mapexp = ExpressionFactory.matchDbExp(
					EipTMsgboardCategory.CATEGORY_ID_PK_COLUMN, record
							.getCategoryId());
			mapquery.setQualifier(mapexp);
			List list = dataContext.performQuery(mapquery);

			List users = new ArrayList();
			int size = list.size();
			if (size == 1) {
				EipTMsgboardCategoryMap map = (EipTMsgboardCategoryMap) list
						.get(0);
				users.add(map.getUserId());
				loginUserStatus = map.getStatus();
			} else {
				for (int i = 0; i < size; i++) {
					EipTMsgboardCategoryMap map = (EipTMsgboardCategoryMap) list
							.get(i);
					users.add(map.getUserId());
					if (uid == map.getUserId().intValue()) {
						loginUserStatus = map.getStatus();
					}
				}
			}

			SelectQuery query = new SelectQuery(TurbineUser.class);
			Expression exp = ExpressionFactory.inDbExp(
					TurbineUser.USER_ID_PK_COLUMN, users);
			query.setQualifier(exp);
			members = ALEipUtils.getUsersFromSelectQuery(query);

			rd.setCategoryId(record.getCategoryId().intValue());
			rd.setCategoryName(record.getCategoryName());
			rd.setNote(record.getNote());
			// 公開/非公開を設定する．
			// rd.setPublicFlag("T".equals(record.getPublicFlag()));
			rd.setOwnerId(record.getTurbineUser().getUserId().intValue());
			rd.setOwnerName(ALEipUtils.getUserFullName(record.getTurbineUser()
					.getUserId().intValue()));
			rd.setCreateDate(ALDateUtil.format(record.getCreateDate(),
					"yyyy年M月d日"));
			rd.setUpdateDate(ALDateUtil.format(record.getUpdateDate(),
					"yyyy年M月d日"));

			if (public_flag) {
				if ((MsgboardUtils.STAT_VALUE_ALL).equals(loginUserStatus)) {
					rd.setAccessFlag(MsgboardUtils.ACCESS_PUBLIC_ALL);
				} else {
					rd.setAccessFlag(MsgboardUtils.ACCESS_PUBLIC_MEMBER);
				}
			} else {
				if ((MsgboardUtils.STAT_VALUE_ALL).equals(loginUserStatus)) {
					rd.setAccessFlag(MsgboardUtils.ACCESS_SEACRET_SELF);
				} else {
					rd.setAccessFlag(MsgboardUtils.ACCESS_SEACRET_MEMBER);
				}
			}
		} catch (Exception e) {
			// TODO: エラー処理
			logger.error("[MsgboardCategorySelectData]", e);
			throw new ALDBErrorException();
		}
		return rd;
	}

	/**
	 * @return
	 * @see com.aimluck.eip.common.ALAbstractSelectData#getColumnMap()
	 */
	protected Attributes getColumnMap() {
		Attributes map = new Attributes();
		map.putValue("category_name",
				EipTMsgboardCategoryMap.EIP_TMSGBOARD_CATEGORY_PROPERTY + "."
						+ EipTMsgboardCategory.CATEGORY_NAME_PROPERTY);
		map.putValue("create_user",
				EipTMsgboardCategoryMap.EIP_TMSGBOARD_CATEGORY_PROPERTY + "."
						+ EipTMsgboardCategory.TURBINE_USER_PROPERTY + "."
						+ TurbineUser.LAST_NAME_KANA_PROPERTY);
		return map;
	}

	public int getCategorySum() {
		return categorySum;
	}

	public int getUserId() {
		return uid;
	}

	/**
	 * 
	 * @param id
	 * @return
	 */
	public boolean isMatch(int id1, long id2) {
		return id1 == (int) id2;
	}

	public boolean getAuthorityEdit() {
		return authority_edit;
	}

	public boolean getAuthorityDelete() {
		return authority_delete;
	}

	/**
	 * 共有メンバーを取得します。
	 * 
	 * @return
	 */
	public List getMemberList() {
		return members;
	}

	/**
	 * アクセス権限チェック用メソッド。<br />
	 * アクセス権限の機能名を返します。
	 * 
	 * @return
	 */
	public String getAclPortletFeature() {
		return ALAccessControlConstants.POERTLET_FEATURE_MSGBOARD_CATEGORY;
	}

}
