/*
 * 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.util;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.imageio.ImageIO;

import org.apache.cayenne.DataRow;
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.jetspeed.services.resources.JetspeedResources;
import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.eip.cayenne.om.portlet.EipTMsgboardCategory;
import com.aimluck.eip.cayenne.om.portlet.EipTMsgboardCategoryMap;
import com.aimluck.eip.cayenne.om.portlet.EipTMsgboardFile;
import com.aimluck.eip.cayenne.om.portlet.EipTMsgboardTopic;
import com.aimluck.eip.cayenne.om.security.TurbineUser;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.fileupload.beans.FileuploadLiteBean;
import com.aimluck.eip.fileupload.util.FileuploadUtils;
import com.aimluck.eip.msgboard.MsgboardCategoryResultData;
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.ALEipUtils;
import com.aimluck.eip.whatsnew.util.WhatsNewUtils;

/**
 * 掲示板のユーティリティクラス <BR>
 * 
 */
public class MsgboardUtils {

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

	/** 所有者の識別子 */
	public static final String OWNER_ID = "ownerid";

	/** 掲示板の添付ファイルを保管するディレクトリの指定 */
	private static final String FOLDER_FILEDIR_MSGBOARD = JetspeedResources
			.getString("aipo.filedir", "");

	/** 全てのユーザーが閲覧／返信可 */
	public static final int ACCESS_PUBLIC_ALL = 0;

	/** 全てのユーザーが閲覧可。ただし返信できるのは所属メンバーのみ。 */
	public static final int ACCESS_PUBLIC_MEMBER = 1;

	/** 所属メンバーのみ閲覧／閲覧可 */
	public static final int ACCESS_SEACRET_MEMBER = 2;

	/** 自分のみ閲覧／返信可 */
	public static final int ACCESS_SEACRET_SELF = 3;

	/** カテゴリの公開／非公開の値（公開） */
	public static final String PUBLIC_FLG_VALUE_PUBLIC = "T";

	/** カテゴリの公開／非公開の値（非公開） */
	public static final String PUBLIC_FLG_VALUE_NONPUBLIC = "F";

	/** カテゴリの状態値（自分のみのカテゴリ） */
	public static final String STAT_VALUE_OWNER = "O";

	/** カテゴリの状態値（共有カテゴリ） */
	public static final String STAT_VALUE_SHARE = "S";

	/** カテゴリの状態値（公開カテゴリ） */
	public static final String STAT_VALUE_ALL = "A";

	/**
	 * トピックオブジェクトモデルを取得します。 <BR>
	 * 
	 * @param rundata
	 * @param context
	 * @param isJoin
	 *            カテゴリテーブルをJOINするかどうか
	 * @return
	 */
	public static EipTMsgboardTopic getEipTMsgboardParentTopic(RunData rundata,
			Context context, boolean isJoin) throws ALPageNotFoundException,
			ALDBErrorException {
		String topicid = ALEipUtils.getTemp(rundata, context,
				ALEipConstants.ENTITY_ID);
		try {
			if (topicid == null || Integer.valueOf(topicid) == null) {
				// トピック ID が空の場合
				logger.debug("[MsgboardTopic] Empty ID...");
				throw new ALPageNotFoundException();
			}

			int userid = ALEipUtils.getUserId(rundata);

			DataContext dataContext = DatabaseOrmService.getInstance()
					.getDataContext();
			SelectQuery query = new SelectQuery(EipTMsgboardTopic.class);
			Expression exp1 = ExpressionFactory.matchDbExp(
					EipTMsgboardTopic.TOPIC_ID_PK_COLUMN, Integer
							.valueOf(topicid));
			query.setQualifier(exp1);
			Expression exp2 = ExpressionFactory.matchExp(
					EipTMsgboardTopic.PARENT_ID_PROPERTY, Integer.valueOf(0));
			query.andQualifier(exp2);

			// アクセス制御
			Expression exp11 = ExpressionFactory.matchExp(
					EipTMsgboardTopic.EIP_TMSGBOARD_CATEGORY_PROPERTY + "."
							+ EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY, "T");
			Expression exp12 = ExpressionFactory.matchExp(
					EipTMsgboardTopic.EIP_TMSGBOARD_CATEGORY_PROPERTY + "."
							+ EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY, "F");
			Expression exp13 = ExpressionFactory
					.matchExp(
							EipTMsgboardTopic.EIP_TMSGBOARD_CATEGORY_PROPERTY
									+ "."
									+ EipTMsgboardCategory.EIP_TMSGBOARD_CATEGORY_MAPS_PROPERTY
									+ "."
									+ EipTMsgboardCategoryMap.USER_ID_PROPERTY,
							Integer.valueOf(userid));
			query.andQualifier(exp11.orExp(exp12.andExp(exp13)));
			query.setDistinct(true);

			List topics = dataContext.performQuery(query);
			if (topics == null || topics.size() == 0) {
				// 指定した トピック ID のレコードが見つからない場合
				logger.debug("[MsgboardTopic] Not found ID...");
				throw new ALPageNotFoundException();
			}

			EipTMsgboardTopic topic = ((EipTMsgboardTopic) topics.get(0));
			return topic;
		} catch (Exception ex) {
			// TODO: エラー処理
			logger.error("[MsgboardUtils]", ex);
			throw new ALDBErrorException();

		}
	}

