001: package org.claros.intouch.webmail.controllers;
002:
003: import java.io.ByteArrayInputStream;
004: import java.io.ByteArrayOutputStream;
005: import java.io.ObjectOutputStream;
006: import java.sql.SQLException;
007: import java.util.Properties;
008:
009: import javax.mail.Folder;
010: import javax.mail.Message;
011: import javax.mail.Session;
012: import javax.mail.internet.MimeMessage;
013:
014: import org.apache.commons.dbutils.QueryRunner;
015: import org.apache.commons.logging.Log;
016: import org.apache.commons.logging.LogFactory;
017: import org.claros.commons.auth.models.AuthProfile;
018: import org.claros.commons.db.DbConfigList;
019: import org.claros.commons.exception.NoPermissionException;
020: import org.claros.commons.exception.SystemException;
021: import org.claros.commons.mail.exception.MailboxActionException;
022: import org.claros.commons.mail.models.ConnectionMetaHandler;
023: import org.claros.commons.mail.models.ConnectionProfile;
024: import org.claros.commons.mail.models.Email;
025: import org.claros.commons.mail.parser.MessageParser;
026: import org.claros.commons.mail.protocols.Protocol;
027: import org.claros.commons.mail.protocols.ProtocolFactory;
028: import org.claros.intouch.common.utility.Constants;
029: import org.claros.intouch.common.utility.Utility;
030: import org.claros.intouch.webmail.factory.FolderControllerFactory;
031: import org.claros.intouch.webmail.models.FolderDbObject;
032: import org.claros.intouch.webmail.models.MsgDbObject;
033:
034: import com.jenkov.mrpersister.impl.mapping.AutoGeneratedColumnsMapper;
035: import com.jenkov.mrpersister.itf.IGenericDao;
036: import com.jenkov.mrpersister.itf.mapping.IObjectMappingKey;
037: import com.jenkov.mrpersister.util.JdbcUtil;
038:
039: /**
040: * @author Umut Gokbayrak
041: */
042: public class DbMailControllerImpl implements MailController {
043: private static Log log = LogFactory
044: .getLog(DbMailControllerImpl.class);
045: private AuthProfile auth;
046: private ConnectionProfile profile;
047: private ConnectionMetaHandler handler;
048: private String folder;
049:
050: @SuppressWarnings("unused")
051: private DbMailControllerImpl() {
052: super ();
053: }
054:
055: public DbMailControllerImpl(AuthProfile auth,
056: ConnectionProfile profile, ConnectionMetaHandler handler,
057: String folder) {
058: this .auth = auth;
059: this .profile = profile;
060: this .handler = handler;
061: this .folder = folder;
062: }
063:
064: /* (non-Javadoc)
065: * @see org.claros.groupware.webmail.controllers.MailController#getEmailById(java.lang.Long)
066: */
067: public Email getEmailById(Long emailId) throws Exception {
068: Email email = null;
069: MimeMessage msg = null;
070:
071: FolderControllerFactory fact = new FolderControllerFactory(
072: auth, profile, handler);
073: FolderController cont = fact.getFolderController();
074: FolderDbObject foldObj = cont.getInboxFolder();
075: if (foldObj.getId().toString().equals(folder)) {
076: // it is the INBOX
077: ProtocolFactory pFact = new ProtocolFactory(profile, auth,
078: handler);
079: Protocol prot = pFact.getPop3();
080: msg = (MimeMessage) prot.getMessage(emailId.intValue());
081: try {
082: email = MessageParser.parseMessage(msg);
083: email.setMsgId(emailId);
084: } catch (Exception e) {
085: log
086: .error(
087: "Message could not be parsed to an email object",
088: e);
089: throw new MailboxActionException(e);
090: }
091: if (email != null) {
092: email.setMsgId(emailId);
093: }
094: } else {
095: // it is fetched from the db
096: MsgDbObject item = getEmailDbItemById(emailId);
097:
098: Properties props = new Properties();
099: Session session = Session.getDefaultInstance(props);
100: ByteArrayInputStream bis = new ByteArrayInputStream(item
101: .getEmail());
102: msg = new MimeMessage(session, bis);
103: try {
104: email = MessageParser.parseMessage(msg);
105: email.setMsgId(item.getId());
106: } catch (Exception e) {
107: log
108: .error(
109: "Message could not be parsed to an email object",
110: e);
111: throw new MailboxActionException(e);
112: } finally {
113: bis.close();
114: }
115: if (email != null) {
116: email.setMsgId(item.getId());
117: }
118: }
119: return email;
120: }
121:
122: /**
123: *
124: * @param auth
125: * @param emailId
126: * @return
127: * @throws Exception
128: */
129: private MsgDbObject getEmailDbItemById(Long emailId)
130: throws Exception {
131: MsgDbObject email = null;
132: IGenericDao dao = null;
133: try {
134: dao = Utility.getDbConnection();
135: String username = auth.getUsername();
136:
137: String sql = "SELECT * FROM MSG_DB_OBJECTS WHERE USERNAME=? AND ID = ?";
138: email = (MsgDbObject) dao.read(MsgDbObject.class, sql,
139: new Object[] { username, emailId });
140: } finally {
141: JdbcUtil.close(dao);
142: dao = null;
143: }
144: return email;
145: }
146:
147: /* (non-Javadoc)
148: * @see org.claros.groupware.webmail.controllers.MailController#deleteEmail(java.lang.Long)
149: */
150: public void deleteEmail(Long emailId) throws Exception {
151: FolderControllerFactory fact = new FolderControllerFactory(
152: auth, profile, handler);
153: FolderController cont = fact.getFolderController();
154: FolderDbObject foldObj = cont.getInboxFolder();
155: if (foldObj.getId().toString().equals(folder)) {
156: // it is the INBOX
157: ProtocolFactory pFact = new ProtocolFactory(profile, auth,
158: handler);
159: Protocol prot = pFact.getPop3();
160: prot.deleteMessages(new int[] { emailId.intValue() });
161: } else {
162: // it is DB
163: MsgDbObject tmp = getEmailDbItemById(emailId);
164: if (tmp != null) {
165: String user = tmp.getUsername();
166: if (!auth.getUsername().equals(user)) {
167: throw new NoPermissionException();
168: }
169:
170: IGenericDao dao = null;
171: try {
172: dao = Utility.getDbConnection();
173: dao.deleteByPrimaryKey(MsgDbObject.class, emailId);
174: } catch (Exception e) {
175: // do nothing sier
176: } finally {
177: JdbcUtil.close(dao);
178: dao = null;
179: }
180: }
181: }
182: }
183:
184: /* (non-Javadoc)
185: * @see org.claros.groupware.webmail.controllers.MailController#moveEmail(java.lang.Long, java.lang.String)
186: */
187: public void moveEmail(Long msgId, String destFolder)
188: throws Exception {
189: FolderControllerFactory fact = new FolderControllerFactory(
190: auth, profile, handler);
191: FolderController cont = fact.getFolderController();
192: FolderDbObject foldObj = cont.getInboxFolder();
193:
194: // message can not be moved to the INBOX
195: if (foldObj.getId().toString().equals(destFolder)) {
196: throw new SystemException();
197: }
198:
199: if (foldObj.getId().toString().equals(folder)) {
200: // it is the INBOX
201: ProtocolFactory pFact = new ProtocolFactory(profile, auth,
202: handler);
203: Protocol prot = pFact.getPop3();
204: Message msg = prot.getMessage(msgId.intValue());
205:
206: try {
207: if (!msg.getFolder().isOpen()) {
208: msg.getFolder().open(Folder.READ_WRITE);
209: }
210: // create a byte array from the message content.
211: ByteArrayOutputStream bos = new ByteArrayOutputStream();
212: msg.writeTo(bos);
213: byte bMsg[] = bos.toByteArray();
214: bos.close();
215:
216: // serialize the message byte array
217: ObjectOutputStream os = new ObjectOutputStream(bos);
218: os.writeObject(bMsg);
219:
220: // create an email db item
221: MsgDbObject item = new MsgDbObject();
222: item.setEmail(bos.toByteArray());
223: item.setUniqueId(null);
224: item.setFolderId(new Long(destFolder));
225: item.setUnread(new Boolean(true));
226: item.setUsername(auth.getUsername());
227: item.setMsgSize(new Long(bMsg.length));
228:
229: // save the email db item.
230: appendEmail(item);
231: prot.deleteMessages(new int[] { msgId.intValue() });
232: } catch (Exception e) {
233: e.printStackTrace();
234: }
235: } else {
236: // it is db - db move
237: MsgDbObject item = getEmailDbItemById(msgId);
238: Long destId = new Long(destFolder);
239: item.setFolderId(destId);
240: updateEmail(item);
241: }
242: }
243:
244: /**
245: *
246: * @param item
247: * @throws Exception
248: */
249: private void updateEmail(MsgDbObject item) throws Exception {
250: MsgDbObject tmp = getEmailDbItemById(item.getId());
251: String user = tmp.getUsername();
252: if (!auth.getUsername().equals(user)) {
253: throw new NoPermissionException();
254: }
255:
256: IGenericDao dao = null;
257: try {
258: dao = Utility.getDbConnection();
259: dao.update(MsgDbObject.class, item);
260: } finally {
261: JdbcUtil.close(dao);
262: dao = null;
263: }
264: }
265:
266: /* (non-Javadoc)
267: * @see org.claros.groupware.webmail.controllers.MailController#appendEmail(org.claros.groupware.webmail.models.EmailDbItem)
268: */
269: @SuppressWarnings("deprecation")
270: public void appendEmail(MsgDbObject item) throws Exception {
271: IGenericDao dao = null;
272: try {
273: dao = Utility.getDbConnection();
274:
275: IObjectMappingKey myObj = Constants.persistMan
276: .getObjectMappingFactory().createInstance(
277: MsgDbObject.class,
278: new AutoGeneratedColumnsMapper(true));
279: dao.insert(myObj, item);
280: } finally {
281: JdbcUtil.close(dao);
282: dao = null;
283: }
284: }
285:
286: /* (non-Javadoc)
287: * @see org.claros.groupware.webmail.controllers.MailController#markAsRead(java.lang.Long)
288: */
289: public void markAsRead(Long msgId) throws Exception {
290: FolderControllerFactory fact = new FolderControllerFactory(
291: auth, profile, handler);
292: FolderController cont = fact.getFolderController();
293: FolderDbObject foldObj = cont.getInboxFolder();
294: if (foldObj.getId().toString().equals(folder)) {
295: // it is the INBOX
296: // do nothing
297: } else {
298: QueryRunner run = new QueryRunner(DbConfigList
299: .getDataSourceById("file"));
300: String username = auth.getUsername();
301: try {
302: String sql = "UPDATE MSG_DB_OBJECTS SET UNREAD = ? WHERE USERNAME=? AND ID=?";
303: run.update(sql, new Object[] { new Integer(0),
304: username, msgId });
305: } catch (SQLException e) {
306: throw e;
307: }
308: }
309: }
310:
311: /**
312: *
313: * @param auth
314: * @param md5Header
315: * @return
316: * @throws Exception
317: */
318: public boolean mailAlreadyFetched(String md5Header)
319: throws Exception {
320: IGenericDao dao = null;
321: boolean result = false;
322: try {
323: dao = Utility.getDbConnection();
324: String username = auth.getUsername();
325:
326: String sql = "SELECT * FROM MSG_DB_OBJECTS WHERE USERNAME=? AND UNIQUE_ID = ?";
327: MsgDbObject email = (MsgDbObject) dao.read(
328: MsgDbObject.class, sql, new Object[] { username,
329: md5Header });
330: if (email != null) {
331: result = true;
332: }
333: } finally {
334: JdbcUtil.close(dao);
335: dao = null;
336: }
337: return result;
338: }
339:
340: /* (non-Javadoc)
341: * @see org.claros.groupware.webmail.controllers.MailController#deleteEmails(int)
342: */
343: public void deleteEmails(int msgs[]) throws Exception {
344: FolderControllerFactory fact = new FolderControllerFactory(
345: auth, profile, handler);
346: FolderController cont = fact.getFolderController();
347: FolderDbObject foldObj = cont.getInboxFolder();
348: if (foldObj.getId().toString().equals(folder)) {
349: // it is the INBOX
350: ProtocolFactory pFact = new ProtocolFactory(profile, auth,
351: handler);
352: Protocol prot = pFact.getPop3();
353: prot.deleteMessages(msgs);
354: } else {
355: for (int i = 0; i < msgs.length; i++) {
356: deleteEmail(new Long(msgs[i]));
357: }
358: }
359: }
360:
361: /**
362: *
363: */
364: public void moveEmails(int[] msgs, String destFolder)
365: throws Exception {
366: FolderControllerFactory fact = new FolderControllerFactory(
367: auth, profile, handler);
368: FolderController cont = fact.getFolderController();
369: FolderDbObject foldObj = cont.getInboxFolder();
370:
371: // message can not be moved to the INBOX
372: if (foldObj.getId().toString().equals(destFolder)) {
373: throw new SystemException();
374: }
375:
376: if (foldObj.getId().toString().equals(folder)) {
377: // it is the INBOX
378: ProtocolFactory pFact = new ProtocolFactory(profile, auth,
379: handler);
380: Protocol prot = pFact.getPop3();
381: for (int i = 0; i < msgs.length; i++) {
382: Message msg = prot.getMessage(msgs[i]);
383:
384: try {
385: if (!msg.getFolder().isOpen()) {
386: msg.getFolder().open(Folder.READ_WRITE);
387: }
388: // create a byte array from the message content.
389: ByteArrayOutputStream bos = new ByteArrayOutputStream();
390: msg.writeTo(bos);
391: byte bMsg[] = bos.toByteArray();
392: bos.close();
393:
394: // serialize the message byte array
395: ObjectOutputStream os = new ObjectOutputStream(bos);
396: os.writeObject(bMsg);
397:
398: // create an email db item
399: MsgDbObject item = new MsgDbObject();
400: item.setEmail(bos.toByteArray());
401: item.setUniqueId("");
402: item.setFolderId(new Long(destFolder));
403: item.setUnread(new Boolean(true));
404: item.setUsername(auth.getUsername());
405: item.setMsgSize(new Long(bMsg.length));
406:
407: // save the email db item.
408: appendEmail(item);
409: } catch (Exception e) {
410: e.printStackTrace();
411: }
412: }
413:
414: prot.deleteMessages(msgs);
415:
416: } else {
417: MsgDbObject tmp = null;
418: if (msgs != null) {
419: for (int i = 0; i < msgs.length; i++) {
420: tmp = getEmailDbItemById(new Long(msgs[i]));
421: Long destId = new Long(destFolder);
422: tmp.setFolderId(destId);
423: updateEmail(tmp);
424: }
425: }
426: }
427: }
428:
429: /**
430: *
431: */
432: public void markAsDeleted(int[] ids) throws Exception {
433: deleteEmails(ids);
434: }
435: }
|