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