	/**
	 * 返信記事オブジェクトモデルを取得します。 <BR>
	 * 
	 * @param rundata
	 * @param context
	 * @param isJoin
	 *            カテゴリテーブルをJOINするかどうか
	 * @return
	 */
	public static EipTMsgboardTopic getEipTMsgboardTopicReply(RunData rundata,
			Context context, String topicid, boolean isJoin)
			throws ALPageNotFoundException, ALDBErrorException {
		try {
			if (topicid == null || Integer.valueOf(topicid) == null) {
				// トピック ID が空の場合
				logger.debug("[MsgboardTopic] Empty ID...");
				throw new ALPageNotFoundException();
			}

			DataContext dataContext = DatabaseOrmService.getInstance()
					.getDataContext();
			SelectQuery query = new SelectQuery(EipTMsgboardTopic.class);
			Expression exp1 = ExpressionFactory.matchDbExp(
					EipTMsgboardTopic.TOPIC_ID_PK_COLUMN, Integer
							.valueOf(topicid));
			query.setQualifier(exp1);
			// Expression exp2 = ExpressionFactory.matchDbExp("owner_id", new
			// Integer(
			// ALEipUtils.getUserId(rundata)));
			Expression exp2 = ExpressionFactory.matchExp(
					EipTMsgboardTopic.OWNER_ID_PROPERTY, Integer
							.valueOf(ALEipUtils.getUserId(rundata)));
			query.andQualifier(exp2);

			List topics = dataContext.performQuery(query);
			if (topics == null || topics.size() == 0) {
				// 指定した トピック ID のレコードが見つからない場合
				logger.debug("[MsgboardTopic] Not found ID...");
				throw new ALPageNotFoundException();
			}
			return ((EipTMsgboardTopic) topics.get(0));
		} catch (Exception ex) {

			// TODO: エラー処理
			logger.error("[MsgboardUtils]", ex);
			throw new ALDBErrorException();

		}
	}

	/**
	 * ファイルオブジェクトモデルを取得します。 <BR>
	 * 
	 * @param rundata
	 * @param context
	 * @return
	 */
	public static EipTMsgboardFile getEipTMsgboardFile(RunData rundata)
			throws ALPageNotFoundException, ALDBErrorException {
		try {
			int attachmentIndex = rundata.getParameters().getInt(
					"attachmentIndex", -1);
			if (attachmentIndex < 0) {
				// ID が空の場合
				logger.debug("[MsgboardUtils] Empty ID...");
				throw new ALPageNotFoundException();

			}

			DataContext dataContext = DatabaseOrmService.getInstance()
					.getDataContext();
			SelectQuery query = new SelectQuery(EipTMsgboardFile.class);
			Expression exp = ExpressionFactory.matchDbExp(
					EipTMsgboardFile.FILE_ID_PK_COLUMN, Integer
							.valueOf(attachmentIndex));
			query.andQualifier(exp);
			List files = dataContext.performQuery(query);
			if (files == null || files.size() == 0) {
				// 指定した ID のレコードが見つからない場合
				logger.debug("[MsgboardUtils] Not found ID...");
				throw new ALPageNotFoundException();
			}
			return (EipTMsgboardFile) files.get(0);
		} catch (Exception ex) {
			// TODO: エラー処理
			logger.error("[MsgboardUtils]", ex);
			throw new ALDBErrorException();
		}
	}

