/* * 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.file; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.List; import java.util.Properties; import java.util.jar.Attributes; import javax.mail.Header; import javax.mail.Message; import javax.mail.Session; import javax.mail.internet.MimeMessage; import org.apache.cayenne.exp.Expression; import org.apache.cayenne.exp.ExpressionFactory; import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; import com.aimluck.eip.cayenne.om.portlet.EipTMail; import com.aimluck.eip.common.ALPageNotFoundException; import com.aimluck.eip.mail.ALAbstractFolder; import com.aimluck.eip.mail.ALLocalMailMessage; import com.aimluck.eip.mail.ALMailMessage; import com.aimluck.eip.orm.Database; import com.aimluck.eip.orm.query.SelectQuery; import com.aimluck.eip.services.storage.ALStorageService; import com.aimluck.eip.util.ALCommonUtils; /** * ローカルのファイルシステムを利用し、送受信したメールを保持するローカルフォルダのクラスです。 <br /> * */ public class ALFileLocalFolder extends ALAbstractFolder { private static final JetspeedLogger logger = JetspeedLogFactoryService .getLogger(ALFileLocalFolder.class.getName()); /** メールのファイル名規則 */ public static final String DEFAULT_MAIL_FILENAME_DATE_FORMAT = "yyyyMMddHHmmssSSS"; /** * コンストラクタ * * @param parentFolder * 親フォルダ * @param folderName * 自身のフォルダ名 */ public ALFileLocalFolder(int type_mail, String org_id, int user_id, int account_id) { super(type_mail, org_id, user_id, account_id); } /** * メールを取得します。 * * @param index * @return */ @Override public ALLocalMailMessage getMail(int mailid) { try { SelectQuery<EipTMail> query = Database.query(EipTMail.class); Expression exp1 = ExpressionFactory.matchDbExp(EipTMail.MAIL_ID_PK_COLUMN, Integer .valueOf(mailid)); Expression exp2 = ExpressionFactory.matchExp(EipTMail.USER_ID_PROPERTY, user_id); EipTMail email = query.setQualifier(exp1.andExp(exp2)).fetchSingle(); if (email == null) { logger.debug("[Mail] Not found ID..."); return null; } ALLocalMailMessage msg = readMail(getFullName() + ALStorageService.separator() + email.getFilePath()); // 未読→既読に変更 email.setReadFlg("T"); Database.commit(); return msg; } catch (Throwable t) { Database.rollback(); logger.error("ALFileLocalFolder.getMail", t); return null; } } /** * 指定されたファイルを読み込み,mail メッセージを取得する. * * @param fileName * @return */ private ALLocalMailMessage readMail(String filepath) { System.setProperty("mail.mime.charset", "ISO-2022-JP"); System.setProperty("mail.mime.decodetext.strict", "false"); Properties prop = new Properties(); prop.setProperty("mail.mime.address.strict", "false"); ALLocalMailMessage localmsg = null; BufferedInputStream input = null; try { input = new BufferedInputStream(ALStorageService.getFile(filepath)); localmsg = new ALLocalMailMessage(Session.getDefaultInstance(prop), input); input.close(); } catch (Exception ex) { logger.error("ALFileLocalFolder.readMail", ex); } return localmsg; } /** * メールを保存する。 * * @param messages * @return */ @Override public boolean saveMail(ALMailMessage mail, String orgId) { boolean res = false; try { String tmpFileName = getNewFileName(); res = saveMailToFile(mail, tmpFileName, true); if (res) { res = insertMailToDB((MimeMessage) mail, tmpFileName, false, false); } } catch (Exception ex) { logger.error("ALFileLocalFolder.saveMail", ex); res = false; } return res; } /** * 受信サーバから受信した受信可能サイズを超えたメールを保存する。<br /> * このメールはヘッダ情報のみ、受信サーバから取得し、他の情報は取得しない。 * * @param localMailMessage * @return */ @Override public boolean saveDefectiveMail(ALMailMessage mail, String orgId) { boolean res = false; try { String tmpFileName = getNewFileName(); res = saveMailToFile(mail, tmpFileName, false); if (res) { res = insertMailToDB((MimeMessage) mail, tmpFileName, false, false); } } catch (Exception ex) { logger.error("ALFileLocalFolder.saveDefectiveMail", ex); res = false; } return res; } /** * メールをファイルに保存します。 * * @param mail * @return */ private boolean saveMailToFile(ALMailMessage mail, String fileName, boolean savecontents) { boolean res = false; ByteArrayOutputStream output = null; try { // String pop3MailPath = getFullName() + File.separator + fileName; // メールの保存 output = new ByteArrayOutputStream(); if (savecontents) { mail.writeTo(output); } else { MimeMessage mimeMessage = (MimeMessage) mail; Session session = Session.getDefaultInstance(new Properties()); Message newMsg = new MimeMessage(session); Enumeration<?> headers = mimeMessage.getAllHeaders(); while (headers.hasMoreElements()) { Header h = (Header) headers.nextElement(); newMsg.addHeader(h.getName(), h.getValue()); } newMsg.setText("メールのサイズが" + ALCommonUtils.getMaxFileSize() + "MBを超えていたため、このメールを受信できませんでした。\r\n 誠に恐れ入りますが、別のメーラーで受信してください。"); newMsg.writeTo(output); } ALStorageService.createNewFile(new ByteArrayInputStream(output .toByteArray()), getFullName(), fileName); output.flush(); output.close(); mail.clearContents(); res = true; } catch (Exception ex) { logger.error("ALFileLocalFolder.saveMailToFile", ex); try { if (output != null) { output.close(); } } catch (IOException ie) { logger.error("ALFileLocalFolder.saveMailToFile", ie); } res = false; } finally { try { if (output != null) { output.close(); } } catch (IOException ie) { logger.error("ALFileLocalFolder.saveMailToFile", ie); res = false; } } return res; } /** * 指定されたインデックスのメールを削除する. * * @return */ @Override public boolean deleteMail(int mailid) { try { SelectQuery<EipTMail> query = Database.query(EipTMail.class); Expression exp1 = ExpressionFactory.matchDbExp(EipTMail.MAIL_ID_PK_COLUMN, Integer .valueOf(mailid)); Expression exp2 = ExpressionFactory.matchExp(EipTMail.USER_ID_PROPERTY, user_id); Expression exp3 = ExpressionFactory.matchExp(EipTMail.ACCOUNT_ID_PROPERTY, account_id); List<EipTMail> mail_list = query .andQualifier(exp1) .andQualifier(exp2) .andQualifier(exp3) .fetchList(); if (mail_list == null || mail_list.size() == 0) { logger.debug("[ALDbLocalFolder] Not found ID..."); throw new ALPageNotFoundException(); } EipTMail record = mail_list.get(0); String filePath = record.getFilePath(); // ファイル削除 ALStorageService.deleteFile(getFullName() + ALStorageService.separator() + filePath); // メールを削除する Database.delete(record); Database.commit(); } catch (Throwable t) { Database.rollback(); logger.error("ALFileLocalFolder.deleteMail", t); return false; } return true; } /** * 指定されたインデックスのメールを削除する. * * @param msgIndexes * @return */ @Override public boolean deleteMails(List<String> msgIndexes) { try { SelectQuery<EipTMail> query = Database.query(EipTMail.class); Expression exp1 = ExpressionFactory.inDbExp(EipTMail.MAIL_ID_PK_COLUMN, msgIndexes); Expression exp2 = ExpressionFactory.matchExp(EipTMail.USER_ID_PROPERTY, Integer .valueOf(user_id)); List<EipTMail> mail_list = query.andQualifier(exp1).andQualifier(exp2).fetchList(); if (mail_list == null || mail_list.size() == 0) { logger.debug("[ALFileLocalFolder] Not found ID..."); throw new ALPageNotFoundException(); } for (EipTMail record : mail_list) { String filePath = record.getFilePath(); ALStorageService.deleteFile(getFullName() + ALStorageService.separator() + filePath); } Database.deleteAll(mail_list); Database.commit(); } catch (Throwable t) { Database.rollback(); logger.error("ALFileLocalFolder.deleteMails", t); return false; } return true; } /** * * @return */ @Override protected Attributes getColumnMap() { Attributes map = new Attributes(); map.putValue("read_flg", EipTMail.READ_FLG_PROPERTY); map.putValue("subject", EipTMail.SUBJECT_PROPERTY); map.putValue("person", EipTMail.PERSON_PROPERTY); map.putValue("date", EipTMail.EVENT_DATE_PROPERTY); map.putValue("volume", EipTMail.FILE_VOLUME_PROPERTY); return map; } /** * 新着メール数を取得する。 * * @return */ @Override public int getNewMailNum() { return 0; } /** * 新着メール数を更新する. * * @param num */ @Override public void setNewMailNum(int num) { } /** * 指定したフォルダ内のメールの総数を取得する。 * * @param type * 送受信フラグ * @return */ public int getMailSum() { return 0; } /** * 指定したフォルダ内の未読メール数を取得する. * * @return */ @Override public int getUnreadMailNum() { return 0; } /** * ローカルフォルダを閉じる. */ @Override public void close() { } /** * 新しいファイル名を生成する. * * @return */ public String getNewFileName() { return String.valueOf(System.nanoTime()); } /** * @param msgIndexes * @return */ @Override public boolean readMails(List<String> msgIndexes) { try { SelectQuery<EipTMail> query = Database.query(EipTMail.class); Expression exp1 = ExpressionFactory.inDbExp(EipTMail.MAIL_ID_PK_COLUMN, msgIndexes); Expression exp2 = ExpressionFactory.matchExp(EipTMail.USER_ID_PROPERTY, Integer .valueOf(user_id)); List<EipTMail> mail_list = query.andQualifier(exp1).andQualifier(exp2).fetchList(); if (mail_list == null || mail_list.size() == 0) { logger.debug("[ALFileLocalFolder] Not found ID..."); throw new ALPageNotFoundException(); } for (EipTMail record : mail_list) { record.setReadFlg("T"); } Database.commit(); } catch (Throwable t) { Database.rollback(); logger.error("ALFileLocalFolder.readMails", t); return false; } return true; } @Override public boolean unreadMails(List<String> msgIndexes) { try { SelectQuery<EipTMail> query = Database.query(EipTMail.class); Expression exp1 = ExpressionFactory.inDbExp(EipTMail.MAIL_ID_PK_COLUMN, msgIndexes); Expression exp2 = ExpressionFactory.matchExp(EipTMail.USER_ID_PROPERTY, Integer .valueOf(user_id)); List<EipTMail> mail_list = query.andQualifier(exp1).andQualifier(exp2).fetchList(); if (mail_list == null || mail_list.size() == 0) { logger.debug("[ALFileLocalFolder] Not found ID..."); throw new ALPageNotFoundException(); } for (EipTMail record : mail_list) { record.setReadFlg("F"); } Database.commit(); } catch (Throwable t) { Database.rollback(); logger.error("ALFileLocalFolder.unreadMails", t); return false; } return true; } }