/*
* Aipo is a groupware program developed by TOWN, Inc.
* Copyright (C) 2004-2015 TOWN, Inc.
* http://www.aipo.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.aimluck.eip.mail;
import java.util.Calendar;
import org.apache.cayenne.access.DataContext;
import org.apache.jetspeed.om.security.JetspeedUser;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.turbine.om.security.User;
import com.aimluck.eip.cayenne.om.portlet.EipMMailAccount;
import com.aimluck.eip.mail.util.ALMailUtils;
import com.aimluck.eip.mail.util.ALStaticObject;
import com.aimluck.eip.orm.Database;
import com.aimluck.eip.util.ALCommonUtils;
/**
* メール受信(POP3)を操作するクラスです。 <br />
*
*/
public class ALPop3MailReceiveThread implements Runnable {
/** 受信結果のキー(新着メール数) */
public static final String KEY_NEW_MAIL_NUM = "nmn";
/** 受信結果のキー(受信メール数) */
public static final String KEY_RECEIVE_MAIL_NUM = "rmn";
/** 受信結果のキー(受信メール総数) */
public static final String KEY_RECEIVE_MAIL_ALL_NUM = "rman";
/** 受信中のキー */
public static final String KEY_RECEIVE_STAT = "rs";
/** 受信中のキー */
public static final String KEY_THREAD = "thread";
/** 処理タイプ(メール受信) */
public static final int PROCESS_TYPE_RECEIVEMAIL = 1;
/** 処理タイプ(新着メール確認) */
public static final int PROCESS_TYPE_GET_NEWMAILNUM = 2;
/** 処理タイプ(メール受信中断) */
public static final int PROCESS_TYPE_STOP_RECEIVEMAIL = 3;
/** 処理状態(終了) */
public static final int PROCESS_STAT_FINISHED = 0;
/** 処理状態(実行中) */
public static final int PROCESS_STAT_PROCESSING = -100;
/** 処理状態(未実行) */
public static final int PROCESS_STAT_NONPROCESSING = -101;
/** データベース ID */
private String orgId = null;
/** ユーザー ID */
private String userId = null;
/** メールアカウント ID */
private int mailAccountId = 0;
/** 処理タイプ */
private int processType = PROCESS_TYPE_RECEIVEMAIL;
/** logger */
private static final JetspeedLogger logger = JetspeedLogFactoryService
.getLogger(ALPop3MailReceiveThread.class.getName());
/**
* コンストラクタ
*
* @param orgId
* @param userId
* @param mailAccountId
*/
public ALPop3MailReceiveThread(String orgId, JetspeedUser user,
int mailAccountId, int processType) {
this.orgId = orgId;
this.mailAccountId = mailAccountId;
this.processType = processType;
userId = user.getUserId();
ALStaticObject ob = ALStaticObject.getInstance();
ob.addAccountId(mailAccountId);
}
/**
* メール受信処理
*
*/
@Override
public void run() {
ALStaticObject ob = ALStaticObject.getInstance();
try {
DataContext.bindThreadDataContext(Database.createDataContext(orgId));
EipMMailAccount account =
ALMailUtils.getMailAccount(Integer.parseInt(userId), mailAccountId);
if (processType == PROCESS_TYPE_RECEIVEMAIL) {
logger
.info("[ALFilePop3MailReceiveThread] start receivemail (orgId, userId, mailAccountId)=("
+ Database.getDomainName()
+ ","
+ userId
+ ","
+ mailAccountId
+ ")");
// メール受信
int res = receiveMail(orgId, account);
ob.updateAccountStat(mailAccountId, KEY_RECEIVE_MAIL_NUM, Integer
.valueOf(res));
} else if (processType == PROCESS_TYPE_GET_NEWMAILNUM) {
logger
.info("[ALFilePop3MailReceiveThread] start newmailnum (orgId, userId, mailAccountId)=("
+ orgId
+ ","
+ userId
+ ","
+ mailAccountId
+ ")");
// 新着メール数確認
int res = checkNewMailNum(orgId, account);
if (res >= 0) {
ob.updateAccountStat(mailAccountId, KEY_NEW_MAIL_NUM, Integer
.valueOf(res));
}
}
} catch (Exception e) {
logger.error("ALFilePop3MailReceiveThread.run", e);
} finally {
Database.tearDown();
ob.updateAccountStat(
mailAccountId,
KEY_RECEIVE_STAT,
PROCESS_STAT_FINISHED);
ALStaticObject.getInstance().removeAccountId(mailAccountId);
}
}
/**
* 指定されたアカウントのメールを受信する。
*
* @param account
*/
private int receiveMail(String orgId, EipMMailAccount account) {
ALStaticObject.getInstance().updateAccountStat(
mailAccountId,
KEY_RECEIVE_STAT,
PROCESS_STAT_PROCESSING);
int result = ALPop3MailReceiver.RECEIVE_MSG_FAIL;
if (account == null) {
return result;
}
try {
ALMailHandler handler =
ALMailFactoryService.getInstance().getMailHandler();
ALMailReceiverContext rcontext =
ALMailUtils.getALPop3MailReceiverContext(orgId, account);
result = handler.receive(rcontext, orgId);
if (result <= ALPop3MailReceiver.RECEIVE_MSG_FAIL
&& result != ALPop3MailReceiver.RECEIVE_MSG_FAIL_OVER_MAIL_MAX_SIZE) {
// 受信に失敗した場合の処理
return result;
}
// 最終受信日を保存する.
DataContext dataContext = account.getDataContext();
account.setLastReceivedDate(Calendar.getInstance().getTime());
Database.commit(dataContext);
} catch (Exception ex) {
Database.rollback();
logger.error("ALFilePop3MailReceiveThread.receiveMail", ex);
result = ALPop3MailReceiver.RECEIVE_MSG_FAIL;
return result;
}
return result;
}
/**
* 指定されたアカウントの新着メール数を取得する。
*
* @param account
*/
private int checkNewMailNum(String orgId, EipMMailAccount account) {
int res = -1;
if (account == null) {
return res;
}
try {
ALMailHandler handler =
ALMailFactoryService.getInstance().getMailHandler();
ALMailReceiverContext rcontext =
ALMailUtils.getALPop3MailReceiverContext(orgId, account);
res = handler.getNewMailSum(rcontext);
} catch (Exception ex) {
logger.error("ALFilePop3MailReceiveThread.checkNewMailNum", ex);
res = -1;
}
return res;
}
/**
* 新着メール数を取得する。
*
* @param user
* @return
*/
public static int getNewMailNum(User user, int mailAccountId) {
if (user == null) {
return PROCESS_STAT_NONPROCESSING;
}
ALStaticObject ob = ALStaticObject.getInstance();
Object obj = ob.getAccountStat(mailAccountId, KEY_NEW_MAIL_NUM);
if (obj == null) {
return PROCESS_STAT_NONPROCESSING;
}
return ((Integer) obj).intValue();
}
/**
* 指定したユーザーのaccountIdが存在するかどうかチェック
*
* @param user
* @return
*/
public static boolean isProcessing(User user, int mailAccountId) {
return !(ALStaticObject.getInstance().receivable(mailAccountId));
}
/**
* 指定したユーザーがメールを受信中かどうかチェック
*
* @param user
* @return
*/
public static boolean isReceiving(User user, int mailAccountId,
String mailReceiveThreadStatus) {
Object objRS =
ALStaticObject.getInstance().getAccountStat(
mailAccountId,
KEY_RECEIVE_STAT);
// メール受信を開始しているかどうかをチェック
if ("1".equals(mailReceiveThreadStatus)) {
return true;
}
if (objRS == null || (Integer) objRS != PROCESS_STAT_PROCESSING) {
return false;
}
return true;
}
/**
* 受信結果を取得する。
*
* @param user
* @return
*/
public static int getReceiveMailResult(User user, int mailAccountId) {
ALStaticObject ob = ALStaticObject.getInstance();
Object obj = ob.getAccountStat(mailAccountId, KEY_RECEIVE_MAIL_NUM);
if (obj == null) {
return PROCESS_STAT_NONPROCESSING;
}
return ((Integer) obj).intValue();
}
public static String getReceiveMailResultStr(User user, int mailAccountId,
String mailReceiveThreadStatus) {
String msg = null;
if (isReceiving(user, mailAccountId, mailReceiveThreadStatus)) {
StringBuffer sb = new StringBuffer();
Object objRMAN =
ALStaticObject.getInstance().getAccountStat(
mailAccountId,
KEY_RECEIVE_MAIL_ALL_NUM);
Object objRMN =
ALStaticObject.getInstance().getAccountStat(
mailAccountId,
KEY_RECEIVE_MAIL_NUM);
if (objRMAN != null) {
sb
.append("メールを受信中です( ")
.append(objRMAN)
.append(" 件中 ")
.append(objRMN)
.append(" 件を受信 )。");
} else {
sb.append("メール受信サーバに問い合わせ中です。");
}
return sb.toString();
}
// 処理が終了している場合
int res = getReceiveMailResult(user, mailAccountId);
if (res == PROCESS_STAT_NONPROCESSING) {
msg = "";
return msg;
} else if (res == ALPop3MailReceiver.RECEIVE_MSG_FAIL) {
msg = "メールを受信できませんでした。メールアカウントの設定をご確認ください。";
} else if (res == ALPop3MailReceiver.RECEIVE_MSG_FAIL_LOCKED) {
msg = "メールの受信中、もしくは、メンテナンス中です。しばらくしてから、『メール一覧』ボタンを押してください。";
} else if (res == ALPop3MailReceiver.RECEIVE_MSG_FAIL_OVER_MAIL_MAX_SIZE) {
int size = ALCommonUtils.getMaxFileSize();
msg =
(size + "MB よりも大きいサイズのメールがありました。" + size + "MBを超えたメールの場合は、送信者などの情報のみ受信し、本文は受信しません。");
} else if (res == ALPop3MailReceiver.RECEIVE_MSG_FAIL_CONNECT) {
msg = "設定されている受信サーバ(POP3)と接続できませんでした。";
} else if (res == ALPop3MailReceiver.RECEIVE_MSG_FAIL_AUTH) {
msg = "設定されている受信サーバ(POP3)へのログインに失敗しました。";
} else if (res == ALPop3MailReceiver.RECEIVE_MSG_FAIL_EXCEPTION) {
msg = "システム上の問題により、メールを受信できませんでした(Exception エラー)。";
} else if (res == ALPop3MailReceiver.RECEIVE_MSG_FAIL_OUTOFMEMORY) {
msg = "システム上の問題により、メールを受信できませんでした(OutOfMemory エラー)。";
} else {
msg = "メールを受信しました。";
}
ALStaticObject.getInstance().removeAccountId(mailAccountId);
return msg;
}
}