	/**
	 * トピックオブジェクトモデルを取得します。 <BR>
	 * 
	 * @param rundata
	 * @param context
	 * @param isJoin
	 *            カテゴリテーブルをJOINするかどうか
	 * @return
	 */
	public static List getEipTMsgboardTopicList(RunData rundata,
			Context context, boolean isJoin) throws ALPageNotFoundException,
			ALDBErrorException {
		String topicid = ALEipUtils.getTemp(rundata, context,
				ALEipConstants.ENTITY_ID);
		try {
			if (topicid == null || Integer.valueOf(topicid) == null) {
				// トピック ID が空の場合
				logger.debug("[MsgboardTopic] Empty ID...");
				throw new ALPageNotFoundException();
			}

			DataContext dataContext = DatabaseOrmService.getInstance()
					.getDataContext();
			SelectQuery query = new SelectQuery(EipTMsgboardTopic.class);
			Expression exp001 = ExpressionFactory.matchExp(
					EipTMsgboardTopic.PARENT_ID_PROPERTY, Integer
							.valueOf(topicid));

			// アクセス制御
			Expression exp01 = ExpressionFactory.matchDbExp(
					EipTMsgboardTopic.TOPIC_ID_PK_COLUMN, Integer
							.valueOf(topicid));
			Expression exp11 = ExpressionFactory.matchExp(
					EipTMsgboardTopic.EIP_TMSGBOARD_CATEGORY_PROPERTY + "."
							+ EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY, "T");
			Expression exp21 = ExpressionFactory.matchExp(
					EipTMsgboardTopic.EIP_TMSGBOARD_CATEGORY_PROPERTY + "."
							+ EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY, "F");
			Expression exp22 = ExpressionFactory
					.matchExp(
							EipTMsgboardTopic.EIP_TMSGBOARD_CATEGORY_PROPERTY
									+ "."
									+ EipTMsgboardCategory.EIP_TMSGBOARD_CATEGORY_MAPS_PROPERTY
									+ "."
									+ EipTMsgboardCategoryMap.USER_ID_PROPERTY,
							Integer.valueOf(ALEipUtils.getUserId(rundata)));
			query.setQualifier((exp01.andExp(exp11.orExp(exp21.andExp(exp22))))
					.orExp(exp001));
			query.setDistinct(true);

			List topics = dataContext.performQuery(query);
			if (topics == null || topics.size() == 0) {
				// 指定した トピック ID のレコードが見つからない場合
				logger.debug("[MsgboardTopic] Not found ID...");
				throw new ALPageNotFoundException();
			}
			return topics;
		} catch (Exception ex) {

			// TODO: エラー処理
			logger.error("[MsgboardUtils]", ex);
			throw new ALDBErrorException();

		}
	}

	/**
	 * トピックオブジェクトモデルを取得します。 <BR>
	 * 
	 * @param rundata
	 * @param context
	 * @param isJoin
	 *            カテゴリテーブルをJOINするかどうか
	 * @return
	 */
	public static List getEipTMsgboardTopicListToDeleteTopic(RunData rundata,
			Context context, boolean isJoin) throws ALPageNotFoundException,
			ALDBErrorException {
		String topicid = ALEipUtils.getTemp(rundata, context,
				ALEipConstants.ENTITY_ID);
		try {
			if (topicid == null || Integer.valueOf(topicid) == null) {
				// トピック ID が空の場合
				logger.debug("[MsgboardTopic] Empty ID...");
				throw new ALPageNotFoundException();
			}

			int userid = ALEipUtils.getUserId(rundata);

			DataContext dataContext = DatabaseOrmService.getInstance()
					.getDataContext();
			SelectQuery query = new SelectQuery(EipTMsgboardTopic.class);
			Expression exp01 = ExpressionFactory.matchDbExp(
					EipTMsgboardTopic.OWNER_ID_COLUMN, Integer.valueOf(userid));
			Expression exp02 = ExpressionFactory.matchDbExp(
					EipTMsgboardTopic.TOPIC_ID_PK_COLUMN, Integer
							.valueOf(topicid));
			Expression exp03 = ExpressionFactory.matchExp(
					EipTMsgboardTopic.PARENT_ID_PROPERTY, Integer
							.valueOf(topicid));
			query.andQualifier((exp01.andExp(exp02)).orExp(exp03));
			List topics = dataContext.performQuery(query);
			if (topics == null || topics.size() == 0) {
				// 指定した トピック ID のレコードが見つからない場合
				logger.debug("[MsgboardTopic] Not found ID...");
				throw new ALPageNotFoundException();
			}

			boolean isdelete = false;
			int size = topics.size();
			for (int i = 0; i < size; i++) {
				EipTMsgboardTopic topic = (EipTMsgboardTopic) topics.get(i);
				if (topic.getOwnerId().intValue() == userid) {
					isdelete = true;
					break;
				}
			}
			if (!isdelete) {
				// 指定した トピック ID のレコードが見つからない場合
				logger.debug("[MsgboardTopic] Not found ID...");
				throw new ALPageNotFoundException();
			}

			return topics;
		} catch (Exception ex) {
			// TODO: エラー処理
			logger.error("[MsgboardUtils]", ex);
			throw new ALDBErrorException();

		}
	}

	/**
	 * カテゴリオブジェクトモデルを取得します。 <BR>
	 * 
	 * @param rundata
	 * @param context
	 * @return
	 */
	public static EipTMsgboardCategory getEipTMsgboardCategory(RunData rundata,
			Context context, boolean ownerOnly) throws ALPageNotFoundException,
			ALDBErrorException {
		String categoryid = ALEipUtils.getTemp(rundata, context,
				ALEipConstants.ENTITY_ID);
		try {
			if (categoryid == null || Integer.valueOf(categoryid) == null) {
				// カテゴリ IDが空の場合
				logger.debug("[MsgboardCategory] Empty ID...");
				throw new ALPageNotFoundException();
			}

			DataContext dataContext = DatabaseOrmService.getInstance()
					.getDataContext();
			SelectQuery query = new SelectQuery(EipTMsgboardCategory.class);

			Expression exp1 = ExpressionFactory.matchDbExp(
					EipTMsgboardCategory.CATEGORY_ID_PK_COLUMN, Integer
							.valueOf(categoryid));
			query.setQualifier(exp1);
			Expression exp2 = ExpressionFactory
					.noMatchDbExp(EipTMsgboardCategory.TURBINE_USER_PROPERTY
							+ "." + TurbineUser.USER_ID_PK_COLUMN, Integer
							.valueOf(0));
			query.andQualifier(exp2);
			if (ownerOnly) {
				/*
				 * Expression exp3 = ExpressionFactory.matchDbExp(
				 * EipTMsgboardCategory.TURBINE_USER_PROPERTY + "." +
				 * TurbineUser.USER_ID_PK_COLUMN, Integer.valueOf(ALEipUtils
				 * .getUserId(rundata))); query.andQualifier(exp3);
				 */
			}

			// アクセス制御

			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(
					EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY, "T");
			Expression exp02 = ExpressionFactory.matchExp(
					EipTMsgboardCategory.EIP_TMSGBOARD_CATEGORY_MAPS_PROPERTY
							+ "." + EipTMsgboardCategoryMap.STATUS_PROPERTY,
					"O");
			Expression exp03 = ExpressionFactory.matchExp(
					EipTMsgboardCategory.EIP_TMSGBOARD_CATEGORY_MAPS_PROPERTY
							+ "." + EipTMsgboardCategoryMap.STATUS_PROPERTY,
					"A");
			Expression exp11 = ExpressionFactory.matchExp(
					EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY, "F");
			Expression exp12 = ExpressionFactory.matchExp(
					EipTMsgboardCategory.EIP_TMSGBOARD_CATEGORY_MAPS_PROPERTY
							+ "." + EipTMsgboardCategoryMap.USER_ID_PROPERTY,
					Integer.valueOf(loginUserId));

			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);

			List categories = dataContext.performQuery(query);
			if (categories == null || categories.size() == 0) {
				// 指定したカテゴリ IDのレコードが見つからない場合
				logger.debug("[MsgboardUtils] Not found ID...");
				throw new ALPageNotFoundException();
			}
			return ((EipTMsgboardCategory) categories.get(0));
		} catch (Exception ex) {
			// TODO: エラー処理
			logger.error("[MsgboardUtils]", ex);
			throw new ALDBErrorException();

		}
	}

	/**
	 * <BR>
	 * 
	 * @param rundata
	 * @param context
	 * @return
	 */
	public static List getWhatsNewInsertList(RunData rundata, int categoryid,
			String is_public) throws ALPageNotFoundException,
			ALDBErrorException {

		int userid = ALEipUtils.getUserId(rundata);
		DataContext dataContext = DatabaseOrmService.getInstance()
				.getDataContext();
		List result = new ArrayList();

		if ("F".equals(is_public)) {
			try {

				SelectQuery query = new SelectQuery(
						EipTMsgboardCategoryMap.class);
				query
						.addCustomDbAttribute(EipTMsgboardCategoryMap.USER_ID_COLUMN);

				Expression exp1 = ExpressionFactory.matchExp(
						EipTMsgboardCategoryMap.CATEGORY_ID_PROPERTY, Integer
								.valueOf(categoryid));
				query.setQualifier(exp1);

				// アクセス制御
				Expression exp11 = ExpressionFactory.matchExp(
						EipTMsgboardCategoryMap.EIP_TMSGBOARD_CATEGORY_PROPERTY
								+ "."
								+ EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY,
						"T");
				Expression exp12 = ExpressionFactory.matchExp(
						EipTMsgboardCategoryMap.EIP_TMSGBOARD_CATEGORY_PROPERTY
								+ "."
								+ EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY,
						"F");
				Expression exp13 = ExpressionFactory.matchExp(
						EipTMsgboardCategoryMap.STATUS_PROPERTY, "S");
				query.andQualifier(exp11.orExp(exp12.andExp(exp13)));
				query.setDistinct(true);

				List uids = dataContext.performQuery(query);

				if (uids != null && uids.size() != 0) {
					int size = uids.size();
					for (int i = 0; i < size; i++) {
						DataRow uid = (DataRow) uids.get(i);
						Integer id = (Integer) ALEipUtils.getObjFromDataRow(
								uid, EipTMsgboardCategoryMap.USER_ID_COLUMN);
						if (id.intValue() != userid) {
							result.add(ALEipUtils.getALEipUser(id.intValue()));
						}
					}
				}

				/* メンバー全員に新着ポートレット登録 */
				ALAccessControlFactoryService aclservice = (ALAccessControlFactoryService) ((TurbineServices) TurbineServices
						.getInstance())
						.getService(ALAccessControlFactoryService.SERVICE_NAME);
				ALAccessControlHandler aclhandler = aclservice
						.getAccessControlHandler();
				List userIds = aclhandler
						.getAcceptUserIdsInListExceptLoginUser(
								dataContext,
								(int) ALEipUtils.getUserId(rundata),
								ALAccessControlConstants.POERTLET_FEATURE_MSGBOARD_TOPIC,
								ALAccessControlConstants.VALUE_ACL_DETAIL,
								result);

				return userIds;
			} catch (Exception ex) {
				// TODO: エラー処理
				logger.error("[MsgboardUtils]", ex);
				throw new ALDBErrorException();
			}
		} else {
			/* 自分以外の全員に新着ポートレット登録 */
			ALAccessControlFactoryService aclservice = (ALAccessControlFactoryService) ((TurbineServices) TurbineServices
					.getInstance())
					.getService(ALAccessControlFactoryService.SERVICE_NAME);
			ALAccessControlHandler aclhandler = aclservice
					.getAccessControlHandler();
			List userIds = aclhandler.getAcceptUserIdsExceptLoginUser(
					dataContext, ALEipUtils.getUserId(rundata),
					ALAccessControlConstants.POERTLET_FEATURE_MSGBOARD_TOPIC,
					ALAccessControlConstants.VALUE_ACL_DETAIL);
			return userIds;

		}
	}

	public static ArrayList loadCategoryList(RunData rundata) {
		// カテゴリ一覧
		ArrayList categoryList = new ArrayList();
		try {
			DataContext dataContext = DatabaseOrmService.getInstance()
					.getDataContext();
			SelectQuery query = new SelectQuery(EipTMsgboardCategory.class);

			// アクセス制御
			Expression exp01 = ExpressionFactory.matchExp(
					EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY,
					MsgboardUtils.PUBLIC_FLG_VALUE_PUBLIC);
			Expression exp02 = ExpressionFactory.matchExp(
					EipTMsgboardCategory.EIP_TMSGBOARD_CATEGORY_MAPS_PROPERTY
							+ "." + EipTMsgboardCategoryMap.STATUS_PROPERTY,
					MsgboardUtils.STAT_VALUE_OWNER);
			Expression exp03 = ExpressionFactory.matchExp(
					EipTMsgboardCategory.EIP_TMSGBOARD_CATEGORY_MAPS_PROPERTY
							+ "." + EipTMsgboardCategoryMap.STATUS_PROPERTY,
					MsgboardUtils.STAT_VALUE_ALL);
			Expression exp11 = ExpressionFactory.matchExp(
					EipTMsgboardCategory.PUBLIC_FLAG_PROPERTY,
					MsgboardUtils.PUBLIC_FLG_VALUE_NONPUBLIC);
			Expression exp12 = ExpressionFactory.matchExp(
					EipTMsgboardCategory.EIP_TMSGBOARD_CATEGORY_MAPS_PROPERTY
							+ "." + EipTMsgboardCategoryMap.USER_ID_PROPERTY,
					Integer.valueOf(ALEipUtils.getUserId(rundata)));
			query.setQualifier((exp01.andExp(exp02.orExp(exp03))).orExp(exp11
					.andExp(exp12)));
			query.setDistinct(true);

			MsgboardCategoryResultData otherRd = null;
			List aList = dataContext.performQuery(query);
			int size = aList.size();
			for (int i = 0; i < size; i++) {
				EipTMsgboardCategory record = (EipTMsgboardCategory) aList
						.get(i);
				MsgboardCategoryResultData rd = new MsgboardCategoryResultData();
				rd.initField();
				rd.setCategoryId(record.getCategoryId().longValue());
				rd.setCategoryName(record.getCategoryName());
				if (record.getCategoryId().longValue() == 1) {
					// カテゴリ「その他」は最後に追加するため，ここではリストに追加しない．
					otherRd = rd;
				} else {
					categoryList.add(rd);
				}
			}
			if (otherRd != null) {
				categoryList.add(otherRd);
			}
		} catch (Exception ex) {
			logger.error("Exception", ex);
			return null;
		}
		return categoryList;
	}

	public static boolean insertFileDataDelegate(RunData rundata,
			Context context, EipTMsgboardTopic topic, List fileuploadList,
			String folderName, ArrayList msgList) {

		if (fileuploadList == null || fileuploadList.size() <= 0) {
			return true;
		}

		DataContext dataContext = DatabaseOrmService.getInstance()
				.getDataContext();
		int uid = ALEipUtils.getUserId(rundata);
		String org_id = DatabaseOrmService.getInstance().getOrgId(rundata);

		try {
			FileuploadLiteBean filebean = null;
			int size = fileuploadList.size();
			for (int i = 0; i < size; i++) {
				filebean = (FileuploadLiteBean) fileuploadList.get(i);

				// サムネイル処理
				String[] acceptExts = ImageIO.getWriterFormatNames();
				byte[] fileThumbnail = FileuploadUtils.getBytesShrinkFilebean(
						org_id, folderName, uid, filebean, acceptExts,
						FileuploadUtils.DEF_THUMBNAIL_WIDTH,
						FileuploadUtils.DEF_THUMBNAIL_HEIGTH, msgList);

				String filename = FileuploadUtils.getNewFileName(MsgboardUtils
						.getSaveDirPath(org_id, uid));

				// 新規オブジェクトモデル
				EipTMsgboardFile file = (EipTMsgboardFile) dataContext
						.createAndRegisterNewObject(EipTMsgboardFile.class);
				// 所有者
				file.setOwnerId(Integer.valueOf(uid));
				// トピックID
				file.setEipTMsgboardTopic(topic);
				// ファイル名
				file.setFileName(filebean.getFileName());
				// ファイルパス
				file.setFilePath(MsgboardUtils.getRelativePath(filename));
				// サムネイル画像
				if (fileThumbnail != null) {
					file.setFileThumbnail(fileThumbnail);
				}
				// 作成日
				file.setCreateDate(Calendar.getInstance().getTime());
				// 更新日
				file.setUpdateDate(Calendar.getInstance().getTime());

				// ファイルの移動
				File srcFile = FileuploadUtils.getAbsolutePath(org_id, uid,
						folderName, filebean.getFileId());
				File destFile = new File(MsgboardUtils.getAbsolutePath(org_id,
						uid, filename));
				FileuploadUtils.copyFile(srcFile, destFile);

				srcFile = null;
				destFile = null;
			}

			// 添付ファイル保存先のフォルダを削除
			File folder = FileuploadUtils.getFolder(org_id, uid, folderName);
			FileuploadUtils.deleteFolder(folder);
		} catch (Exception e) {
			logger.error("Exception", e);
			return false;
		}
		return true;
	}

	/**
	 * ユーザ毎のルート保存先（絶対パス）を取得します。
	 * 
	 * @param uid
	 * @return
	 */
	public static String getSaveDirPath(String orgId, int uid) {
		return FOLDER_FILEDIR_MSGBOARD + File.separator + orgId
				+ File.separator + "msgboard" + File.separator + uid;
	}

	/**
	 * ユーザ毎の保存先（相対パス）を取得します。
	 * 
	 * @param uid
	 * @return
	 */
	public static String getRelativePath(String fileName) {
		return new StringBuffer().append("/").append(fileName).toString();
	}

	/**
	 * 添付ファイル保存先（絶対パス）を取得します。
	 * 
	 * @param uid
	 * @return
	 */
	public static String getAbsolutePath(String orgId, int uid, String fileName) {
		StringBuffer sb = new StringBuffer().append(FOLDER_FILEDIR_MSGBOARD)
				.append(File.separator).append(orgId).append(File.separator)
				.append("msgboard").append(File.separator).append(uid);

		File f = new File(sb.toString());
		if (!f.exists()) {
			f.mkdirs();
		}

		return sb.append(File.separator).append(fileName).toString();
	}

	public static void shiftWhatsNewReadFlag(RunData rundata, int entityid) {
		int uid = ALEipUtils.getUserId(rundata);
		DataContext dataContext = DatabaseOrmService.getInstance()
				.getDataContext();

		SelectQuery query = new SelectQuery(EipTMsgboardTopic.class);
		Expression exp = ExpressionFactory.matchExp(
				EipTMsgboardTopic.PARENT_ID_PROPERTY, entityid);
		query.setQualifier(exp);
		query.addCustomDbAttribute(EipTMsgboardTopic.TOPIC_ID_PK_COLUMN);
		query.setDistinct(true);

		List topics = dataContext.performQuery(query);
		if (topics != null) {
			int size = topics.size();
			DataRow dataRow = null;
			Integer _id = null;
			for (int i = 0; i < size; i++) {
				dataRow = (DataRow) topics.get(i);
				_id = (Integer) dataRow
						.get(EipTMsgboardTopic.TOPIC_ID_PK_COLUMN);
				WhatsNewUtils.shiftWhatsNewReadFlag(
						WhatsNewUtils.WHATS_NEW_TYPE_MSGBOARD_TOPIC, _id
								.intValue(), uid);
			}
		}

		WhatsNewUtils.shiftWhatsNewReadFlag(
				WhatsNewUtils.WHATS_NEW_TYPE_MSGBOARD_TOPIC, entityid, uid);

	}

	/**
	 * アクセス権限をチェックします。
	 * 
	 * @return
	 */
	public static boolean CheckPermission(RunData rundata, Context context,
			int defineAclType, String pfeature) {

		if (defineAclType == 0) {
			return true;
		}

		if (pfeature == null || "".equals(pfeature)) {
			return true;
		}

		ALAccessControlFactoryService aclservice = (ALAccessControlFactoryService) ((TurbineServices) TurbineServices
				.getInstance())
				.getService(ALAccessControlFactoryService.SERVICE_NAME);
		ALAccessControlHandler aclhandler = aclservice
				.getAccessControlHandler();
		boolean hasAuthority = aclhandler.hasAuthority(ALEipUtils
				.getUserId(rundata), pfeature, defineAclType);

		return hasAuthority;
	}
}
