0001: /*
0002: Copyright (C) 2004 Know Gate S.L. All rights reserved.
0003: C/Oņa, 107 1š2 28050 Madrid (Spain)
0004:
0005: Redistribution and use in source and binary forms, with or without
0006: modification, are permitted provided that the following conditions
0007: are met:
0008:
0009: 1. Redistributions of source code must retain the above copyright
0010: notice, this list of conditions and the following disclaimer.
0011:
0012: 2. The end-user documentation included with the redistribution,
0013: if any, must include the following acknowledgment:
0014: "This product includes software parts from hipergate
0015: (http://www.hipergate.org/)."
0016: Alternately, this acknowledgment may appear in the software itself,
0017: if and wherever such third-party acknowledgments normally appear.
0018:
0019: 3. The name hipergate must not be used to endorse or promote products
0020: derived from this software without prior written permission.
0021: Products derived from this software may not be called hipergate,
0022: nor may hipergate appear in their name, without prior written
0023: permission.
0024:
0025: This library is distributed in the hope that it will be useful,
0026: but WITHOUT ANY WARRANTY; without even the implied warranty of
0027: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
0028:
0029: You should have received a copy of hipergate License with this code;
0030: if not, visit http://www.hipergate.org or mail to info@hipergate.org
0031: */
0032:
0033: package com.knowgate.hipermail;
0034:
0035: import java.sql.SQLException;
0036: import java.sql.PreparedStatement;
0037: import java.sql.ResultSet;
0038: import java.sql.ResultSetMetaData;
0039: import java.sql.Timestamp;
0040: import java.sql.Blob;
0041: import java.sql.Types;
0042: import java.sql.Statement;
0043: import java.sql.CallableStatement;
0044:
0045: import java.math.BigDecimal;
0046:
0047: import java.io.UnsupportedEncodingException;
0048: import java.io.ByteArrayInputStream;
0049: import java.io.ByteArrayOutputStream;
0050: import java.io.IOException;
0051: import java.io.File;
0052: import java.io.BufferedOutputStream;
0053: import java.io.FileOutputStream;
0054: import java.io.FileNotFoundException;
0055: import java.io.InputStream;
0056:
0057: import javax.mail.Session;
0058: import javax.mail.Folder;
0059: import javax.mail.UIDFolder;
0060: import javax.mail.Store;
0061: import javax.mail.Message;
0062: import javax.mail.MessagingException;
0063: import javax.mail.StoreClosedException;
0064: import javax.mail.FolderClosedException;
0065: import javax.mail.MessagingException;
0066: import javax.mail.FetchProfile;
0067: import javax.mail.Flags;
0068: import javax.mail.Multipart;
0069: import javax.mail.URLName;
0070: import javax.mail.BodyPart;
0071: import javax.mail.Address;
0072: import javax.mail.Flags;
0073: import javax.mail.Session;
0074:
0075: import javax.mail.internet.AddressException;
0076: import javax.mail.internet.InternetAddress;
0077: import javax.mail.internet.MimeMessage;
0078: import javax.mail.internet.MimeBodyPart;
0079: import javax.mail.internet.InternetAddress;
0080: import javax.mail.internet.ParseException;
0081: import javax.mail.internet.MimeMultipart;
0082: import javax.mail.internet.MimePart;
0083: import javax.mail.internet.MimeUtility;
0084:
0085: import java.util.Properties;
0086: import java.util.NoSuchElementException;
0087:
0088: import com.sun.mail.util.BASE64DecoderStream;
0089:
0090: import com.knowgate.jdc.JDCConnection;
0091: import com.knowgate.debug.DebugFile;
0092: import com.knowgate.dfs.FileSystem;
0093: import com.knowgate.dataobjs.DB;
0094: import com.knowgate.dataobjs.DBTable;
0095: import com.knowgate.dataobjs.DBBind;
0096: import com.knowgate.dataobjs.DBSubset;
0097: import com.knowgate.dataobjs.DBPersist;
0098: import com.knowgate.dataobjs.DBSubset;
0099: import com.knowgate.dataobjs.DBKeySet;
0100: import com.knowgate.hipergate.Category;
0101: import com.knowgate.misc.Gadgets;
0102: import com.knowgate.misc.MD5;
0103: import com.knowgate.hipergate.Product;
0104: import com.knowgate.hipergate.ProductLocation;
0105:
0106: /**
0107: * <p>A subclass of javax.mail.Folder providing storage for MimeMessages at database
0108: * LONGVARBINARY columns and MBOX files.</p>
0109: * Folders are also a subclass of com.knowgate.hipergate.Category<br>
0110: * Category behaviour is obtained by delegation to a private Category instance.<br>
0111: * For each DBFolder there is a corresponding row at k_categories database table.
0112: * @author Sergio Montoro Ten
0113: * @version 3.0
0114: */
0115:
0116: public class DBFolder extends Folder {
0117:
0118: // Store Messages using an MBOX file
0119: public static final int MODE_MBOX = 64;
0120:
0121: // Store Messages using database BLOB columns
0122: public static final int MODE_BLOB = 128;
0123:
0124: private int iOpenMode;
0125:
0126: private Category oCatg;
0127:
0128: private JDCConnection oConn;
0129:
0130: private String sFolderDir, sFolderName;
0131:
0132: // ---------------------------------------------------------------------------
0133:
0134: protected DBFolder(Store oStor, String sName) {
0135: super (oStor);
0136: oCatg = new Category();
0137: iOpenMode = 0;
0138: sFolderName = sName;
0139: }
0140:
0141: // ---------------------------------------------------------------------------
0142:
0143: protected JDCConnection getConnection() {
0144: return ((DBStore) getStore()).getConnection();
0145: }
0146:
0147: // ---------------------------------------------------------------------------
0148:
0149: /**
0150: * Get instance of com.knowgate.hipergate.Category object
0151: */
0152: public Category getCategory() {
0153: return oCatg;
0154: }
0155:
0156: // ---------------------------------------------------------------------------
0157:
0158: /**
0159: * <p>Get Category GUID</p>
0160: * Each folder has a Global Unique Identifier which is stored at column
0161: * gu_category of table k_categories
0162: * @return String Category GUID or <b>null</b> if category is not set
0163: */
0164: public String getCategoryGuid() {
0165: if (null == oCatg)
0166: return null;
0167: else
0168: return oCatg.getStringNull(DB.gu_category, null);
0169: }
0170:
0171: // ---------------------------------------------------------------------------
0172:
0173: /**
0174: * <p>Get set of identifiers for messages at this folder</p>
0175: * Set entries are the mime identifiers for each message
0176: * @return DBKeySet
0177: * @throws SQLException
0178: */
0179: public DBKeySet keySet() throws SQLException {
0180: if (DebugFile.trace) {
0181: DebugFile.writeln("Begin DBFolder.keySet()");
0182: DebugFile.incIdent();
0183: }
0184: DBKeySet oKeySet = new DBKeySet(DB.k_mime_msgs, DB.id_message,
0185: DB.id_message + " IS NOT NULL AND " + DB.gu_category
0186: + "=? AND " + DB.bo_deleted + "<>1 AND "
0187: + DB.gu_parent_msg + " IS NULL", 0);
0188: oKeySet.load(getConnection(), new Object[] { oCatg
0189: .getString(DB.gu_category) });
0190: if (DebugFile.trace) {
0191: DebugFile.decIdent();
0192: DebugFile.writeln("End DBFolder.keySet() : "
0193: + String.valueOf(oKeySet.size()));
0194: }
0195: return oKeySet;
0196: } // keySet
0197:
0198: // ---------------------------------------------------------------------------
0199:
0200: /**
0201: * Append messages to this DBFolder
0202: * @param msgs Array of mime messages to be appended
0203: * @throws MessagingException
0204: * @throws ArrayIndexOutOfBoundsException
0205: */
0206: public void appendMessages(Message[] msgs)
0207: throws MessagingException, ArrayIndexOutOfBoundsException {
0208:
0209: for (int m = 0; m < msgs.length; m++)
0210: appendMessage((MimeMessage) msgs[m]);
0211: }
0212:
0213: // ---------------------------------------------------------------------------
0214:
0215: /**
0216: * Copy a DBMimeMessage from another DBFolder to this DBFolder
0217: * @param oSrcMsg Source message.
0218: * @return GUID of new message
0219: * @throws MessagingException
0220: */
0221: public String copyMessage(DBMimeMessage oSrcMsg)
0222: throws MessagingException {
0223:
0224: if (DebugFile.trace) {
0225: DebugFile.writeln("Begin DBFolder.copyMessage()");
0226: DebugFile.incIdent();
0227: }
0228:
0229: BigDecimal oPg = null;
0230: BigDecimal oPos = null;
0231: int iLen = 0;
0232: String sId = null;
0233: try {
0234: String sSQL = "SELECT " + DB.pg_message + ","
0235: + DB.id_message + "," + DB.nu_position + ","
0236: + DB.len_mimemsg + " FROM " + DB.k_mime_msgs
0237: + " WHERE " + DB.gu_mimemsg + "=";
0238: if (DebugFile.trace)
0239: DebugFile.writeln("Connection.prepareStatement(" + sSQL
0240: + "'" + oSrcMsg.getMessageGuid() + "')");
0241:
0242: PreparedStatement oStmt = getConnection().prepareStatement(
0243: sSQL + "?", ResultSet.TYPE_FORWARD_ONLY,
0244: ResultSet.CONCUR_READ_ONLY);
0245: oStmt.setString(1, oSrcMsg.getMessageGuid());
0246: ResultSet oRSet = oStmt.executeQuery();
0247: if (!oRSet.next())
0248: throw new MessagingException(
0249: "DBFolder.copyMessage() could not find source message "
0250: + oSrcMsg.getMessageGuid());
0251: oPg = oRSet.getBigDecimal(1);
0252: sId = oRSet.getString(2);
0253: oPos = oRSet.getBigDecimal(3);
0254: iLen = oRSet.getInt(4);
0255: oRSet.close();
0256: oStmt.close();
0257: } catch (SQLException sqle) {
0258: try {
0259: getConnection().rollback();
0260: } catch (Exception ignore) {
0261: }
0262: if (DebugFile.trace) {
0263: DebugFile
0264: .writeln("DBFolder.copyMessage() SQLException "
0265: + sqle.getMessage());
0266: DebugFile.decIdent();
0267: }
0268: throw new MessagingException(
0269: "DBFolder.copyMessage() SQLException "
0270: + sqle.getMessage(), sqle);
0271: }
0272:
0273: if (null == oPg)
0274: throw new MessagingException(
0275: "DBFolder.copyMessage() Source Message not found");
0276:
0277: DBFolder oSrcFldr = (DBFolder) oSrcMsg.getFolder();
0278:
0279: MboxFile oMboxSrc = null;
0280: MimeMessage oMimeSrc;
0281: String sNewGuid = null;
0282: try {
0283: if ((oSrcFldr.mode & MODE_MBOX) != 0) {
0284: oMboxSrc = new MboxFile(oSrcFldr.getFile(),
0285: MboxFile.READ_ONLY);
0286: InputStream oInStrm = oMboxSrc.getMessageAsStream(oPos
0287: .longValue(), iLen);
0288: oMimeSrc = new MimeMessage(Session
0289: .getDefaultInstance(new Properties()), oInStrm);
0290: oInStrm.close();
0291: oMboxSrc.close();
0292: oMboxSrc = null;
0293:
0294: String sId2 = oMimeSrc.getMessageID();
0295: if ((sId != null) && (sId2 != null)) {
0296: if (!sId.trim().equals(sId2.trim())) {
0297: throw new MessagingException(
0298: "MessageID "
0299: + sId
0300: + " at database does not match MessageID "
0301: + oMimeSrc.getMessageID()
0302: + " at MBOX file "
0303: + oSrcFldr.getFile().getName()
0304: + " for message index "
0305: + oPg.toString());
0306: }
0307: } // fi (sId!=null && sId2!=null)
0308:
0309: appendMessage(oMimeSrc);
0310: } else {
0311: ByteArrayOutputStream oByOutStrm = new ByteArrayOutputStream();
0312: oSrcMsg.writeTo(oByOutStrm);
0313: ByteArrayInputStream oByInStrm = new ByteArrayInputStream(
0314: oByOutStrm.toByteArray());
0315: oByOutStrm.close();
0316: oMimeSrc = new MimeMessage(Session
0317: .getDefaultInstance(new Properties()),
0318: oByInStrm);
0319: oByInStrm.close();
0320: appendMessage(oMimeSrc);
0321: }
0322: } catch (Exception e) {
0323: if (oMboxSrc != null) {
0324: try {
0325: oMboxSrc.close();
0326: } catch (Exception ignore) {
0327: }
0328: }
0329: try {
0330: oSrcFldr.getConnection().rollback();
0331: } catch (Exception ignore) {
0332: }
0333: if (DebugFile.trace) {
0334: DebugFile.writeln("DBFolder.copyMessage() "
0335: + e.getClass().getName() + e.getMessage());
0336: DebugFile.decIdent();
0337: }
0338: throw new MessagingException(e.getMessage(), e);
0339: }
0340:
0341: if (DebugFile.trace) {
0342: DebugFile.decIdent();
0343: DebugFile.writeln("End DBFolder.copyMessage() : "
0344: + sNewGuid);
0345: }
0346:
0347: return sNewGuid;
0348: } // copyMessage
0349:
0350: // ---------------------------------------------------------------------------
0351:
0352: /**
0353: * Move a DBMimeMessage from another DBFolder to this DBFolder
0354: * @param oSrcMsg Source message
0355: * @throws MessagingException
0356: */
0357: public void moveMessage(DBMimeMessage oSrcMsg)
0358: throws MessagingException {
0359:
0360: if (DebugFile.trace) {
0361: DebugFile
0362: .writeln("Begin DBFolder.moveMessage([DBMimeMessage])");
0363: DebugFile.incIdent();
0364: }
0365:
0366: PreparedStatement oStmt = null;
0367: ResultSet oRSet = null;
0368: BigDecimal oPg = null;
0369: BigDecimal oPos = null;
0370: int iLen = 0;
0371: boolean bNullLen = true;
0372:
0373: boolean bWasOpen = isOpen();
0374: if (!bWasOpen)
0375: open(Folder.READ_WRITE);
0376:
0377: try {
0378: oConn = getConnection();
0379: if (DebugFile.trace)
0380: DebugFile.writeln("Connection.prepareStatement(SELECT "
0381: + DB.pg_message + "," + DB.nu_position + ","
0382: + DB.len_mimemsg + " FROM " + DB.k_mime_msgs
0383: + " WHERE " + DB.gu_mimemsg + "='"
0384: + oSrcMsg.getMessageGuid() + "')");
0385: oStmt = oConn.prepareStatement("SELECT " + DB.pg_message
0386: + "," + DB.nu_position + "," + DB.len_mimemsg
0387: + " FROM " + DB.k_mime_msgs + " WHERE "
0388: + DB.gu_mimemsg + "=?");
0389: oStmt.setString(1, oSrcMsg.getMessageGuid());
0390: oRSet = oStmt.executeQuery();
0391: if (oRSet.next()) {
0392: oPg = oRSet.getBigDecimal(1);
0393: oPos = oRSet.getBigDecimal(2);
0394: iLen = oRSet.getInt(3);
0395: bNullLen = oRSet.wasNull();
0396: }
0397: oRSet.close();
0398: oRSet = null;
0399: oStmt.close();
0400: oStmt = null;
0401:
0402: if (DebugFile.trace) {
0403: if (oPg != null)
0404: DebugFile.writeln("message number is "
0405: + oPg.toString());
0406: else
0407: DebugFile.writeln("message number is null");
0408: if (oPos != null)
0409: DebugFile.writeln("message position is "
0410: + oPos.toString());
0411: else
0412: DebugFile.writeln("message position is null");
0413: if (!bNullLen)
0414: DebugFile.writeln("message length is "
0415: + String.valueOf(iLen));
0416: else
0417: DebugFile.writeln("message length is null");
0418: }
0419:
0420: oConn.setAutoCommit(false);
0421:
0422: String sSrcCatg = null;
0423: if (DebugFile.trace) {
0424: DBFolder oSrcFldr = (DBFolder) oSrcMsg.getFolder();
0425: if (null == oSrcFldr)
0426: DebugFile.writeln("Source message folder is null");
0427: else {
0428: Category oSrcCatg = oSrcFldr.getCategory();
0429: if (null == oSrcCatg)
0430: DebugFile
0431: .writeln("Source message category is null");
0432: else {
0433: sSrcCatg = oSrcCatg.getStringNull(
0434: DB.gu_category, null);
0435: }
0436: }
0437: if (null == sSrcCatg) {
0438: DebugFile.decIdent();
0439: throw new MessagingException(
0440: "Could not find folder for source message");
0441: }
0442: if (DebugFile.trace)
0443: DebugFile
0444: .writeln("Connection.prepareStatement(UPDATE "
0445: + DB.k_categories
0446: + " SET "
0447: + DB.len_size
0448: + "="
0449: + DB.len_size
0450: + "-"
0451: + String.valueOf(iLen)
0452: + " WHERE "
0453: + DB.gu_category
0454: + "='"
0455: + sSrcCatg + "')");
0456: }
0457: sSrcCatg = ((DBFolder) (oSrcMsg.getFolder())).getCategory()
0458: .getString(DB.gu_category);
0459: oStmt = oConn.prepareStatement("UPDATE " + DB.k_categories
0460: + " SET " + DB.len_size + "=" + DB.len_size + "-"
0461: + String.valueOf(iLen) + " WHERE " + DB.gu_category
0462: + "=?");
0463: oStmt.setString(1, sSrcCatg);
0464: oStmt.executeUpdate();
0465: oStmt.close();
0466: oStmt = null;
0467: if (DebugFile.trace)
0468: DebugFile.writeln("Connection.prepareStatement(UPDATE "
0469: + DB.k_categories
0470: + " SET "
0471: + DB.len_size
0472: + "="
0473: + DB.len_size
0474: + "-"
0475: + String.valueOf(iLen)
0476: + " WHERE "
0477: + DB.gu_category
0478: + "='"
0479: + getCategory().getStringNull(DB.gu_category,
0480: "null") + "')");
0481: oStmt = oConn.prepareStatement("UPDATE " + DB.k_categories
0482: + " SET " + DB.len_size + "=" + DB.len_size + "+"
0483: + String.valueOf(iLen) + " WHERE " + DB.gu_category
0484: + "=?");
0485: oStmt.setString(1, getCategory().getString(DB.gu_category));
0486: oStmt.executeUpdate();
0487: oStmt.close();
0488: oStmt = null;
0489: oConn.commit();
0490: } catch (SQLException sqle) {
0491: if (null != oRSet) {
0492: try {
0493: oRSet.close();
0494: } catch (Exception ignore) {
0495: }
0496: }
0497: if (null != oStmt) {
0498: try {
0499: oStmt.close();
0500: } catch (Exception ignore) {
0501: }
0502: }
0503: if (null != oConn) {
0504: try {
0505: oConn.rollback();
0506: } catch (Exception ignore) {
0507: }
0508: }
0509: if (!bWasOpen) {
0510: try {
0511: close(false);
0512: } catch (Exception ignore) {
0513: }
0514: }
0515: throw new MessagingException(sqle.getMessage(), sqle);
0516: }
0517:
0518: if (null == oPg) {
0519: if (!bWasOpen) {
0520: try {
0521: close(false);
0522: } catch (Exception ignore) {
0523: }
0524: }
0525: throw new MessagingException("Source message "
0526: + oSrcMsg.getMessageGuid() + " not found");
0527: }
0528:
0529: // If position is null then message is only at the database and not also at
0530: // an MBOX file so skip moving from one MBOX file to another
0531: if (null != oPos) {
0532:
0533: DBFolder oSrcFldr = (DBFolder) oSrcMsg.getFolder();
0534:
0535: MboxFile oMboxSrc = null, oMboxThis = null;
0536: try {
0537: oMboxSrc = new MboxFile(oSrcFldr.getFile(),
0538: MboxFile.READ_WRITE);
0539: oMboxThis = new MboxFile(oSrcFldr.getFile(),
0540: MboxFile.READ_WRITE);
0541:
0542: oMboxThis.appendMessage(oMboxSrc, oPos.longValue(),
0543: iLen);
0544: oMboxThis.close();
0545: oMboxThis = null;
0546:
0547: oMboxSrc.purge(new int[] { oPg.intValue() });
0548:
0549: oMboxSrc.close();
0550: oMboxSrc = null;
0551: } catch (Exception e) {
0552: if (oMboxThis != null) {
0553: try {
0554: oMboxThis.close();
0555: } catch (Exception ignore) {
0556: }
0557: }
0558: if (oMboxSrc != null) {
0559: try {
0560: oMboxSrc.close();
0561: } catch (Exception ignore) {
0562: }
0563: }
0564: if (!bWasOpen) {
0565: try {
0566: close(false);
0567: } catch (Exception ignore) {
0568: }
0569: }
0570: throw new MessagingException(e.getMessage(), e);
0571: }
0572: } // fi (oPos)
0573:
0574: try {
0575: oConn = getConnection();
0576: String sCatGuid = getCategory().getString(DB.gu_category);
0577: BigDecimal dNext = getNextMessage();
0578: oStmt = oConn.prepareStatement("UPDATE " + DB.k_mime_msgs
0579: + " SET " + DB.gu_category + "=?," + DB.pg_message
0580: + "=? WHERE " + DB.gu_mimemsg + "=?");
0581: oStmt.setString(1, sCatGuid);
0582: oStmt.setBigDecimal(2, dNext);
0583: oStmt.setString(3, oSrcMsg.getMessageGuid());
0584: oStmt.executeUpdate();
0585: oStmt.close();
0586: oStmt = null;
0587: oConn.commit();
0588: } catch (SQLException sqle) {
0589: if (null != oStmt) {
0590: try {
0591: oStmt.close();
0592: } catch (Exception ignore) {
0593: }
0594: }
0595: if (null != oConn) {
0596: try {
0597: oConn.rollback();
0598: } catch (Exception ignore) {
0599: }
0600: }
0601: if (!bWasOpen) {
0602: try {
0603: close(false);
0604: } catch (Exception ignore) {
0605: }
0606: }
0607: throw new MessagingException(sqle.getMessage(), sqle);
0608: }
0609:
0610: if (!bWasOpen)
0611: close(false);
0612:
0613: if (DebugFile.trace) {
0614: DebugFile.decIdent();
0615: DebugFile.writeln("End DBFolder.moveMessage()");
0616: }
0617: } // moveMessage
0618:
0619: // ---------------------------------------------------------------------------
0620:
0621: /**
0622: * This method is not implemented and will always raise UnsupportedOperationException
0623: * @throws UnsupportedOperationException
0624: */
0625: public boolean create(int type) throws MessagingException {
0626: throw new UnsupportedOperationException("DBFolder.create()");
0627: }
0628:
0629: // ---------------------------------------------------------------------------
0630:
0631: /**
0632: * Create DBFolder with given name under current user mailroot Category
0633: * @param sFolderName Folder Name
0634: * @return <b>true</b>
0635: * @throws MessagingException
0636: */
0637: public boolean create(String sFolderName) throws MessagingException {
0638:
0639: try {
0640: String sGuid = ((DBStore) getStore()).getUser()
0641: .getMailFolder(
0642: getConnection(),
0643: Category.makeName(getConnection(),
0644: sFolderName));
0645: oCatg = new Category(getConnection(), sGuid);
0646: } catch (SQLException sqle) {
0647: throw new MessagingException(sqle.getMessage(), sqle);
0648: }
0649: return true;
0650: }
0651:
0652: // ---------------------------------------------------------------------------
0653:
0654: /**
0655: * Open this DBFolder
0656: * @param mode {READ_ONLY|READ_WRITE}
0657: * @throws MessagingException
0658: */
0659: public void open(int mode) throws MessagingException {
0660: final int ALL_OPTIONS = READ_ONLY | READ_WRITE | MODE_MBOX
0661: | MODE_BLOB;
0662:
0663: if (DebugFile.trace) {
0664: DebugFile.writeln("DBFolder.open(" + String.valueOf(mode)
0665: + ")");
0666: DebugFile.incIdent();
0667: }
0668:
0669: if ((0 == (mode & READ_ONLY)) && (0 == (mode & READ_WRITE))) {
0670: if (DebugFile.trace)
0671: DebugFile.decIdent();
0672: throw new MessagingException(
0673: "Folder must be opened in either READ_ONLY or READ_WRITE mode");
0674: } else if (ALL_OPTIONS != (mode | ALL_OPTIONS)) {
0675: if (DebugFile.trace)
0676: DebugFile.decIdent();
0677: throw new MessagingException(
0678: "Invalid DBFolder open() option mode");
0679: } else {
0680: if ((0 == (mode & MODE_MBOX)) && (0 == (mode & MODE_BLOB)))
0681: mode |= MODE_MBOX;
0682:
0683: iOpenMode = mode;
0684: oConn = getConnection();
0685:
0686: if ((iOpenMode & MODE_MBOX) != 0) {
0687: String sFolderUrl;
0688: try {
0689: sFolderUrl = Gadgets.chomp(getStore().getURLName()
0690: .getFile(), File.separator)
0691: + oCatg.getPath(oConn);
0692: if (DebugFile.trace)
0693: DebugFile.writeln("mail folder directory is "
0694: + sFolderUrl);
0695: if (sFolderUrl.startsWith("file://"))
0696: sFolderDir = sFolderUrl.substring(7);
0697: else
0698: sFolderDir = sFolderUrl;
0699: } catch (SQLException sqle) {
0700: iOpenMode = 0;
0701: oConn = null;
0702: if (DebugFile.trace)
0703: DebugFile.decIdent();
0704: throw new MessagingException(sqle.getMessage(),
0705: sqle);
0706: }
0707: try {
0708: File oDir = new File(sFolderDir);
0709: if (!oDir.exists()) {
0710: FileSystem oFS = new FileSystem();
0711: oFS.mkdirs(sFolderUrl);
0712: }
0713: } catch (IOException ioe) {
0714: iOpenMode = 0;
0715: oConn = null;
0716: if (DebugFile.trace)
0717: DebugFile.decIdent();
0718: throw new MessagingException(ioe.getMessage(), ioe);
0719: } catch (SecurityException se) {
0720: iOpenMode = 0;
0721: oConn = null;
0722: if (DebugFile.trace)
0723: DebugFile.decIdent();
0724: throw new MessagingException(se.getMessage(), se);
0725: } catch (Exception je) {
0726: iOpenMode = 0;
0727: oConn = null;
0728: if (DebugFile.trace)
0729: DebugFile.decIdent();
0730: throw new MessagingException(je.getMessage(), je);
0731: }
0732:
0733: // Create a ProductLocation pointing to the MBOX file if it does not exist
0734: oConn = getConnection();
0735: PreparedStatement oStmt = null;
0736: ResultSet oRSet = null;
0737: boolean bHasFilePointer;
0738: try {
0739: oStmt = oConn.prepareStatement("SELECT NULL FROM "
0740: + DB.k_x_cat_objs + " WHERE "
0741: + DB.gu_category + "=? AND " + DB.id_class
0742: + "=15", ResultSet.TYPE_FORWARD_ONLY,
0743: ResultSet.CONCUR_READ_ONLY);
0744: oStmt.setString(1, getCategory().getString(
0745: DB.gu_category));
0746: oRSet = oStmt.executeQuery();
0747: bHasFilePointer = oRSet.next();
0748: oRSet.close();
0749: oRSet = null;
0750: oStmt.close();
0751: oStmt = null;
0752:
0753: if (!bHasFilePointer) {
0754: oConn.setAutoCommit(false);
0755:
0756: Product oProd = new Product();
0757: oProd.put(DB.gu_owner, oCatg
0758: .getString(DB.gu_owner));
0759: oProd.put(DB.nm_product, oCatg
0760: .getString(DB.nm_category));
0761: oProd.store(oConn);
0762:
0763: ProductLocation oLoca = new ProductLocation();
0764: oLoca.put(DB.gu_product, oProd
0765: .getString(DB.gu_product));
0766: oLoca.put(DB.gu_owner, oCatg
0767: .getString(DB.gu_owner));
0768: oLoca.put(DB.pg_prod_locat, 1);
0769: oLoca.put(DB.id_cont_type, 1);
0770: oLoca.put(DB.id_prod_type, "MBOX");
0771: oLoca.put(DB.len_file, 0);
0772: oLoca.put(DB.xprotocol, "file://");
0773: oLoca.put(DB.xhost, "localhost");
0774: oLoca.put(DB.xpath, Gadgets.chomp(sFolderDir,
0775: File.separator));
0776: oLoca.put(DB.xfile, oCatg
0777: .getString(DB.nm_category)
0778: + ".mbox");
0779: oLoca.put(DB.xoriginalfile, oCatg
0780: .getString(DB.nm_category)
0781: + ".mbox");
0782: oLoca.store(oConn);
0783:
0784: oStmt = oConn.prepareStatement("INSERT INTO "
0785: + DB.k_x_cat_objs + " ("
0786: + DB.gu_category + "," + DB.gu_object
0787: + "," + DB.id_class
0788: + ") VALUES (?,?,15)");
0789: oStmt.setString(1, oCatg
0790: .getString(DB.gu_category));
0791: oStmt.setString(2, oProd
0792: .getString(DB.gu_product));
0793: oStmt.executeUpdate();
0794: oStmt.close();
0795: oStmt = null;
0796:
0797: oConn.commit();
0798: }
0799: } catch (SQLException sqle) {
0800: if (DebugFile.trace) {
0801: DebugFile.writeln("SQLException "
0802: + sqle.getMessage());
0803: DebugFile.decIdent();
0804: }
0805: if (oStmt != null) {
0806: try {
0807: oStmt.close();
0808: } catch (SQLException ignore) {
0809: }
0810: }
0811: if (oConn != null) {
0812: try {
0813: oConn.rollback();
0814: } catch (SQLException ignore) {
0815: }
0816: }
0817: throw new MessagingException(sqle.getMessage(),
0818: sqle);
0819: }
0820: } else {
0821: sFolderDir = null;
0822: }
0823:
0824: if (DebugFile.trace) {
0825: DebugFile.decIdent();
0826: String sMode = "";
0827: if ((iOpenMode & READ_WRITE) != 0)
0828: sMode += " READ_WRITE ";
0829: if ((iOpenMode & READ_ONLY) != 0)
0830: sMode += " READ_ONLY ";
0831: if ((iOpenMode & MODE_BLOB) != 0)
0832: sMode += " MODE_BLOB ";
0833: if ((iOpenMode & MODE_MBOX) != 0)
0834: sMode += " MODE_MBOX ";
0835: DebugFile.writeln("End DBFolder.open() :");
0836: }
0837:
0838: }
0839: } // open
0840:
0841: // ---------------------------------------------------------------------------
0842:
0843: /**
0844: * Close this folder
0845: * @param expunge
0846: * @throws MessagingException
0847: */
0848: public void close(boolean expunge) throws MessagingException {
0849: if (expunge)
0850: expunge();
0851: iOpenMode = 0;
0852: oConn = null;
0853: sFolderDir = null;
0854: }
0855:
0856: // ---------------------------------------------------------------------------
0857:
0858: /**
0859: * Wipe all messages and delete this folder
0860: * @param recurse boolean
0861: * @return boolean
0862: * @throws MessagingException
0863: */
0864: public boolean delete(boolean recurse) throws MessagingException {
0865: try {
0866: wipe();
0867: return oCatg.delete(getConnection());
0868: } catch (SQLException sqle) {
0869: throw new MessagingException(sqle.getMessage(), sqle);
0870: }
0871: }
0872:
0873: // ---------------------------------------------------------------------------
0874:
0875: /**
0876: * Get folder by name or GUID
0877: * @param name String Folder name or GUID
0878: * @return Folder
0879: * @throws MessagingException
0880: */
0881: public Folder getFolder(String name) throws MessagingException {
0882: return ((DBStore) getStore()).getFolder(name);
0883: }
0884:
0885: // ---------------------------------------------------------------------------
0886:
0887: /**
0888: * This method is not implemented and will always raise UnsupportedOperationException
0889: * @throws UnsupportedOperationException
0890: */
0891:
0892: public boolean hasNewMessages() throws MessagingException {
0893: throw new UnsupportedOperationException(
0894: "DBFolder.hasNewMessages()");
0895: }
0896:
0897: // ---------------------------------------------------------------------------
0898:
0899: public boolean renameTo(Folder f) throws MessagingException,
0900: StoreClosedException, NullPointerException {
0901:
0902: String[] aLabels = new String[] { "en", "es", "fr", "de", "it",
0903: "pt", "ca", "ja", "cn", "tw", "fi", "ru", "pl", "nl",
0904: "xx" };
0905: PreparedStatement oUpdt = null;
0906:
0907: if (!((DBStore) getStore()).isConnected())
0908: throw new StoreClosedException(getStore(),
0909: "Store is not connected");
0910:
0911: if (oCatg.isNull(DB.gu_category))
0912: throw new NullPointerException("Folder is closed");
0913:
0914: try {
0915:
0916: oUpdt = getConnection().prepareStatement(
0917: "DELETE FROM " + DB.k_cat_labels + " WHERE "
0918: + DB.gu_category + "=?");
0919: oUpdt.setString(1, oCatg.getString(DB.gu_category));
0920: oUpdt.executeUpdate();
0921: oUpdt.close();
0922:
0923: oUpdt.getConnection()
0924: .prepareStatement(
0925: "INSERT INTO " + DB.k_cat_labels + " ("
0926: + DB.gu_category + ","
0927: + DB.id_language + ","
0928: + DB.tr_category + ","
0929: + DB.url_category
0930: + ") VALUES (?,?,?,NULL)");
0931: oUpdt.setString(1, oCatg.getString(DB.gu_category));
0932:
0933: for (int l = 0; l < aLabels.length; l++) {
0934: oUpdt.setString(2, aLabels[l]);
0935: oUpdt.setString(3, f.getName().substring(0, 1)
0936: .toUpperCase()
0937: + f.getName().substring(1).toLowerCase());
0938: oUpdt.executeUpdate();
0939: }
0940: oUpdt.close();
0941: oUpdt = null;
0942: getConnection().commit();
0943: } catch (SQLException sqle) {
0944: try {
0945: if (null != oUpdt)
0946: oUpdt.close();
0947: } catch (SQLException ignore) {
0948: }
0949: try {
0950: getConnection().rollback();
0951: } catch (SQLException ignore) {
0952: }
0953: throw new MessagingException(sqle.getMessage(), sqle);
0954: }
0955: return true;
0956: } // renameTo
0957:
0958: // ---------------------------------------------------------------------------
0959:
0960: public boolean exists() throws MessagingException,
0961: StoreClosedException {
0962: if (!((DBStore) getStore()).isConnected())
0963: throw new StoreClosedException(getStore(),
0964: "Store is not connected");
0965:
0966: try {
0967: return oCatg.exists(getConnection());
0968: } catch (SQLException sqle) {
0969: throw new MessagingException(sqle.getMessage(), sqle);
0970: }
0971: }
0972:
0973: // ---------------------------------------------------------------------------
0974:
0975: /**
0976: * <p>Expunge deleted messages</p>
0977: * This method removes from the database and the MBOX file those messages flagged
0978: * as deleted at k_mime_msgs table
0979: * @return <b>null</b>
0980: * @throws MessagingException
0981: */
0982: public Message[] expunge() throws MessagingException {
0983: Statement oStmt = null;
0984: CallableStatement oCall = null;
0985: PreparedStatement oUpdt = null;
0986: PreparedStatement oPart = null;
0987: PreparedStatement oAddr = null;
0988: ResultSet oRSet;
0989:
0990: if (DebugFile.trace) {
0991: DebugFile.writeln("Begin DBFolder.expunge()");
0992: DebugFile.incIdent();
0993: }
0994:
0995: // *************************************************************************
0996: // If Folder is not opened is read-write mode then raise an exception
0997: if (0 == (iOpenMode & READ_WRITE)) {
0998: if (DebugFile.trace)
0999: DebugFile.decIdent();
1000: throw new javax.mail.FolderClosedException(this ,
1001: "Folder is not open is READ_WRITE mode");
1002: }
1003:
1004: if ((0 == (iOpenMode & MODE_MBOX))
1005: && (0 == (iOpenMode & MODE_BLOB))) {
1006: if (DebugFile.trace)
1007: DebugFile.decIdent();
1008: throw new javax.mail.FolderClosedException(this ,
1009: "Folder is not open in MBOX nor BLOB mode");
1010: }
1011:
1012: // ***********************************************
1013: // Get the list of deleted and not purged messages
1014:
1015: MboxFile oMBox = null;
1016: DBSubset oDeleted = new DBSubset(DB.k_mime_msgs, DB.gu_mimemsg
1017: + "," + DB.pg_message, DB.bo_deleted + "=1 AND "
1018: + DB.gu_category + "='"
1019: + oCatg.getString(DB.gu_category) + "'", 100);
1020:
1021: try {
1022: int iDeleted = oDeleted.load(getConnection());
1023:
1024: File oFile = getFile();
1025:
1026: // *************************************
1027: // Purge deleted messages from MBOX file
1028:
1029: if (oFile.exists() && iDeleted > 0) {
1030: oMBox = new MboxFile(oFile, MboxFile.READ_WRITE);
1031: int[] msgnums = new int[iDeleted];
1032: for (int m = 0; m < iDeleted; m++)
1033: msgnums[m] = oDeleted.getInt(1, m);
1034: oMBox.purge(msgnums);
1035: oMBox.close();
1036: }
1037:
1038: // ******************************************
1039: // Erase files referenced by deleted messages
1040:
1041: oStmt = oConn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
1042: ResultSet.CONCUR_READ_ONLY);
1043: oRSet = oStmt.executeQuery("SELECT p." + DB.file_name
1044: + " FROM " + DB.k_mime_parts + " p,"
1045: + DB.k_mime_msgs + " m WHERE p." + DB.gu_mimemsg
1046: + "=m." + DB.gu_mimemsg + " AND m."
1047: + DB.id_disposition + "='reference' AND m."
1048: + DB.bo_deleted + "=1 AND m." + DB.gu_category
1049: + "='" + oCatg.getString(DB.gu_category) + "'");
1050:
1051: while (oRSet.next()) {
1052: String sFileName = oRSet.getString(1);
1053: if (!oRSet.wasNull()) {
1054: try {
1055: File oRef = new File(sFileName);
1056: if (oRef.exists())
1057: oRef.delete();
1058: } catch (SecurityException se) {
1059: if (DebugFile.trace)
1060: DebugFile
1061: .writeln("SecurityException "
1062: + sFileName + " "
1063: + se.getMessage());
1064: }
1065: }
1066: } // wend
1067:
1068: oRSet.close();
1069: oRSet = null;
1070: oStmt.close();
1071: oStmt = null;
1072:
1073: // ****************************************************
1074: // Set Category size to length of MBOX file after purge
1075:
1076: oFile = getFile();
1077: oStmt = oConn.createStatement();
1078: oStmt.executeUpdate("UPDATE " + DB.k_categories + " SET "
1079: + DB.len_size + "="
1080: + String.valueOf(oFile.length()) + " WHERE "
1081: + DB.gu_category + "='"
1082: + getCategory().getString(DB.gu_category) + "'");
1083: oStmt.close();
1084: oStmt = null;
1085:
1086: // *********************************************
1087: // Actually delete messages from database tables
1088:
1089: if (oConn.getDataBaseProduct() == JDCConnection.DBMS_POSTGRESQL) {
1090: oStmt = oConn.createStatement();
1091: for (int d = 0; d < iDeleted; d++)
1092: oStmt.executeQuery("SELECT k_sp_del_mime_msg('"
1093: + oDeleted.getString(0, d) + "')");
1094: oStmt.close();
1095: oStmt = null;
1096: } else {
1097: oCall = oConn
1098: .prepareCall("{ call k_sp_del_mime_msg(?) }");
1099:
1100: for (int d = 0; d < iDeleted; d++) {
1101: oCall.setString(1, oDeleted.getString(0, d));
1102: oCall.execute();
1103: } // next
1104: oCall.close();
1105: oCall = null;
1106: }
1107:
1108: if (oFile.exists() && iDeleted > 0) {
1109:
1110: // ***********************************************************************
1111: // Temporary move all messages at k_mime_msgs, k_mime_parts & k_inet_addrs
1112: // beyond its maximum so they do not clash when progressive identifiers
1113: // are re-assigned
1114:
1115: BigDecimal oUnit = new BigDecimal(1);
1116: oStmt = oConn.createStatement(
1117: ResultSet.TYPE_FORWARD_ONLY,
1118: ResultSet.CONCUR_READ_ONLY);
1119: oRSet = oStmt
1120: .executeQuery("SELECT MAX("
1121: + DB.pg_message
1122: + ") FROM "
1123: + DB.k_mime_msgs
1124: + " WHERE "
1125: + DB.gu_category
1126: + "='"
1127: + getCategory().getString(
1128: DB.gu_category) + "'");
1129: oRSet.next();
1130: BigDecimal oMaxPg = oRSet.getBigDecimal(1);
1131: if (oRSet.wasNull())
1132: oMaxPg = new BigDecimal(0);
1133: oRSet.close();
1134: oRSet = null;
1135: oStmt.close();
1136: oStmt = null;
1137: oMaxPg = oMaxPg.add(oUnit);
1138:
1139: String sCat = getCategory().getString(DB.gu_category);
1140: oStmt = oConn.createStatement();
1141: oStmt.executeUpdate("UPDATE " + DB.k_mime_msgs
1142: + " SET " + DB.pg_message + "=" + DB.pg_message
1143: + "+" + oMaxPg.toString() + " WHERE "
1144: + DB.gu_category + "='" + sCat + "'");
1145: oStmt.close();
1146: oStmt = null;
1147:
1148: // *********************************************************************************
1149: // Re-assign ordinal position and byte offset for all messages remaining after purge
1150:
1151: DBSubset oMsgSet = new DBSubset(DB.k_mime_msgs,
1152: DB.gu_mimemsg + "," + DB.pg_message,
1153: DB.gu_category
1154: + "='"
1155: + getCategory().getString(
1156: DB.gu_category) + "' ORDER BY "
1157: + DB.pg_message, 1000);
1158: int iMsgCount = oMsgSet.load(oConn);
1159:
1160: oMBox = new MboxFile(oFile, MboxFile.READ_ONLY);
1161: long[] aPositions = oMBox.getMessagePositions();
1162: oMBox.close();
1163:
1164: oMaxPg = new BigDecimal(0);
1165: oUpdt = oConn.prepareStatement("UPDATE "
1166: + DB.k_mime_msgs + " SET " + DB.pg_message
1167: + "=?," + DB.nu_position + "=? WHERE "
1168: + DB.gu_mimemsg + "=?");
1169: oPart = oConn.prepareStatement("UPDATE "
1170: + DB.k_mime_parts + " SET " + DB.pg_message
1171: + "=? WHERE " + DB.gu_mimemsg + "=?");
1172: oAddr = oConn.prepareStatement("UPDATE "
1173: + DB.k_inet_addrs + " SET " + DB.pg_message
1174: + "=? WHERE " + DB.gu_mimemsg + "=?");
1175: for (int m = 0; m < iMsgCount; m++) {
1176: String sGuMsg = oMsgSet.getString(0, m);
1177: oUpdt.setBigDecimal(1, oMaxPg);
1178: oUpdt.setBigDecimal(2,
1179: new BigDecimal(aPositions[m]));
1180: oUpdt.setString(3, sGuMsg);
1181: oUpdt.executeUpdate();
1182: oPart.setBigDecimal(1, oMaxPg);
1183: oPart.setString(2, sGuMsg);
1184: oPart.executeUpdate();
1185: oAddr.setBigDecimal(1, oMaxPg);
1186: oAddr.setString(2, sGuMsg);
1187: oAddr.executeUpdate();
1188: oMaxPg = oMaxPg.add(oUnit);
1189: }
1190: oUpdt.close();
1191: oPart.close();
1192: oAddr.close();
1193: }
1194: oConn.commit();
1195: } catch (SQLException sqle) {
1196: try {
1197: if (oMBox != null)
1198: oMBox.close();
1199: } catch (Exception e) {
1200: }
1201: try {
1202: if (oStmt != null)
1203: oStmt.close();
1204: } catch (Exception e) {
1205: }
1206: try {
1207: if (oCall != null)
1208: oCall.close();
1209: } catch (Exception e) {
1210: }
1211: try {
1212: if (oConn != null)
1213: oConn.rollback();
1214: } catch (Exception e) {
1215: }
1216: throw new MessagingException(sqle.getMessage(), sqle);
1217: } catch (IOException sqle) {
1218: try {
1219: if (oMBox != null)
1220: oMBox.close();
1221: } catch (Exception e) {
1222: }
1223: try {
1224: if (oStmt != null)
1225: oStmt.close();
1226: } catch (Exception e) {
1227: }
1228: try {
1229: if (oCall != null)
1230: oCall.close();
1231: } catch (Exception e) {
1232: }
1233: try {
1234: if (oConn != null)
1235: oConn.rollback();
1236: } catch (Exception e) {
1237: }
1238: throw new MessagingException(sqle.getMessage(), sqle);
1239: }
1240:
1241: if (DebugFile.trace) {
1242: DebugFile.decIdent();
1243: DebugFile.writeln("End DBFolder.expunge()");
1244: }
1245:
1246: return null;
1247: } // expunge
1248:
1249: // ---------------------------------------------------------------------------
1250:
1251: /**
1252: * Delete all messages from this folder and clear MBOX file
1253: * @throws MessagingException
1254: */
1255: public void wipe() throws MessagingException {
1256: Statement oStmt = null;
1257: CallableStatement oCall = null;
1258: PreparedStatement oUpdt = null;
1259: PreparedStatement oPart = null;
1260: PreparedStatement oAddr = null;
1261: ResultSet oRSet;
1262:
1263: if (DebugFile.trace) {
1264: DebugFile.writeln("Begin DBFolder.wipe()");
1265: DebugFile.incIdent();
1266: }
1267:
1268: // *************************************************************************
1269: // If Folder is not opened is read-write mode then raise an exception
1270: if (0 == (iOpenMode & READ_WRITE)) {
1271: if (DebugFile.trace)
1272: DebugFile.decIdent();
1273: throw new javax.mail.FolderClosedException(this ,
1274: "Folder is not open is READ_WRITE mode");
1275: }
1276:
1277: if ((0 == (iOpenMode & MODE_MBOX))
1278: && (0 == (iOpenMode & MODE_BLOB))) {
1279: if (DebugFile.trace)
1280: DebugFile.decIdent();
1281: throw new javax.mail.FolderClosedException(this ,
1282: "Folder is not open in MBOX nor BLOB mode");
1283: }
1284:
1285: // *************************************************
1286: // Get the list of all messages stored at this folder
1287:
1288: MboxFile oMBox = null;
1289: DBSubset oDeleted = new DBSubset(DB.k_mime_msgs, DB.gu_mimemsg
1290: + "," + DB.pg_message, DB.gu_category + "='"
1291: + oCatg.getString(DB.gu_category) + "'", 100);
1292:
1293: try {
1294: int iDeleted = oDeleted.load(getConnection());
1295: if (DebugFile.trace)
1296: DebugFile.writeln("there are "
1297: + String.valueOf(iDeleted)
1298: + " messages to be deleted");
1299:
1300: // ****************************************
1301: // Erase files referenced by draft messages
1302:
1303: oStmt = oConn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
1304: ResultSet.CONCUR_READ_ONLY);
1305: if (DebugFile.trace)
1306: DebugFile.writeln("Statement.executeQuery(SELECT p."
1307: + DB.file_name + " FROM " + DB.k_mime_parts
1308: + " p," + DB.k_mime_msgs + " m WHERE p."
1309: + DB.gu_mimemsg + "=m." + DB.gu_mimemsg
1310: + " AND m." + DB.id_disposition
1311: + "='reference' AND m." + DB.bo_deleted
1312: + "=1 AND m." + DB.gu_category + "='"
1313: + oCatg.getString(DB.gu_category) + "')");
1314: oRSet = oStmt.executeQuery("SELECT p." + DB.file_name
1315: + " FROM " + DB.k_mime_parts + " p,"
1316: + DB.k_mime_msgs + " m WHERE p." + DB.gu_mimemsg
1317: + "=m." + DB.gu_mimemsg + " AND m."
1318: + DB.id_disposition + "='reference' AND m."
1319: + DB.bo_deleted + "=1 AND m." + DB.gu_category
1320: + "='" + oCatg.getString(DB.gu_category) + "'");
1321:
1322: while (oRSet.next()) {
1323: String sFileName = oRSet.getString(1);
1324: if (!oRSet.wasNull()) {
1325: try {
1326: File oRef = new File(sFileName);
1327: if (oRef.exists())
1328: oRef.delete();
1329: } catch (SecurityException se) {
1330: if (DebugFile.trace)
1331: DebugFile
1332: .writeln("SecurityException "
1333: + sFileName + " "
1334: + se.getMessage());
1335: }
1336: }
1337: } // wend
1338:
1339: oRSet.close();
1340: oRSet = null;
1341: oStmt.close();
1342: oStmt = null;
1343:
1344: // *************************
1345: // Set Category size to zero
1346:
1347: oStmt = oConn.createStatement();
1348: if (DebugFile.trace)
1349: DebugFile.writeln("Statement.executeUpdate(UPDATE "
1350: + DB.k_categories + " SET " + DB.len_size
1351: + "=0 WHERE " + DB.gu_category + "='"
1352: + getCategory().getString(DB.gu_category)
1353: + "')");
1354: oStmt.executeUpdate("UPDATE " + DB.k_categories + " SET "
1355: + DB.len_size + "=0 WHERE " + DB.gu_category + "='"
1356: + getCategory().getString(DB.gu_category) + "'");
1357: oStmt.close();
1358: oStmt = null;
1359:
1360: // *********************************************
1361: // Actually delete messages from database tables
1362:
1363: if (oConn.getDataBaseProduct() == JDCConnection.DBMS_POSTGRESQL) {
1364: oStmt = oConn.createStatement();
1365: for (int d = 0; d < iDeleted; d++)
1366: oStmt.executeQuery("SELECT k_sp_del_mime_msg('"
1367: + oDeleted.getString(0, d) + "')");
1368: oStmt.close();
1369: oStmt = null;
1370: } else {
1371: oCall = oConn
1372: .prepareCall("{ call k_sp_del_mime_msg(?) }");
1373:
1374: for (int d = 0; d < iDeleted; d++) {
1375: oCall.setString(1, oDeleted.getString(0, d));
1376: oCall.execute();
1377: } // next
1378: oCall.close();
1379: oCall = null;
1380: }
1381:
1382: // *************************************
1383: // Truncate MBOX file
1384:
1385: File oFile = getFile();
1386: if (oFile.exists()) {
1387: if (DebugFile.trace)
1388: DebugFile.writeln("File.delete(" + getFilePath()
1389: + ")");
1390: oFile.delete();
1391: }
1392:
1393: if (DebugFile.trace)
1394: DebugFile.writeln("Connection.commit()");
1395:
1396: oConn.commit();
1397: } catch (Exception sqle) {
1398: try {
1399: if (oMBox != null)
1400: oMBox.close();
1401: } catch (Exception e) {
1402: }
1403: try {
1404: if (oStmt != null)
1405: oStmt.close();
1406: } catch (Exception e) {
1407: }
1408: try {
1409: if (oCall != null)
1410: oCall.close();
1411: } catch (Exception e) {
1412: }
1413: try {
1414: if (oConn != null)
1415: oConn.rollback();
1416: } catch (Exception e) {
1417: }
1418: throw new MessagingException(sqle.getMessage(), sqle);
1419: }
1420:
1421: if (DebugFile.trace) {
1422: DebugFile.decIdent();
1423: DebugFile.writeln("End DBFolder.wipe()");
1424: }
1425: } // wipe
1426:
1427: // ---------------------------------------------------------------------------
1428:
1429: /**
1430: * <p>Get category subpath to directory holding MBOX files for this folder</p>
1431: * The category path is composed by concatenating the names of all the parent
1432: * folders separated by a slash. The name of a folder is stored at column nm_category
1433: * of table k_categories
1434: * @return String
1435: */
1436: public String getFullName() {
1437: try {
1438: if (oCatg.exists(getConnection()))
1439: return oCatg.getPath(getConnection());
1440: else
1441: return null;
1442: } catch (SQLException sqle) {
1443: return null;
1444: }
1445: }
1446:
1447: // ---------------------------------------------------------------------------
1448:
1449: /**
1450: * Get path to directory containing files belonging to this folder
1451: * @return String
1452: */
1453: public String getDirectoryPath() {
1454: return Gadgets.chomp(sFolderDir, File.separator);
1455: }
1456:
1457: // ---------------------------------------------------------------------------
1458:
1459: /**
1460: * Get full path to MBOX file containing mime messages
1461: * @return String
1462: */
1463: public String getFilePath() {
1464: return Gadgets.chomp(sFolderDir, File.separator)
1465: + oCatg.getString(DB.nm_category) + ".mbox";
1466: }
1467:
1468: // ---------------------------------------------------------------------------
1469:
1470: /**
1471: * Get MBOX file that holds messages for this DBFolder
1472: * @return java.io.File object representing MBOX file.
1473: */
1474: public File getFile() {
1475: return new File(getFilePath());
1476: }
1477:
1478: // ---------------------------------------------------------------------------
1479:
1480: /**
1481: * Get column nm_category from table k_categories for this folder
1482: * @return String
1483: */
1484: public String getName() {
1485: return sFolderName == null ? oCatg.getString(DB.nm_category)
1486: : sFolderName;
1487: }
1488:
1489: // ---------------------------------------------------------------------------
1490:
1491: public URLName getURLName() throws MessagingException,
1492: StoreClosedException {
1493:
1494: if (!((DBStore) getStore()).isConnected())
1495: throw new StoreClosedException(getStore(),
1496: "Store is not connected");
1497:
1498: com.knowgate.acl.ACLUser oUsr = ((DBStore) getStore())
1499: .getUser();
1500: return new URLName("jdbc://", "localhost", -1, oCatg
1501: .getString(DB.gu_category), oUsr.getString(DB.gu_user),
1502: oUsr.getString(DB.tx_pwd));
1503: }
1504:
1505: // ---------------------------------------------------------------------------
1506:
1507: protected Message getMessage(String sMsgId, int IdType)
1508: throws MessagingException {
1509:
1510: if (DebugFile.trace) {
1511: DebugFile.writeln("Begin DBFolder.getMessage(" + sMsgId
1512: + "," + String.valueOf(IdType) + ")");
1513: DebugFile.incIdent();
1514: }
1515:
1516: // *************************************************************************
1517: // If Folder is not opened then raise an exception
1518: if (!isOpen()) {
1519: if (DebugFile.trace)
1520: DebugFile.decIdent();
1521: throw new javax.mail.FolderClosedException(this ,
1522: "Folder is closed");
1523: }
1524:
1525: DBMimeMessage oRetVal = null;
1526:
1527: PreparedStatement oStmt = null;
1528: ResultSet oRSet = null;
1529: String sSQL;
1530: Timestamp tsSent;
1531: String sMsgGuid, sContentId, sMsgDesc, sMsgDisposition, sMsgMD5, sMsgSubject, sMsgFrom, sReplyTo, sDisplayName;
1532: short iAnswered, iDeleted, iDraft, iFlagged, iRecent, iSeen;
1533: final String sColList = DB.gu_mimemsg + "," + DB.id_message
1534: + "," + DB.id_disposition + "," + DB.tx_md5 + ","
1535: + DB.de_mimemsg + "," + DB.tx_subject + ","
1536: + DB.dt_sent + "," + DB.bo_answered + ","
1537: + DB.bo_deleted + "," + DB.bo_draft + ","
1538: + DB.bo_flagged + "," + DB.bo_recent + "," + DB.bo_seen
1539: + "," + DB.tx_email_from + "," + DB.tx_email_reply
1540: + "," + DB.nm_from + "," + DB.by_content;
1541: InternetAddress oFrom = null, oReply = null;
1542: MimeMultipart oParts = new MimeMultipart();
1543:
1544: try {
1545: switch (IdType) {
1546: case 1:
1547: sSQL = "SELECT " + sColList + " FROM " + DB.k_mime_msgs
1548: + " WHERE " + DB.gu_mimemsg + "=?";
1549: if (DebugFile.trace)
1550: DebugFile.writeln("Connection.prepareStatement("
1551: + sSQL + ")");
1552:
1553: oStmt = oConn.prepareStatement(sSQL,
1554: ResultSet.TYPE_FORWARD_ONLY,
1555: ResultSet.CONCUR_READ_ONLY);
1556: oStmt.setString(1, sMsgId);
1557: break;
1558: case 2:
1559: sSQL = "SELECT " + sColList + " FROM " + DB.k_mime_msgs
1560: + " WHERE " + DB.id_message + "=?";
1561: if (DebugFile.trace)
1562: DebugFile.writeln("Connection.prepareStatement("
1563: + sSQL + ")");
1564:
1565: oStmt = oConn.prepareStatement(sSQL,
1566: ResultSet.TYPE_FORWARD_ONLY,
1567: ResultSet.CONCUR_READ_ONLY);
1568: oStmt.setString(1, sMsgId);
1569: break;
1570: case 3:
1571: sSQL = "SELECT " + sColList + " FROM " + DB.k_mime_msgs
1572: + " WHERE " + DB.pg_message + "=?";
1573: if (DebugFile.trace)
1574: DebugFile.writeln("Connection.prepareStatement("
1575: + sSQL + ")");
1576:
1577: oStmt = oConn.prepareStatement(sSQL,
1578: ResultSet.TYPE_FORWARD_ONLY,
1579: ResultSet.CONCUR_READ_ONLY);
1580: oStmt
1581: .setBigDecimal(1, new java.math.BigDecimal(
1582: sMsgId));
1583: break;
1584: }
1585:
1586: oRSet = oStmt.executeQuery();
1587:
1588: if (oRSet.next()) {
1589: sMsgGuid = oRSet.getString(1);
1590:
1591: if (DebugFile.trace)
1592: DebugFile.writeln("gu_mimemsg=" + sMsgGuid);
1593:
1594: sContentId = oRSet.getString(2);
1595: sMsgDisposition = oRSet.getString(3);
1596: sMsgMD5 = oRSet.getString(4);
1597: sMsgDesc = oRSet.getString(5);
1598: sMsgSubject = oRSet.getString(6);
1599: tsSent = oRSet.getTimestamp(7);
1600: iAnswered = oRSet.getShort(8);
1601: iDeleted = oRSet.getShort(9);
1602: iDraft = oRSet.getShort(10);
1603: iFlagged = oRSet.getShort(11);
1604: iRecent = oRSet.getShort(12);
1605: iSeen = oRSet.getShort(13);
1606: sMsgFrom = oRSet.getString(14);
1607: sReplyTo = oRSet.getString(15);
1608: sDisplayName = oRSet.getString(16);
1609:
1610: if (DebugFile.trace)
1611: DebugFile.writeln("ResultSet.getBinaryStream("
1612: + DB.by_content + ")");
1613:
1614: InputStream oLongVarBin = oRSet.getBinaryStream(17);
1615:
1616: if (!oRSet.wasNull()) {
1617: if (DebugFile.trace)
1618: DebugFile
1619: .writeln("MimeMultipart.addBodyPart(new MimeBodyPart(InputStream)");
1620: oParts.addBodyPart(new MimeBodyPart(oLongVarBin));
1621: }
1622:
1623: oRSet.close();
1624: oRSet = null;
1625:
1626: oRetVal = new DBMimeMessage(this , sMsgGuid);
1627:
1628: oRetVal.setContentID(sContentId);
1629: oRetVal.setDisposition(sMsgDisposition);
1630: oRetVal.setContentMD5(sMsgMD5);
1631: oRetVal.setDescription(sMsgDesc);
1632:
1633: if (sMsgSubject != null) {
1634: if (sMsgSubject.length() > 0) {
1635: if (DebugFile.trace)
1636: DebugFile.writeln("tx_subject="
1637: + sMsgSubject);
1638: oRetVal.setSubject(sMsgSubject);
1639: }
1640: }
1641:
1642: oRetVal.setSentDate(tsSent);
1643: oRetVal.setFlag(Flags.Flag.ANSWERED, iAnswered != 0);
1644: oRetVal.setFlag(Flags.Flag.DELETED, iDeleted != 0);
1645: oRetVal.setFlag(Flags.Flag.DRAFT, iDraft != 0);
1646: oRetVal.setFlag(Flags.Flag.FLAGGED, iFlagged != 0);
1647: oRetVal.setFlag(Flags.Flag.RECENT, iRecent != 0);
1648: oRetVal.setFlag(Flags.Flag.SEEN, iSeen != 0);
1649:
1650: if (sMsgFrom != null) {
1651: if (DebugFile.trace)
1652: DebugFile.writeln("from: " + sMsgFrom);
1653: if (null == sDisplayName)
1654: oFrom = new InternetAddress(sMsgFrom);
1655: else
1656: oFrom = new InternetAddress(sMsgFrom,
1657: sDisplayName);
1658: oRetVal.setFrom(oFrom);
1659: }
1660:
1661: if (sReplyTo != null) {
1662: if (DebugFile.trace)
1663: DebugFile.writeln("reply to: " + sReplyTo);
1664: oReply = new InternetAddress(sReplyTo);
1665: oRetVal.setReplyTo(new Address[] { oReply });
1666: }
1667:
1668: oRetVal.setRecipients(Message.RecipientType.TO, oRetVal
1669: .getRecipients(Message.RecipientType.TO));
1670: oRetVal.setRecipients(Message.RecipientType.CC, oRetVal
1671: .getRecipients(Message.RecipientType.CC));
1672: oRetVal
1673: .setRecipients(
1674: Message.RecipientType.BCC,
1675: oRetVal
1676: .getRecipients(Message.RecipientType.BCC));
1677:
1678: if (DebugFile.trace)
1679: DebugFile
1680: .writeln("MimeMessage.setContent(MimeMultipart)");
1681:
1682: oRetVal.setContent(oParts);
1683: } else {
1684: oRSet.close();
1685: oRSet = null;
1686: }// fi (oRSet.next())
1687:
1688: oStmt.close();
1689: oStmt = null;
1690: } catch (SQLException sqle) {
1691: try {
1692: if (oRSet != null)
1693: oRSet.close();
1694: } catch (SQLException ignore) {
1695: }
1696: try {
1697: if (oStmt != null)
1698: oStmt.close();
1699: } catch (SQLException ignore) {
1700: }
1701:
1702: throw new MessagingException(sqle.getMessage(), sqle);
1703: } catch (UnsupportedEncodingException uee) {
1704: try {
1705: if (oRSet != null)
1706: oRSet.close();
1707: } catch (SQLException ignore) {
1708: }
1709: try {
1710: if (oStmt != null)
1711: oStmt.close();
1712: } catch (SQLException ignore) {
1713: }
1714:
1715: throw new MessagingException(uee.getMessage(), uee);
1716: }
1717:
1718: if (DebugFile.trace) {
1719: DebugFile.decIdent();
1720: DebugFile.writeln("End DBFolder.getMessage() : "
1721: + (oRetVal != null ? "[MimeMessage]" : "null"));
1722: }
1723:
1724: return oRetVal;
1725: } // getMessage
1726:
1727: // ---------------------------------------------------------------------------
1728:
1729: private void saveMimeParts(MimeMessage oMsg, String sMsgCharSeq,
1730: String sBoundary, String sMsgGuid, String sMsgId,
1731: int iPgMessage, int iOffset) throws MessagingException,
1732: OutOfMemoryError {
1733:
1734: if (DebugFile.trace) {
1735: DebugFile
1736: .writeln("Begin DBFolder.saveMimeParts([Connection], [MimeMessage], "
1737: + sBoundary
1738: + ", "
1739: + sMsgGuid
1740: + ","
1741: + sMsgId
1742: + ", "
1743: + String.valueOf(iPgMessage)
1744: + ", "
1745: + String.valueOf(iOffset)
1746: + ", [Properties])");
1747: DebugFile.incIdent();
1748: }
1749:
1750: PreparedStatement oStmt = null;
1751: Blob oContentTxt;
1752: ByteArrayOutputStream byOutPart;
1753: int iPrevPart = 0, iThisPart = 0, iNextPart = 0, iPartStart = 0;
1754:
1755: try {
1756: MimeMultipart oParts = (MimeMultipart) oMsg.getContent();
1757:
1758: final int iParts = oParts.getCount();
1759:
1760: if (DebugFile.trace)
1761: DebugFile.writeln("message has "
1762: + String.valueOf(iParts) + " parts");
1763:
1764: if (iParts > 0) {
1765: // Skip boundary="..."; from Mime header
1766: // and boundaries from all previous parts
1767: if (sMsgCharSeq != null && sBoundary != null
1768: && ((iOpenMode & MODE_MBOX) != 0)) {
1769: // First boundary substring acurrence is the one from the message headers
1770: iPrevPart = sMsgCharSeq.indexOf(sBoundary,
1771: iPrevPart);
1772: if (iPrevPart > 0) {
1773: iPrevPart += sBoundary.length();
1774: if (DebugFile.trace)
1775: DebugFile
1776: .writeln("found message boundary token at "
1777: + String.valueOf(iPrevPart));
1778: } // fi (message boundary)
1779: } // fi (sMsgCharSeq && sBoundary)
1780:
1781: String sSQL = "INSERT INTO "
1782: + DB.k_mime_parts
1783: + "(gu_mimemsg,id_message,pg_message,nu_offset,id_part,id_content,id_type,id_disposition,len_part,de_part,tx_md5,file_name,by_content) VALUES ('"
1784: + sMsgGuid + "',?,?,?,?,?,?,?,?,?,NULL,?,?)";
1785:
1786: if (DebugFile.trace)
1787: DebugFile.writeln("Connection.prepareStatement("
1788: + sSQL + ")");
1789:
1790: oStmt = oConn.prepareStatement(sSQL);
1791:
1792: for (int p = 0; p < iParts; p++) {
1793: if (DebugFile.trace) {
1794: DebugFile.writeln("processing part "
1795: + String.valueOf(p));
1796: DebugFile.writeln("previous part at "
1797: + String.valueOf(iPrevPart));
1798: DebugFile.writeln("part boundary is "
1799: + sBoundary);
1800: if (null == sMsgCharSeq)
1801: DebugFile
1802: .writeln("characer sequence is null");
1803: }
1804:
1805: BodyPart oPart = oParts.getBodyPart(p);
1806: byOutPart = new ByteArrayOutputStream(oPart
1807: .getSize() > 0 ? oPart.getSize() : 131072);
1808: oPart.writeTo(byOutPart);
1809:
1810: if (sMsgCharSeq != null && sBoundary != null
1811: && iPrevPart > 0) {
1812: iThisPart = sMsgCharSeq.indexOf(sBoundary,
1813: iPrevPart);
1814: if (iThisPart > 0) {
1815: if (DebugFile.trace)
1816: DebugFile.writeln("found part "
1817: + String.valueOf(p + iOffset)
1818: + " boundary at "
1819: + String.valueOf(iThisPart));
1820: iPartStart = iThisPart + sBoundary.length();
1821: while (iPartStart < sMsgCharSeq.length()) {
1822: if (sMsgCharSeq.charAt(iPartStart) != ' '
1823: && sMsgCharSeq
1824: .charAt(iPartStart) != '\r'
1825: && sMsgCharSeq
1826: .charAt(iPartStart) != '\n'
1827: && sMsgCharSeq
1828: .charAt(iPartStart) != '\t')
1829: break;
1830: else
1831: iPartStart++;
1832: } // wend
1833: }
1834: iNextPart = sMsgCharSeq.indexOf(sBoundary,
1835: iPartStart);
1836: if (iNextPart < 0) {
1837: if (DebugFile.trace)
1838: DebugFile.writeln("no next part found");
1839: iNextPart = sMsgCharSeq.length();
1840: } else {
1841: if (DebugFile.trace)
1842: DebugFile
1843: .writeln("next part boundary found at "
1844: + String
1845: .valueOf(iNextPart));
1846: }
1847: } // fi (sMsgCharSeq!=null && sBoundary!=null && iPrevPart>0)
1848:
1849: String sContentType = oPart.getContentType();
1850: if (sContentType != null)
1851: sContentType = MimeUtility
1852: .decodeText(sContentType);
1853:
1854: boolean bForwardedAttachment = false;
1855:
1856: if ((null != sContentType)
1857: && (null != ((DBStore) getStore())
1858: .getSession())) {
1859: if (DebugFile.trace)
1860: DebugFile.writeln("Part Content-Type: "
1861: + sContentType.replace('\r', ' ')
1862: .replace('\n', ' '));
1863:
1864: if (sContentType.toUpperCase().startsWith(
1865: "MULTIPART/ALTERNATIVE")
1866: || sContentType
1867: .toUpperCase()
1868: .startsWith("MULTIPART/RELATED")
1869: || sContentType.toUpperCase()
1870: .startsWith("MULTIPART/SIGNED")) {
1871: try {
1872: ByteArrayInputStream byInStrm = new ByteArrayInputStream(
1873: byOutPart.toByteArray());
1874:
1875: MimeMessage oForwarded = new MimeMessage(
1876: ((DBStore) getStore())
1877: .getSession(), byInStrm);
1878:
1879: saveMimeParts(oForwarded, sMsgCharSeq,
1880: getPartsBoundary(oForwarded),
1881: sMsgGuid, sMsgId, iPgMessage,
1882: iOffset + iParts);
1883:
1884: byInStrm.close();
1885: byInStrm = null;
1886:
1887: bForwardedAttachment = true;
1888: } catch (Exception e) {
1889: if (DebugFile.trace)
1890: DebugFile.writeln(e.getClass()
1891: .getName()
1892: + " " + e.getMessage());
1893: }
1894: } // fi (MULTIPART/ALTERNATIVE)
1895: } // fi (null!=sContentType && null!=getSession())
1896:
1897: if (!bForwardedAttachment) {
1898: if (DebugFile.trace) {
1899: if ((iOpenMode & MODE_MBOX) != 0) {
1900: DebugFile.writeln("MBOX mode");
1901: DebugFile.writeln("nu_offset="
1902: + String.valueOf(iPartStart));
1903: DebugFile.writeln("nu_len="
1904: + String.valueOf(iNextPart
1905: - iPartStart));
1906: } else if ((iOpenMode & MODE_BLOB) != 0) {
1907: DebugFile.writeln("BLOB mode");
1908: DebugFile.writeln("nu_offset=null");
1909: DebugFile.writeln("nu_len="
1910: + String.valueOf(oPart
1911: .getSize() > 0 ? oPart
1912: .getSize() : byOutPart
1913: .size()));
1914: }
1915: DebugFile.writeln("id_message=" + sMsgId);
1916: DebugFile.writeln("id_part="
1917: + String.valueOf(p + iOffset));
1918: DebugFile.writeln("pg_message="
1919: + String.valueOf(iPgMessage));
1920: }
1921:
1922: oStmt.setString(1, sMsgId); // id_message
1923: oStmt.setBigDecimal(2, new BigDecimal(
1924: iPgMessage)); // pg_message
1925:
1926: if ((iPartStart > 0)
1927: && ((iOpenMode & MODE_MBOX) != 0))
1928: oStmt.setBigDecimal(3, new BigDecimal(
1929: iPartStart)); // nu_offset
1930: else
1931: oStmt
1932: .setNull(
1933: 3,
1934: oConn.getDataBaseProduct() == JDCConnection.DBMS_ORACLE ? Types.NUMERIC
1935: : Types.DECIMAL);
1936:
1937: oStmt.setInt(4, p + iOffset); // id_part
1938: oStmt
1939: .setString(
1940: 5,
1941: ((javax.mail.internet.MimeBodyPart) oPart)
1942: .getContentID()); // id_content
1943: oStmt.setString(6, Gadgets.left(sContentType,
1944: 254)); // id_type
1945: oStmt.setString(7, Gadgets.left(oPart
1946: .getDisposition(), 100));
1947:
1948: if ((iOpenMode & MODE_MBOX) != 0)
1949: oStmt.setInt(8, iNextPart - iPartStart);
1950: else
1951: oStmt.setInt(8, oPart.getSize() > 0 ? oPart
1952: .getSize() : byOutPart.size());
1953:
1954: if (oPart.getDescription() != null)
1955: oStmt.setString(9, Gadgets.left(
1956: MimeUtility.decodeText(oPart
1957: .getDescription()), 254));
1958: else
1959: oStmt.setNull(9, Types.VARCHAR);
1960:
1961: if (DebugFile.trace)
1962: DebugFile.writeln("file name is "
1963: + oPart.getFileName());
1964:
1965: if (oPart.getFileName() != null)
1966: oStmt.setString(10, Gadgets.left(
1967: MimeUtility.decodeText(oPart
1968: .getFileName()), 254));
1969: else
1970: oStmt.setNull(10, Types.VARCHAR);
1971:
1972: if ((iOpenMode & MODE_BLOB) != 0)
1973: oStmt.setBinaryStream(11,
1974: new ByteArrayInputStream(byOutPart
1975: .toByteArray()), byOutPart
1976: .size());
1977: else
1978: oStmt.setNull(11, Types.LONGVARBINARY);
1979:
1980: if (DebugFile.trace)
1981: DebugFile
1982: .writeln("PreparedStatement.executeUpdate()");
1983:
1984: oStmt.executeUpdate();
1985: } // fi (bForwardedAttachment)
1986:
1987: byOutPart.close();
1988: byOutPart = null;
1989: oContentTxt = null;
1990:
1991: if ((iOpenMode & MODE_MBOX) != 0)
1992: iPrevPart = iNextPart;
1993:
1994: } // next (p)
1995:
1996: if (DebugFile.trace)
1997: DebugFile.writeln("PreparedStatement.close()");
1998: oStmt.close();
1999: } // fi (iParts>0)
2000: } catch (SQLException e) {
2001: if (DebugFile.trace) {
2002: DebugFile.writeln("SQLException " + e.getMessage());
2003: DebugFile.decIdent();
2004: }
2005: // Ensure that statement is closed and re-throw
2006: if (null != oStmt) {
2007: try {
2008: oStmt.close();
2009: } catch (Exception ignore) {
2010: }
2011: }
2012: try {
2013: if (null != oConn)
2014: oConn.rollback();
2015: } catch (Exception ignore) {
2016: }
2017: throw new MessagingException(e.getMessage(), e);
2018: } catch (IOException e) {
2019: if (DebugFile.trace) {
2020: DebugFile.writeln("IOException " + e.getMessage());
2021: DebugFile.decIdent();
2022: }
2023: // Ensure that statement is closed and re-throw
2024: if (null != oStmt) {
2025: try {
2026: oStmt.close();
2027: } catch (Exception ignore) {
2028: }
2029: }
2030: throw new MessagingException(e.getMessage(), e);
2031: } catch (Exception e) {
2032: if (DebugFile.trace) {
2033: DebugFile.writeln(e.getClass().getName() + " "
2034: + e.getMessage());
2035: DebugFile.decIdent();
2036: }
2037: // Ensure that statement is closed and re-throw
2038: if (null != oStmt) {
2039: try {
2040: oStmt.close();
2041: } catch (Exception ignore) {
2042: }
2043: }
2044: throw new MessagingException(e.getMessage(), e);
2045: }
2046:
2047: if (DebugFile.trace) {
2048: DebugFile.decIdent();
2049: DebugFile.writeln("End DBFolder.saveMimeParts()");
2050: }
2051: } // saveMimeParts
2052:
2053: // ---------------------------------------------------------------------------
2054:
2055: private static String getPartsBoundary(MimeMessage oMsg)
2056: throws MessagingException {
2057: if (DebugFile.trace) {
2058: DebugFile
2059: .writeln("Begin DBFolder.getPartsBoundary([MimeMessage])");
2060: DebugFile.incIdent();
2061: }
2062:
2063: String sBoundary = null;
2064: String sContentType = oMsg.getContentType();
2065:
2066: if (DebugFile.trace)
2067: DebugFile.writeln("Content-Type: " + sContentType);
2068:
2069: if (null != sContentType) {
2070: int iTypeLen = sContentType.length();
2071: // Find first occurrence of "boundary" substring
2072: int iBoundary = sContentType.toLowerCase().indexOf(
2073: "boundary");
2074: if (iBoundary > 0) {
2075: // If "boundary" is found find first equals sign
2076: int iEq = sContentType.indexOf("=", iBoundary + 8);
2077: if (iEq > 0) {
2078: iEq++;
2079: // If equals sign is found skip any blank spaces and quotes
2080: while (iEq < iTypeLen) {
2081: char cAt = sContentType.charAt(iEq);
2082: if (cAt != ' ' && cAt != '"')
2083: break;
2084: else
2085: iEq++;
2086: } // wend
2087: if (iEq < iTypeLen) {
2088: int iEnd = iEq;
2089: // Look forward in character sequence until quote, semi-colon or new line is found
2090: while (iEnd < iTypeLen) {
2091: char cAt = sContentType.charAt(iEnd);
2092: if (cAt != '"' && cAt != ';' && cAt != '\r'
2093: && cAt != '\n' && cAt != '\t')
2094: iEnd++;
2095: else
2096: break;
2097: } // wend
2098: if (iEnd == iTypeLen)
2099: sBoundary = sContentType.substring(iEq);
2100: else
2101: sBoundary = sContentType.substring(iEq,
2102: iEnd);
2103: }
2104: } // fi (indexOf("="))
2105: } // fi (indexOf("boundary"))
2106: } // fi (sContentType)
2107:
2108: if (DebugFile.trace) {
2109: DebugFile.decIdent();
2110: DebugFile.writeln("End DBFolder.getPartsBoundary() : "
2111: + sBoundary);
2112: }
2113:
2114: return sBoundary;
2115: } // getPartsBoundary
2116:
2117: // ---------------------------------------------------------------------------
2118:
2119: private synchronized BigDecimal getNextMessage()
2120: throws MessagingException {
2121: PreparedStatement oStmt = null;
2122: ResultSet oRSet = null;
2123: BigDecimal oNext;
2124:
2125: try {
2126: oConn = getConnection();
2127:
2128: oStmt = oConn.prepareStatement("SELECT MAX("
2129: + DB.pg_message + ") FROM " + DB.k_mime_msgs
2130: + " WHERE " + DB.gu_category + "=?",
2131: ResultSet.TYPE_FORWARD_ONLY,
2132: ResultSet.CONCUR_READ_ONLY);
2133: oStmt.setString(1, getCategory().getString(DB.gu_category));
2134: oRSet = oStmt.executeQuery();
2135: oRSet.next();
2136: oNext = oRSet.getBigDecimal(1);
2137: if (oRSet.wasNull())
2138: oNext = new BigDecimal(0);
2139: else
2140: oNext = oNext.add(new BigDecimal(1));
2141: oRSet.close();
2142: oRSet = null;
2143: oStmt.close();
2144: oStmt = null;
2145: } catch (Exception xcpt) {
2146: try {
2147: if (null != oRSet)
2148: oRSet.close();
2149: } catch (Exception ignore) {
2150: }
2151: try {
2152: if (null != oStmt)
2153: oStmt.close();
2154: } catch (Exception ignore) {
2155: }
2156: throw new MessagingException(xcpt.getMessage(), xcpt);
2157: }
2158: return oNext;
2159: } // getNextMessage()
2160:
2161: // ---------------------------------------------------------------------------
2162:
2163: private void indexMessage(String sGuMimeMsg, String sGuWorkArea,
2164: MimeMessage oMsg, Integer iSize, BigDecimal dPosition,
2165: String sContentType, String sContentID, String sMessageID,
2166: String sDisposition, String sContentMD5,
2167: String sDescription, String sFileName, String sEncoding,
2168: String sSubject, String sPriority, Flags oFlgs,
2169: Timestamp tsSent, Timestamp tsReceived,
2170: InternetAddress oFrom, InternetAddress oReply,
2171: Address[] oTo, Address[] oCC, Address[] oBCC,
2172: boolean bIsSpam, ByteArrayOutputStream byOutStrm,
2173: String sMsgCharSeq) throws MessagingException {
2174:
2175: // *************************************************************************
2176: // Prepare insert statement for k_mime_msgs table.
2177: // This is the main table for referencing messages.
2178:
2179: if (DebugFile.trace) {
2180: DebugFile.writeln("Begin DBFolder.indexMessage()");
2181: DebugFile.incIdent();
2182: }
2183:
2184: Properties pFrom = new Properties(), pTo = new Properties(), pCC = new Properties(), pBCC = new Properties();
2185: PreparedStatement oStmt = null;
2186: BigDecimal dPgMessage;
2187: String sSQL;
2188:
2189: String sBoundary = getPartsBoundary(oMsg);
2190: if (DebugFile.trace)
2191: DebugFile.writeln("part boundary is \""
2192: + (sBoundary == null ? "null" : sBoundary) + "\"");
2193:
2194: try {
2195: sSQL = "INSERT INTO "
2196: + DB.k_mime_msgs
2197: + "(gu_mimemsg,gu_workarea,gu_category,id_type,id_content,id_message,id_disposition,len_mimemsg,tx_md5,de_mimemsg,file_name,tx_encoding,tx_subject,dt_sent,dt_received,tx_email_from,nm_from,tx_email_reply,nm_to,id_priority,bo_answered,bo_deleted,bo_draft,bo_flagged,bo_recent,bo_seen,bo_spam,pg_message,nu_position,by_content) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
2198:
2199: if (DebugFile.trace)
2200: DebugFile.writeln("Connection.prepareStatement(" + sSQL
2201: + ")");
2202:
2203: oStmt = oConn.prepareStatement(sSQL);
2204: oStmt.setString(1, sGuMimeMsg);
2205: oStmt.setString(2, sGuWorkArea);
2206:
2207: if (oCatg.isNull(DB.gu_category))
2208: oStmt.setNull(3, Types.CHAR);
2209: else
2210: oStmt.setString(3, oCatg.getString(DB.gu_category));
2211:
2212: oStmt.setString(4, Gadgets.left(sContentType, 254));
2213: oStmt.setString(5, Gadgets.left(sContentID, 254));
2214: oStmt.setString(6, Gadgets.left(sMessageID, 254));
2215: oStmt.setString(7, Gadgets.left(sDisposition, 100));
2216: oStmt.setObject(8, iSize, Types.INTEGER);
2217:
2218: oStmt.setString(9, Gadgets.left(sContentMD5, 32));
2219: oStmt.setString(10, Gadgets.left(sDescription, 254));
2220: oStmt.setString(11, Gadgets.left(sFileName, 254));
2221: oStmt.setString(12, Gadgets.left(sEncoding, 16));
2222: oStmt.setString(13, Gadgets.left(sSubject, 254));
2223: oStmt.setTimestamp(14, tsSent);
2224: oStmt.setTimestamp(15, tsReceived);
2225:
2226: if (null == oFrom) {
2227: oStmt.setNull(16, Types.VARCHAR);
2228: oStmt.setNull(17, Types.VARCHAR);
2229: } else {
2230: oStmt.setString(16, Gadgets.left(oFrom.getAddress(),
2231: 254));
2232: oStmt.setString(17, Gadgets.left(oFrom.getPersonal(),
2233: 254));
2234: }
2235:
2236: if (null == oReply)
2237: oStmt.setNull(18, Types.VARCHAR);
2238: else
2239: oStmt.setString(18, Gadgets.left(oReply.getAddress(),
2240: 254));
2241:
2242: Address[] aRecipients;
2243: String sRecipientName;
2244:
2245: aRecipients = oTo;
2246: if (null != aRecipients)
2247: if (aRecipients.length == 0)
2248: aRecipients = null;
2249:
2250: if (null != aRecipients) {
2251: sRecipientName = ((InternetAddress) aRecipients[0])
2252: .getPersonal();
2253: if (null == sRecipientName)
2254: sRecipientName = ((InternetAddress) aRecipients[0])
2255: .getAddress();
2256: oStmt.setString(19, Gadgets.left(sRecipientName, 254));
2257: } else {
2258: aRecipients = oCC;
2259: if (null != aRecipients) {
2260: if (aRecipients.length > 0) {
2261: sRecipientName = ((InternetAddress) aRecipients[0])
2262: .getPersonal();
2263: if (null == sRecipientName)
2264: sRecipientName = ((InternetAddress) aRecipients[0])
2265: .getAddress();
2266: oStmt.setString(19, Gadgets.left(
2267: sRecipientName, 254));
2268: } else
2269: oStmt.setNull(19, Types.VARCHAR);
2270: } else {
2271: aRecipients = oBCC;
2272: if (null != aRecipients) {
2273: if (aRecipients.length > 0) {
2274: sRecipientName = ((InternetAddress) aRecipients[0])
2275: .getPersonal();
2276: if (null == sRecipientName)
2277: sRecipientName = ((InternetAddress) aRecipients[0])
2278: .getAddress();
2279: oStmt.setString(19, Gadgets.left(
2280: sRecipientName, 254));
2281: } else
2282: oStmt.setNull(19, Types.VARCHAR);
2283: } else {
2284: oStmt.setNull(19, Types.VARCHAR);
2285: } // fi (MimeMessage.RecipientType.BCC)
2286: } // fi (MimeMessage.RecipientType.CC)
2287: } // fi (MimeMessage.RecipientType.TO)
2288:
2289: if (null == sPriority)
2290: oStmt.setNull(20, Types.VARCHAR);
2291: else
2292: oStmt.setString(20, sPriority);
2293:
2294: // For Oracle insert flags in NUMBER columns and message body in a BLOB column.
2295: // for any other RDBMS use SMALLINT columns for Flags and a LONGVARBINARY column for the body.
2296:
2297: dPgMessage = getNextMessage();
2298:
2299: if (oConn.getDataBaseProduct() == JDCConnection.DBMS_ORACLE) {
2300: if (DebugFile.trace)
2301: DebugFile
2302: .writeln("PreparedStatement.setBigDecimal(21, ...)");
2303:
2304: oStmt.setBigDecimal(21, new BigDecimal(oFlgs
2305: .contains(Flags.Flag.ANSWERED) ? "1" : "0"));
2306: oStmt.setBigDecimal(22, new BigDecimal(oFlgs
2307: .contains(Flags.Flag.DELETED) ? "1" : "0"));
2308: oStmt.setBigDecimal(23, new BigDecimal(0));
2309: oStmt.setBigDecimal(24, new BigDecimal(oFlgs
2310: .contains(Flags.Flag.FLAGGED) ? "1" : "0"));
2311: oStmt.setBigDecimal(25, new BigDecimal(oFlgs
2312: .contains(Flags.Flag.RECENT) ? "1" : "0"));
2313: oStmt.setBigDecimal(26, new BigDecimal(oFlgs
2314: .contains(Flags.Flag.SEEN) ? "1" : "0"));
2315: oStmt.setBigDecimal(27, new BigDecimal(bIsSpam ? "1"
2316: : "0"));
2317: oStmt.setBigDecimal(28, dPgMessage);
2318: oStmt.setBigDecimal(29, dPosition);
2319:
2320: if (DebugFile.trace)
2321: DebugFile
2322: .writeln("PreparedStatement.setBinaryStream(30, new ByteArrayInputStream("
2323: + String.valueOf(byOutStrm.size())
2324: + "))");
2325:
2326: if (byOutStrm.size() > 0)
2327: oStmt.setBinaryStream(30, new ByteArrayInputStream(
2328: byOutStrm.toByteArray()), byOutStrm.size());
2329: else
2330: oStmt.setNull(30, Types.LONGVARBINARY);
2331: } else {
2332: if (DebugFile.trace)
2333: DebugFile
2334: .writeln("PreparedStatement.setShort(21, ...)");
2335:
2336: oStmt.setShort(21, (short) (oFlgs
2337: .contains(Flags.Flag.ANSWERED) ? 1 : 0));
2338: oStmt.setShort(22, (short) (oFlgs
2339: .contains(Flags.Flag.DELETED) ? 1 : 0));
2340: oStmt.setShort(23, (short) (0));
2341: oStmt.setShort(24, (short) (oFlgs
2342: .contains(Flags.Flag.FLAGGED) ? 1 : 0));
2343: oStmt.setShort(25, (short) (oFlgs
2344: .contains(Flags.Flag.RECENT) ? 1 : 0));
2345: oStmt.setShort(26, (short) (oFlgs
2346: .contains(Flags.Flag.SEEN) ? 1 : 0));
2347: oStmt.setShort(27, (short) (bIsSpam ? 1 : 0));
2348: oStmt.setBigDecimal(28, dPgMessage);
2349: oStmt.setBigDecimal(29, dPosition);
2350:
2351: if (DebugFile.trace)
2352: DebugFile
2353: .writeln("PreparedStatement.setBinaryStream(30, new ByteArrayInputStream("
2354: + String.valueOf(byOutStrm.size())
2355: + "))");
2356:
2357: if (byOutStrm.size() > 0)
2358: oStmt.setBinaryStream(30, new ByteArrayInputStream(
2359: byOutStrm.toByteArray()), byOutStrm.size());
2360: else
2361: oStmt.setNull(30, Types.LONGVARBINARY);
2362: }
2363:
2364: if (DebugFile.trace)
2365: DebugFile.writeln("Statement.executeUpdate()");
2366:
2367: oStmt.executeUpdate();
2368: oStmt.close();
2369: oStmt = null;
2370:
2371: } catch (SQLException sqle) {
2372: try {
2373: if (null != oStmt)
2374: oStmt.close();
2375: oStmt = null;
2376: } catch (Exception ignore) {
2377: }
2378: try {
2379: if (null != oConn)
2380: oConn.rollback();
2381: } catch (Exception ignore) {
2382: }
2383: throw new MessagingException(DB.k_mime_msgs + " "
2384: + sqle.getMessage(), sqle);
2385: }
2386: if ((iOpenMode & MODE_BLOB) != 0) {
2387: // Deallocate byte array containing message body for freeing memory as soon as possible
2388: try {
2389: byOutStrm.close();
2390: } catch (IOException ignore) {
2391: }
2392: byOutStrm = null;
2393: }
2394:
2395: // *************************************************************************
2396: // Now that we have saved the main message reference proceed to store
2397: // its parts into k_mime_parts
2398:
2399: try {
2400: Object oContent = oMsg.getContent();
2401: if (oContent instanceof MimeMultipart) {
2402: try {
2403: saveMimeParts(oMsg, sMsgCharSeq, sBoundary,
2404: sGuMimeMsg, sMessageID, dPgMessage
2405: .intValue(), 0);
2406: } catch (MessagingException msge) {
2407: // Close Mbox file rollback and re-throw
2408: try {
2409: oConn.rollback();
2410: } catch (Exception ignore) {
2411: }
2412: throw new MessagingException(msge.getMessage(),
2413: msge.getNextException());
2414: }
2415: } // fi (MimeMultipart)
2416: } catch (Exception xcpt) {
2417: try {
2418: oConn.rollback();
2419: } catch (Exception ignore) {
2420: }
2421: throw new MessagingException("MimeMessage.getContent() "
2422: + xcpt.getMessage(), xcpt);
2423: }
2424:
2425: // *************************************************************************
2426: // Store message recipients at k_mime_addrs
2427:
2428: try {
2429: if (oConn.getDataBaseProduct() == JDCConnection.DBMS_MYSQL)
2430: sSQL = "SELECT "
2431: + DB.gu_contact
2432: + ","
2433: + DB.gu_company
2434: + ","
2435: + DB.tx_name
2436: + ","
2437: + DB.tx_surname
2438: + ","
2439: + DB.tx_surname
2440: + " FROM "
2441: + DB.k_member_address
2442: + " WHERE "
2443: + DB.tx_email
2444: + "=? AND "
2445: + DB.gu_workarea
2446: + "=? UNION SELECT "
2447: + DB.gu_user
2448: + ",CONVERT('****************************USER' USING utf8),"
2449: + DB.nm_user + "," + DB.tx_surname1 + ","
2450: + DB.tx_surname2 + " FROM " + DB.k_users
2451: + " WHERE (" + DB.tx_main_email + "=? OR "
2452: + DB.tx_alt_email + "=?) AND " + DB.gu_workarea
2453: + "=?";
2454: else
2455: sSQL = "SELECT " + DB.gu_contact + "," + DB.gu_company
2456: + "," + DB.tx_name + "," + DB.tx_surname + ","
2457: + DB.tx_surname + " FROM "
2458: + DB.k_member_address + " WHERE " + DB.tx_email
2459: + "=? AND " + DB.gu_workarea
2460: + "=? UNION SELECT " + DB.gu_user
2461: + ",'****************************USER',"
2462: + DB.nm_user + "," + DB.tx_surname1 + ","
2463: + DB.tx_surname2 + " FROM " + DB.k_users
2464: + " WHERE (" + DB.tx_main_email + "=? OR "
2465: + DB.tx_alt_email + "=?) AND " + DB.gu_workarea
2466: + "=?";
2467: } catch (SQLException sqle) {
2468: if (DebugFile.trace)
2469: DebugFile.writeln("SQLException " + sqle.getMessage());
2470: sSQL = "SELECT " + DB.gu_contact + "," + DB.gu_company
2471: + "," + DB.tx_name + "," + DB.tx_surname + ","
2472: + DB.tx_surname + " FROM " + DB.k_member_address
2473: + " WHERE " + DB.tx_email + "=? AND "
2474: + DB.gu_workarea + "=? UNION SELECT " + DB.gu_user
2475: + ",'****************************USER',"
2476: + DB.nm_user + "," + DB.tx_surname1 + ","
2477: + DB.tx_surname2 + " FROM " + DB.k_users
2478: + " WHERE (" + DB.tx_main_email + "=? OR "
2479: + DB.tx_alt_email + "=?) AND " + DB.gu_workarea
2480: + "=?";
2481: }
2482:
2483: if (DebugFile.trace)
2484: DebugFile.writeln("Connection.prepareStatement(" + sSQL
2485: + ")");
2486:
2487: PreparedStatement oAddr = null;
2488:
2489: try {
2490: oAddr = oConn.prepareStatement(sSQL,
2491: ResultSet.TYPE_FORWARD_ONLY,
2492: ResultSet.CONCUR_READ_ONLY);
2493: ResultSet oRSet;
2494:
2495: InternetAddress oInetAdr;
2496: String sTxEmail, sGuCompany, sGuContact, sTxName, sTxSurname1, sTxSurname2, sTxPersonal;
2497:
2498: // Get From address and keep them into pFrom properties
2499:
2500: if (oFrom != null) {
2501: oAddr.setString(1, oFrom.getAddress());
2502: oAddr.setString(2, sGuWorkArea);
2503: oAddr.setString(3, oFrom.getAddress());
2504: oAddr.setString(4, oFrom.getAddress());
2505: oAddr.setString(5, sGuWorkArea);
2506:
2507: oRSet = oAddr.executeQuery();
2508: if (oRSet.next()) {
2509: sGuContact = oRSet.getString(1);
2510: if (oRSet.wasNull())
2511: sGuContact = "null";
2512: sGuCompany = oRSet.getString(2);
2513: if (oRSet.wasNull())
2514: sGuCompany = "null";
2515:
2516: if (sGuCompany
2517: .equals("****************************USER")) {
2518: sTxName = oRSet.getString(3);
2519: if (oRSet.wasNull())
2520: sTxName = "";
2521: sTxSurname1 = oRSet.getString(4);
2522: if (oRSet.wasNull())
2523: sTxSurname1 = "";
2524: sTxSurname2 = oRSet.getString(4);
2525: if (oRSet.wasNull())
2526: sTxSurname2 = "";
2527: sTxPersonal = Gadgets.left(
2528: sTxName + " " + sTxSurname1 + " "
2529: + sTxSurname2, 254).replace(
2530: ',', ' ').trim();
2531: } else
2532: sTxPersonal = "null";
2533:
2534: pFrom.put(oFrom.getAddress(), sGuContact + ","
2535: + sGuCompany + "," + sTxPersonal);
2536: } else
2537: pFrom.put(oFrom.getAddress(), "null,null,null");
2538:
2539: oRSet.close();
2540: } // fi (oFrom)
2541:
2542: if (DebugFile.trace)
2543: DebugFile.writeln("from count = " + pFrom.size());
2544:
2545: // Get TO address and keep them into pTo properties
2546:
2547: if (oTo != null) {
2548: for (int t = 0; t < oTo.length; t++) {
2549: oInetAdr = (InternetAddress) oTo[t];
2550: sTxEmail = Gadgets.left(oInetAdr.getAddress(), 254);
2551:
2552: oAddr.setString(1, sTxEmail);
2553: oAddr.setString(2, sGuWorkArea);
2554: oAddr.setString(3, sTxEmail);
2555: oAddr.setString(4, sTxEmail);
2556: oAddr.setString(5, sGuWorkArea);
2557:
2558: oRSet = oAddr.executeQuery();
2559: if (oRSet.next()) {
2560: sGuContact = oRSet.getString(1);
2561: if (oRSet.wasNull())
2562: sGuContact = "null";
2563: sGuCompany = oRSet.getString(2);
2564: if (oRSet.wasNull())
2565: sGuCompany = "null";
2566: if (sGuCompany
2567: .equals("****************************USER")) {
2568: sTxName = oRSet.getString(3);
2569: if (oRSet.wasNull())
2570: sTxName = "";
2571: sTxSurname1 = oRSet.getString(4);
2572: if (oRSet.wasNull())
2573: sTxSurname1 = "";
2574: sTxSurname2 = oRSet.getString(4);
2575: if (oRSet.wasNull())
2576: sTxSurname2 = "";
2577: sTxPersonal = Gadgets.left(
2578: sTxName + " " + sTxSurname1 + " "
2579: + sTxSurname2, 254)
2580: .replace(',', ' ').trim();
2581: } else
2582: sTxPersonal = "null";
2583:
2584: pTo.put(sTxEmail, sGuContact + "," + sGuCompany
2585: + "," + sTxPersonal);
2586: } // fi (oRSet.next())
2587: else
2588: pTo.put(sTxEmail, "null,null,null");
2589:
2590: oRSet.close();
2591: } // next (t)
2592: } // fi (oTo)
2593:
2594: if (DebugFile.trace)
2595: DebugFile.writeln("to count = " + pTo.size());
2596:
2597: // Get CC address and keep them into pTo properties
2598:
2599: if (oCC != null) {
2600: for (int c = 0; c < oCC.length; c++) {
2601: oInetAdr = (InternetAddress) oCC[c];
2602: sTxEmail = Gadgets.left(oInetAdr.getAddress(), 254);
2603:
2604: oAddr.setString(1, sTxEmail);
2605: oAddr.setString(2, sGuWorkArea);
2606: oAddr.setString(3, sTxEmail);
2607: oAddr.setString(4, sTxEmail);
2608: oAddr.setString(5, sGuWorkArea);
2609:
2610: oRSet = oAddr.executeQuery();
2611: if (oRSet.next()) {
2612: sGuContact = oRSet.getString(1);
2613: if (oRSet.wasNull())
2614: sGuContact = "null";
2615: sGuCompany = oRSet.getString(2);
2616: if (oRSet.wasNull())
2617: sGuCompany = "null";
2618: if (sGuCompany
2619: .equals("****************************USER")) {
2620: sTxName = oRSet.getString(3);
2621: if (oRSet.wasNull())
2622: sTxName = "";
2623: sTxSurname1 = oRSet.getString(4);
2624: if (oRSet.wasNull())
2625: sTxSurname1 = "";
2626: sTxSurname2 = oRSet.getString(4);
2627: if (oRSet.wasNull())
2628: sTxSurname2 = "";
2629: sTxPersonal = Gadgets.left(
2630: sTxName + " " + sTxSurname1 + " "
2631: + sTxSurname2, 254)
2632: .replace(',', ' ').trim();
2633: } else
2634: sTxPersonal = "null";
2635:
2636: pCC.put(sTxEmail, sGuContact + "," + sGuCompany
2637: + "," + sTxPersonal);
2638: } // fi (oRSet.next())
2639: else
2640: pCC.put(sTxEmail, "null,null,null");
2641:
2642: oRSet.close();
2643: } // next (c)
2644: } // fi (oCC)
2645:
2646: if (DebugFile.trace)
2647: DebugFile.writeln("cc count = " + pCC.size());
2648:
2649: // Get BCC address and keep them into pTo properties
2650:
2651: if (oBCC != null) {
2652: for (int b = 0; b < oBCC.length; b++) {
2653: oInetAdr = (InternetAddress) oBCC[b];
2654: sTxEmail = Gadgets.left(oInetAdr.getAddress(), 254);
2655:
2656: oAddr.setString(1, sTxEmail);
2657: oAddr.setString(2, sGuWorkArea);
2658: oAddr.setString(3, sTxEmail);
2659: oAddr.setString(4, sTxEmail);
2660: oAddr.setString(5, sGuWorkArea);
2661:
2662: oRSet = oAddr.executeQuery();
2663: if (oRSet.next()) {
2664: sGuContact = oRSet.getString(1);
2665: if (oRSet.wasNull())
2666: sGuContact = "null";
2667: sGuCompany = oRSet.getString(2);
2668: if (oRSet.wasNull())
2669: sGuCompany = "null";
2670: if (sGuCompany
2671: .equals("****************************USER")) {
2672: sTxName = oRSet.getString(3);
2673: if (oRSet.wasNull())
2674: sTxName = "";
2675: sTxSurname1 = oRSet.getString(4);
2676: if (oRSet.wasNull())
2677: sTxSurname1 = "";
2678: sTxSurname2 = oRSet.getString(4);
2679: if (oRSet.wasNull())
2680: sTxSurname2 = "";
2681: sTxPersonal = Gadgets.left(
2682: sTxName + " " + sTxSurname1 + " "
2683: + sTxSurname2, 254)
2684: .replace(',', ' ').trim();
2685: } else
2686: sTxPersonal = "null";
2687:
2688: pBCC.put(sTxEmail, sGuContact + ","
2689: + sGuCompany);
2690: } // fi (oRSet.next())
2691: else
2692: pBCC.put(sTxEmail, "null,null,null");
2693:
2694: oRSet.close();
2695: } // next (b)
2696: } // fi (oCBB)
2697:
2698: if (DebugFile.trace)
2699: DebugFile.writeln("bcc count = " + pBCC.size());
2700:
2701: oAddr.close();
2702:
2703: sSQL = "INSERT INTO "
2704: + DB.k_inet_addrs
2705: + " (gu_mimemsg,id_message,tx_email,tp_recipient,gu_user,gu_contact,gu_company,tx_personal) VALUES ('"
2706: + sGuMimeMsg + "',?,?,?,?,?,?,?)";
2707:
2708: if (DebugFile.trace)
2709: DebugFile.writeln("Connection.prepareStatement(" + sSQL
2710: + ")");
2711:
2712: oStmt = oConn.prepareStatement(sSQL);
2713:
2714: java.util.Enumeration oMailEnum;
2715: String[] aRecipient;
2716:
2717: if (!pFrom.isEmpty()) {
2718: oMailEnum = pFrom.keys();
2719: while (oMailEnum.hasMoreElements()) {
2720: oStmt.setString(1, sMessageID);
2721: sTxEmail = (String) oMailEnum.nextElement();
2722: if (DebugFile.trace)
2723: DebugFile.writeln("processing mail address "
2724: + sTxEmail);
2725: aRecipient = Gadgets.split(pFrom
2726: .getProperty(sTxEmail), ',');
2727:
2728: oStmt.setString(2, sTxEmail);
2729: oStmt.setString(3, "from");
2730:
2731: if (aRecipient[0].equals("null")
2732: && aRecipient[1].equals("null")) {
2733: oStmt.setNull(4, Types.CHAR);
2734: oStmt.setNull(5, Types.CHAR);
2735: oStmt.setNull(6, Types.CHAR);
2736: } else if (aRecipient[1]
2737: .equals("****************************USER")) {
2738: oStmt.setString(4, aRecipient[0]);
2739: oStmt.setNull(5, Types.CHAR);
2740: oStmt.setNull(6, Types.CHAR);
2741: } else {
2742: oStmt.setNull(4, Types.CHAR);
2743: oStmt.setString(5,
2744: aRecipient[0].equals("null") ? null
2745: : aRecipient[0]);
2746: oStmt.setString(6,
2747: aRecipient[1].equals("null") ? null
2748: : aRecipient[1]);
2749: }
2750:
2751: if (aRecipient[2].equals("null"))
2752: oStmt.setNull(7, Types.VARCHAR);
2753: else
2754: oStmt.setString(7, aRecipient[2]);
2755:
2756: if (DebugFile.trace)
2757: DebugFile.writeln("Statement.executeUpdate()");
2758: oStmt.executeUpdate();
2759: } // wend
2760: } // fi (from)
2761:
2762: if (!pTo.isEmpty()) {
2763: oMailEnum = pTo.keys();
2764: while (oMailEnum.hasMoreElements()) {
2765: oStmt.setString(1, sMessageID);
2766: sTxEmail = (String) oMailEnum.nextElement();
2767: aRecipient = Gadgets.split(pTo
2768: .getProperty(sTxEmail), ',');
2769:
2770: oStmt.setString(2, sTxEmail);
2771: oStmt.setString(3, "to");
2772:
2773: if (aRecipient[0].equals("null")
2774: && aRecipient[1].equals("null")) {
2775: oStmt.setNull(4, Types.CHAR);
2776: oStmt.setNull(5, Types.CHAR);
2777: oStmt.setNull(6, Types.CHAR);
2778: } else if (aRecipient[1]
2779: .equals("****************************USER")) {
2780: oStmt.setString(4, aRecipient[0]);
2781: oStmt.setNull(5, Types.CHAR);
2782: oStmt.setNull(6, Types.CHAR);
2783: } else {
2784: oStmt.setNull(4, Types.CHAR);
2785: oStmt.setString(5,
2786: aRecipient[0].equals("null") ? null
2787: : aRecipient[0]);
2788: oStmt.setString(6,
2789: aRecipient[1].equals("null") ? null
2790: : aRecipient[1]);
2791: }
2792:
2793: if (aRecipient[2].equals("null"))
2794: oStmt.setNull(7, Types.VARCHAR);
2795: else
2796: oStmt.setString(7, aRecipient[2]);
2797:
2798: if (DebugFile.trace)
2799: DebugFile.writeln("Statement.executeUpdate()");
2800:
2801: oStmt.executeUpdate();
2802: } // wend
2803: } // fi (to)
2804:
2805: if (!pCC.isEmpty()) {
2806: oMailEnum = pCC.keys();
2807: while (oMailEnum.hasMoreElements()) {
2808: oStmt.setString(1, sMessageID);
2809: sTxEmail = (String) oMailEnum.nextElement();
2810: aRecipient = Gadgets.split(pCC
2811: .getProperty(sTxEmail), ',');
2812:
2813: oStmt.setString(2, sTxEmail);
2814: oStmt.setString(3, "cc");
2815:
2816: if (aRecipient[0].equals("null")
2817: && aRecipient[1].equals("null")) {
2818: oStmt.setNull(4, Types.CHAR);
2819: oStmt.setNull(5, Types.CHAR);
2820: oStmt.setNull(6, Types.CHAR);
2821: } else if (aRecipient[1]
2822: .equals("****************************USER")) {
2823: oStmt.setString(4, aRecipient[0]);
2824: oStmt.setString(5, null);
2825: oStmt.setString(6, null);
2826: } else {
2827: oStmt.setString(4, null);
2828: oStmt.setString(5,
2829: aRecipient[0].equals("null") ? null
2830: : aRecipient[0]);
2831: oStmt.setString(6,
2832: aRecipient[1].equals("null") ? null
2833: : aRecipient[1]);
2834: }
2835:
2836: if (aRecipient[2].equals("null"))
2837: oStmt.setNull(7, Types.VARCHAR);
2838: else
2839: oStmt.setString(7, aRecipient[2]);
2840:
2841: if (DebugFile.trace)
2842: DebugFile.writeln("Statement.executeUpdate()");
2843:
2844: oStmt.executeUpdate();
2845: } // wend
2846: } // fi (cc)
2847:
2848: if (!pBCC.isEmpty()) {
2849: oMailEnum = pBCC.keys();
2850: while (oMailEnum.hasMoreElements()) {
2851: oStmt.setString(1, sMessageID);
2852: sTxEmail = (String) oMailEnum.nextElement();
2853: aRecipient = Gadgets.split(pBCC
2854: .getProperty(sTxEmail), ',');
2855:
2856: oStmt.setString(2, sTxEmail);
2857: oStmt.setString(3, "bcc");
2858:
2859: if (aRecipient[0].equals("null")
2860: && aRecipient[1].equals("null")) {
2861: oStmt.setNull(4, Types.CHAR);
2862: oStmt.setNull(5, Types.CHAR);
2863: oStmt.setNull(6, Types.CHAR);
2864: } else if (aRecipient[1]
2865: .equals("****************************USER")) {
2866: oStmt.setString(4, aRecipient[0]);
2867: oStmt.setNull(5, Types.CHAR);
2868: oStmt.setNull(6, Types.CHAR);
2869: } else {
2870: oStmt.setNull(4, Types.CHAR);
2871: oStmt.setString(5,
2872: aRecipient[0].equals("null") ? null
2873: : aRecipient[0]);
2874: oStmt.setString(6,
2875: aRecipient[1].equals("null") ? null
2876: : aRecipient[1]);
2877: }
2878:
2879: if (aRecipient[2].equals("null"))
2880: oStmt.setNull(7, Types.VARCHAR);
2881: else
2882: oStmt.setString(7, aRecipient[2]);
2883:
2884: oStmt.executeUpdate();
2885: } // wend
2886: } // fi (bcc)
2887:
2888: oStmt.close();
2889: oStmt = null;
2890:
2891: oStmt = oConn.prepareStatement("UPDATE " + DB.k_categories
2892: + " SET " + DB.len_size + "=" + DB.len_size + "+"
2893: + String.valueOf(iSize) + " WHERE "
2894: + DB.gu_category + "=?");
2895: oStmt.setString(1, getCategory().getString(DB.gu_category));
2896: oStmt.executeUpdate();
2897: oStmt.close();
2898: oStmt = null;
2899:
2900: } catch (SQLException sqle) {
2901: try {
2902: if (null != oStmt)
2903: oStmt.close();
2904: oStmt = null;
2905: } catch (Exception ignore) {
2906: }
2907: try {
2908: if (null != oAddr)
2909: oAddr.close();
2910: oAddr = null;
2911: } catch (Exception ignore) {
2912: }
2913: if (DebugFile.trace)
2914: DebugFile.decIdent();
2915: throw new MessagingException(sqle.getMessage(), sqle);
2916: }
2917: if (DebugFile.trace) {
2918: DebugFile.decIdent();
2919: DebugFile.writeln("End DBFolder.indexMessage()");
2920: }
2921: } // indexMessage
2922:
2923: // ---------------------------------------------------------------------------
2924:
2925: private void checkAppendPreconditions()
2926: throws FolderClosedException, StoreClosedException {
2927: // *************************************************************************
2928: // If DBStore is not connected to the database then raise an exception
2929:
2930: if (!((DBStore) getStore()).isConnected()) {
2931: if (DebugFile.trace)
2932: DebugFile.decIdent();
2933: throw new StoreClosedException(getStore(),
2934: "Store is not connected");
2935: }
2936:
2937: // *************************************************************************
2938: // If Folder is not opened is read-write mode then raise an exception
2939: if (0 == (iOpenMode & READ_WRITE)) {
2940: if (DebugFile.trace)
2941: DebugFile.decIdent();
2942: throw new FolderClosedException(this ,
2943: "Folder is not open is READ_WRITE mode");
2944: }
2945:
2946: if ((0 == (iOpenMode & MODE_MBOX))
2947: && (0 == (iOpenMode & MODE_BLOB))) {
2948: if (DebugFile.trace)
2949: DebugFile.decIdent();
2950: throw new FolderClosedException(this ,
2951: "Folder is not open in MBOX nor BLOB mode");
2952: }
2953: } // checkAppendPreconditions
2954:
2955: // ---------------------------------------------------------------------------
2956:
2957: /**
2958: * Get Message body taking into account its exact MimeMessage subclass
2959: * @param oMsg MimeMessage
2960: * @return ByteArrayOutputStream
2961: * @throws MessagingException
2962: * @throws IOException
2963: */
2964: private static ByteArrayOutputStream getBodyAsStream(
2965: MimeMessage oMsg) throws MessagingException, IOException {
2966: MimePart oText = null;
2967: ByteArrayOutputStream byStrm;
2968:
2969: if (DebugFile.trace) {
2970: DebugFile
2971: .writeln("Begin DBFolder.getBodyAsStream([MimeMessage])");
2972: DebugFile.incIdent();
2973: if (null != oMsg)
2974: DebugFile.writeln(oMsg.getClass().getName());
2975: else
2976: DebugFile.writeln("MimeMessage is null");
2977: }
2978:
2979: if (oMsg.getClass().getName().equals(
2980: "com.knowgate.hipermail.DBMimeMessage"))
2981: // If appended message is a DBMimeMessage then use DBMimeMessage.getBody()
2982: // for getting HTML text part or plain text part of the MULTIPART/ALTERNATIVE
2983: oText = ((DBMimeMessage) oMsg).getBody();
2984: else {
2985: // Else if the appended message is a MimeMessage use standard Java Mail getBody() method
2986: oText = new DBMimeMessage(oMsg).getBody();
2987: } // fi
2988:
2989: if (DebugFile.trace) {
2990: DebugFile.writeln("MimePart encoding is "
2991: + oText.getEncoding());
2992: DebugFile.writeln("MimePart size is "
2993: + String.valueOf(oText.getSize()));
2994: }
2995:
2996: // *************************************************************************
2997: // Initialize a byte array for containing the message body
2998:
2999: if (DebugFile.trace)
3000: DebugFile
3001: .writeln("ByteArrayOutputStream byOutStrm = new ByteArrayOutputStream("
3002: + String
3003: .valueOf(oText.getSize() > 0 ? oText
3004: .getSize()
3005: : 8192) + ")");
3006:
3007: byStrm = new ByteArrayOutputStream(oText.getSize() > 0 ? oText
3008: .getSize() : 8192);
3009: oText.writeTo(byStrm);
3010:
3011: if (DebugFile.trace) {
3012: DebugFile.decIdent();
3013: DebugFile.writeln("End DBFolder.getBodyAsStream() : "
3014: + Gadgets.left(new String(byStrm.toByteArray()),
3015: 100));
3016: }
3017:
3018: return byStrm;
3019: } // getBodyAsStream
3020:
3021: // ---------------------------------------------------------------------------
3022:
3023: /**
3024: *
3025: * @param oMsg MimeMessage
3026: * @return String
3027: * @throws FolderClosedException
3028: * @throws StoreClosedException
3029: * @throws MessagingException
3030: * @throws ArrayIndexOutOfBoundsException
3031: * @throws NullPointerException if oMsg is <b>null</b>
3032: */
3033: public String appendMessage(MimeMessage oMsg)
3034: throws FolderClosedException, StoreClosedException,
3035: MessagingException, ArrayIndexOutOfBoundsException,
3036: NullPointerException {
3037:
3038: if (oMsg == null) {
3039: throw new NullPointerException(
3040: "DBFolder.appendMessage() MimeMessage parameter cannot be null");
3041: }
3042:
3043: if (DebugFile.trace) {
3044: DebugFile.writeln("Begin DBFolder.appendMessage("
3045: + oMsg.getClass().getName() + ")");
3046: DebugFile.incIdent();
3047: }
3048:
3049: // *************************************************************************
3050: // If Message does not have a GUID then assign a new one.
3051: // Message GUID is not the same as MimeMessage Id.
3052:
3053: String gu_mimemsg;
3054: if (oMsg.getClass().getName().equals(
3055: "com.knowgate.hipermail.DBMimeMessage")) {
3056: gu_mimemsg = ((DBMimeMessage) oMsg).getMessageGuid();
3057: if (((DBMimeMessage) oMsg).getFolder() == null)
3058: ((DBMimeMessage) oMsg).setFolder(this );
3059: } else {
3060: gu_mimemsg = Gadgets.generateUUID();
3061: }
3062:
3063: checkAppendPreconditions();
3064:
3065: // *************************************************************************
3066: // Mails are assigned by default to the same WorkArea as their recipient user
3067:
3068: String gu_workarea = ((DBStore) getStore()).getUser()
3069: .getString(DB.gu_workarea);
3070:
3071: // *************************************************************************
3072: // Gather some MimeMessage headers that will be later written at the database
3073:
3074: MboxFile oMBox = null;
3075: ByteArrayOutputStream byOutStrm = null;
3076:
3077: try {
3078: long lPosition = -1;
3079: HeadersHelper oHlpr = new HeadersHelper(oMsg);
3080: RecipientsHelper oRecps = new RecipientsHelper(oMsg);
3081: String sMessageID = oHlpr.decodeMessageId(gu_mimemsg);
3082: String sMsgCharSeq = DBMimeMessage
3083: .source(oMsg, "ISO8859_1");
3084: if (sMsgCharSeq == null) {
3085: if (DebugFile.trace) {
3086: DebugFile
3087: .writeln("DBFolder.appendMessage() : Original message source is null");
3088: DebugFile.decIdent();
3089: }
3090: throw new NullPointerException(
3091: "DBFolder.appendMessage() : Original message source is null");
3092: } // fi (sMsgCharSeq==null)
3093: String sContentMD5 = oHlpr.getContentMD5();
3094: if (null == sContentMD5)
3095: sContentMD5 = HeadersHelper
3096: .computeContentMD5(sMsgCharSeq.getBytes());
3097: int iSize = ((iOpenMode & MODE_MBOX) != 0) ? sMsgCharSeq
3098: .length() : oMsg.getSize();
3099: Integer oSize = ((iSize >= 0) ? new Integer(iSize) : null);
3100:
3101: byOutStrm = getBodyAsStream(oMsg);
3102:
3103: // *************************************************************************
3104: // Create Mbox file and adquire an exclusive lock on it before start writting on the database
3105:
3106: if ((iOpenMode & MODE_MBOX) != 0) {
3107: if (DebugFile.trace)
3108: DebugFile.writeln("new File("
3109: + Gadgets.chomp(sFolderDir, File.separator)
3110: + oCatg.getStringNull(DB.nm_category,
3111: "null") + ".mbox)");
3112:
3113: File oFile = getFile();
3114: lPosition = oFile.length();
3115:
3116: if (DebugFile.trace)
3117: DebugFile.writeln("message position is "
3118: + String.valueOf(lPosition));
3119:
3120: oMBox = new MboxFile(oFile, MboxFile.READ_WRITE);
3121:
3122: /*
3123: if (DebugFile.trace && (oMsg.getMessageID()!=null)) {
3124: if (oMsg.getMessageID().trim().length()>0) {
3125: int iMsgCount = oMBox.getMessageCount();
3126: for (int m=0; m<iMsgCount; m++) {
3127: CharSequence oCharSeq = oMBox.getMessage(m);
3128: if (oCharSeq.toString().indexOf(oMsg.getMessageID())>0) {
3129: throw new MessagingException("File " + oFile.getName() + " already contains message " + oMsg.getMessageID() + " at index " + String.valueOf(m));
3130: }
3131: }
3132: }
3133: } // fi (DebugFile.trace)
3134: */
3135: } // fi (MODE_MBOX)
3136:
3137: indexMessage(gu_mimemsg, gu_workarea, oMsg, oSize,
3138: ((iOpenMode & MODE_MBOX) != 0) ? new BigDecimal(
3139: lPosition) : null, oHlpr.getContentType(),
3140: oHlpr.getContentID(), sMessageID, oHlpr
3141: .getDisposition(), sContentMD5, oHlpr
3142: .getDescription(), oHlpr.getFileName(),
3143: oHlpr.getEncoding(), oHlpr.getSubject(), oHlpr
3144: .getPriority(), oHlpr.getFlags(), oHlpr
3145: .getSentTimestamp(), oHlpr
3146: .getReceivedTimestamp(), RecipientsHelper
3147: .getFromAddress(oMsg), RecipientsHelper
3148: .getReplyAddress(oMsg), oRecps
3149: .getRecipients(Message.RecipientType.TO),
3150: oRecps.getRecipients(Message.RecipientType.CC),
3151: oRecps.getRecipients(Message.RecipientType.BCC),
3152: oHlpr.isSpam(), byOutStrm, sMsgCharSeq);
3153:
3154: if ((iOpenMode & MODE_MBOX) != 0) {
3155: if (DebugFile.trace)
3156: DebugFile.writeln("MboxFile.appendMessage("
3157: + (oMsg.getContentID() != null ? oMsg
3158: .getContentID() : "") + ")");
3159:
3160: oMBox.appendMessage(sMsgCharSeq);
3161:
3162: oMBox.close();
3163: oMBox = null;
3164:
3165: if (DebugFile.trace && ((iOpenMode & MODE_MBOX) != 0)) {
3166: oMBox = new MboxFile(getFile(), MboxFile.READ_ONLY);
3167: int iMsgCount = oMBox.getMessageCount();
3168: CharSequence sWrittenMsg = oMBox
3169: .getMessage(iMsgCount - 1);
3170: if (!sMsgCharSeq.equals(sWrittenMsg.toString())) {
3171: DebugFile
3172: .writeln("Readed message source does not match with original message source");
3173: DebugFile.writeln("**** Original Message ****");
3174: DebugFile.writeln(sMsgCharSeq);
3175: DebugFile.writeln("**** Readed Message ****");
3176: DebugFile.writeln(sWrittenMsg.toString());
3177: }
3178: oMBox.close();
3179: } // fi
3180:
3181: } // fi (MODE_MBOX)
3182:
3183: byOutStrm.close();
3184: byOutStrm = null;
3185:
3186: if (DebugFile.trace)
3187: DebugFile.writeln("Connection.commit()");
3188: oConn.commit();
3189:
3190: } catch (OutOfMemoryError oom) {
3191: try {
3192: if (null != byOutStrm)
3193: byOutStrm.close();
3194: } catch (Exception ignore) {
3195: }
3196: try {
3197: if (null != oMBox)
3198: oMBox.close();
3199: } catch (Exception ignore) {
3200: }
3201: try {
3202: if (null != oConn)
3203: oConn.rollback();
3204: } catch (Exception ignore) {
3205: }
3206: if (DebugFile.trace)
3207: DebugFile.decIdent();
3208: throw new MessagingException("OutOfMemoryError "
3209: + oom.getMessage());
3210: } catch (Exception xcpt) {
3211: try {
3212: if (null != byOutStrm)
3213: byOutStrm.close();
3214: } catch (Exception ignore) {
3215: }
3216: try {
3217: if (oMBox != null)
3218: oMBox.close();
3219: } catch (Exception ignore) {
3220: }
3221: try {
3222: if (null != oConn)
3223: oConn.rollback();
3224: } catch (Exception ignore) {
3225: }
3226: if (DebugFile.trace)
3227: DebugFile.decIdent();
3228: throw new MessagingException(xcpt.getClass().getName()
3229: + " " + xcpt.getMessage(), xcpt);
3230: }
3231:
3232: // End Gathering MimeMessage headers
3233: // *************************************************************************
3234:
3235: if (DebugFile.trace) {
3236: DebugFile.decIdent();
3237: DebugFile.writeln("End DBFolder.appendMessage() : "
3238: + gu_mimemsg);
3239: }
3240: return gu_mimemsg;
3241: } // appendMessage
3242:
3243: // ---------------------------------------------------------------------------
3244:
3245: public Message getMessage(int msgnum) throws MessagingException {
3246: return getMessage(String.valueOf(msgnum), 3);
3247: }
3248:
3249: // ---------------------------------------------------------------------------
3250:
3251: public DBMimeMessage getMessageByGuid(String sMsgGuid)
3252: throws MessagingException {
3253: return (DBMimeMessage) getMessage(sMsgGuid, 1);
3254: }
3255:
3256: // ---------------------------------------------------------------------------
3257:
3258: public DBMimeMessage getMessageByID(String sMsgId)
3259: throws MessagingException {
3260: return (DBMimeMessage) getMessage(sMsgId, 2);
3261: }
3262:
3263: // ---------------------------------------------------------------------------
3264:
3265: public int getMessageCount() throws FolderClosedException,
3266: MessagingException {
3267:
3268: PreparedStatement oStmt = null;
3269: ResultSet oRSet = null;
3270: Object oCount;
3271:
3272: if (DebugFile.trace) {
3273: DebugFile.writeln("Begin DBFolder.getMessageCount()");
3274: DebugFile.incIdent();
3275: }
3276:
3277: // *************************************************************************
3278: // If Folder is not opened then raise an exception
3279: if (!isOpen()) {
3280: if (DebugFile.trace)
3281: DebugFile.decIdent();
3282: throw new javax.mail.FolderClosedException(this ,
3283: "Folder is closed");
3284: }
3285:
3286: try {
3287: oStmt = getConnection().prepareStatement(
3288: "SELECT COUNT(*) FROM " + DB.k_mime_msgs
3289: + " WHERE " + DB.gu_category + "=?",
3290: ResultSet.TYPE_FORWARD_ONLY,
3291: ResultSet.CONCUR_READ_ONLY);
3292: oStmt.setString(1, oCatg
3293: .getStringNull(DB.gu_category, null));
3294: oRSet = oStmt.executeQuery();
3295: oRSet.next();
3296: oCount = oRSet.getObject(1);
3297: oRSet.close();
3298: oRSet = null;
3299: oStmt.close();
3300: oStmt = null;
3301: } catch (SQLException sqle) {
3302: oCount = new Integer(0);
3303: try {
3304: if (null != oRSet)
3305: oRSet.close();
3306: } catch (Exception ignore) {
3307: }
3308: try {
3309: if (null != oStmt)
3310: oStmt.close();
3311: } catch (Exception ignore) {
3312: }
3313: throw new MessagingException(sqle.getMessage(), sqle);
3314: }
3315:
3316: if (DebugFile.trace) {
3317: DebugFile.decIdent();
3318: DebugFile.writeln("End DBFolder.getMessageCount() : "
3319: + oCount.toString());
3320: }
3321:
3322: return Integer.parseInt(oCount.toString());
3323: } // getMessageCount
3324:
3325: // ---------------------------------------------------------------------------
3326:
3327: public Folder getParent() throws MessagingException {
3328: if (DebugFile.trace) {
3329: DebugFile.writeln("Begin DBFolder.getParent()");
3330: DebugFile.incIdent();
3331: }
3332:
3333: if (DebugFile.trace) {
3334: DebugFile.decIdent();
3335: DebugFile.writeln("End DBFolder.getParent() : null");
3336: }
3337:
3338: return null;
3339: } // getParent
3340:
3341: // ---------------------------------------------------------------------------
3342:
3343: public Flags getPermanentFlags() {
3344: Flags oFlgs = new Flags();
3345: oFlgs.add(Flags.Flag.DELETED);
3346: oFlgs.add(Flags.Flag.ANSWERED);
3347: oFlgs.add(Flags.Flag.DRAFT);
3348: oFlgs.add(Flags.Flag.SEEN);
3349: oFlgs.add(Flags.Flag.RECENT);
3350: oFlgs.add(Flags.Flag.FLAGGED);
3351:
3352: return oFlgs;
3353: }
3354:
3355: // ---------------------------------------------------------------------------
3356:
3357: public char getSeparator() throws MessagingException {
3358: return '/';
3359: }
3360:
3361: // ---------------------------------------------------------------------------
3362:
3363: public Folder[] list(String pattern) throws MessagingException {
3364: return null;
3365: }
3366:
3367: // ---------------------------------------------------------------------------
3368:
3369: public int getType() throws MessagingException {
3370: return iOpenMode;
3371: }
3372:
3373: // ---------------------------------------------------------------------------
3374:
3375: public boolean isOpen() {
3376: return (iOpenMode != 0);
3377: }
3378:
3379: // ---------------------------------------------------------------------------
3380:
3381: /**
3382: * <p>Get message GUID, Id, Number, Subject, From and Reply-To from k_mime_msgs table</p>
3383: * This method is mainly used for testing whether or not a message is already present at current folder.
3384: * @param sMsgId String GUID or Id of message to be rerieved
3385: * @return Properties {gu_mimemsg, id_message, pg_message, tx_subject, tx_email_from, tx_email_reply, nm_from }
3386: * or <b>null</b> if no message with such sMsgId was found referenced at k_mime_msgs
3387: * for current folder
3388: * @throws FolderClosedException
3389: * @throws SQLException
3390: */
3391: public Properties getMessageHeaders(String sMsgId)
3392: throws FolderClosedException, SQLException {
3393:
3394: if (DebugFile.trace) {
3395: DebugFile.writeln("Begin DBFolder.getMessageHeaders()");
3396: DebugFile.incIdent();
3397: }
3398:
3399: // *************************************************************************
3400: // If Folder is not opened then raise an exception
3401: if (!isOpen()) {
3402: if (DebugFile.trace)
3403: DebugFile.decIdent();
3404: throw new javax.mail.FolderClosedException(this ,
3405: "Folder is closed");
3406: }
3407:
3408: Properties oRetVal;
3409: PreparedStatement oStmt;
3410:
3411: if (sMsgId.length() == 32) {
3412: if (DebugFile.trace)
3413: DebugFile.writeln("Connection.prepareStatement(SELECT "
3414: + DB.gu_mimemsg + "," + DB.id_message + ","
3415: + DB.pg_message + "," + DB.tx_subject
3416: + " FROM " + DB.k_mime_msgs + " WHERE "
3417: + DB.gu_mimemsg + "='" + sMsgId + "' OR "
3418: + DB.id_message + "='" + sMsgId + "') AND "
3419: + DB.gu_category + "='" + getCategoryGuid()
3420: + "' AND " + DB.bo_deleted + "<>1)");
3421:
3422: oStmt = getConnection().prepareStatement(
3423: "SELECT " + DB.gu_mimemsg + "," + DB.id_message
3424: + "," + DB.pg_message + "," + DB.tx_subject
3425: + "," + DB.tx_email_from + ","
3426: + DB.tx_email_reply + "," + DB.nm_from
3427: + " FROM " + DB.k_mime_msgs + " WHERE ("
3428: + DB.gu_mimemsg + "=? OR " + DB.id_message
3429: + "=?) AND " + DB.gu_category + "=? AND "
3430: + DB.bo_deleted + "<>1",
3431: ResultSet.TYPE_FORWARD_ONLY,
3432: ResultSet.CONCUR_READ_ONLY);
3433: oStmt.setString(1, sMsgId);
3434: oStmt.setString(2, sMsgId);
3435: oStmt.setString(3, getCategoryGuid());
3436: } else {
3437: if (DebugFile.trace)
3438: DebugFile.writeln("Connection.prepareStatement(SELECT "
3439: + DB.gu_mimemsg + "," + DB.id_message + ","
3440: + DB.pg_message + "," + DB.tx_subject + ","
3441: + DB.tx_email_from + "," + DB.tx_email_reply
3442: + "," + DB.nm_from + " FROM " + DB.k_mime_msgs
3443: + " WHERE " + DB.id_message + "='" + sMsgId
3444: + "' AND " + DB.gu_category + "='"
3445: + getCategoryGuid() + "' AND " + DB.bo_deleted
3446: + "<>1)");
3447:
3448: oStmt = getConnection().prepareStatement(
3449: "SELECT " + DB.gu_mimemsg + "," + DB.id_message
3450: + "," + DB.pg_message + "," + DB.tx_subject
3451: + "," + DB.tx_email_from + ","
3452: + DB.tx_email_reply + "," + DB.nm_from
3453: + " FROM " + DB.k_mime_msgs + " WHERE "
3454: + DB.id_message + "=? AND "
3455: + DB.gu_category + "=? AND "
3456: + DB.bo_deleted + "<>1",
3457: ResultSet.TYPE_FORWARD_ONLY,
3458: ResultSet.CONCUR_READ_ONLY);
3459: oStmt.setString(1, sMsgId);
3460: oStmt.setString(2, getCategoryGuid());
3461: } // fi (sMsgId.length()==32)
3462:
3463: ResultSet oRSet = oStmt.executeQuery();
3464:
3465: if (oRSet.next()) {
3466: oRetVal = new Properties();
3467: String s;
3468: BigDecimal d;
3469: s = oRSet.getString(1);
3470: if (DebugFile.trace)
3471: DebugFile.writeln("gu_mimemsg=" + s);
3472: oRetVal.put(DB.gu_mimemsg, s);
3473: s = oRSet.getString(2);
3474: if (!oRSet.wasNull())
3475: oRetVal.put(DB.id_message, s);
3476: d = oRSet.getBigDecimal(3);
3477: if (!oRSet.wasNull())
3478: oRetVal.put(DB.pg_message, d.toString());
3479: s = oRSet.getString(4);
3480: if (!oRSet.wasNull())
3481: oRetVal.put(DB.tx_subject, s);
3482: s = oRSet.getString(5);
3483: if (!oRSet.wasNull())
3484: oRetVal.put(DB.tx_email_from, s);
3485: s = oRSet.getString(6);
3486: if (!oRSet.wasNull())
3487: oRetVal.put(DB.tx_email_reply, s);
3488: s = oRSet.getString(7);
3489: if (!oRSet.wasNull())
3490: oRetVal.put(DB.nm_from, s);
3491: } else {
3492: if (DebugFile.trace)
3493: DebugFile.writeln("message not found");
3494: oRetVal = null;
3495: }
3496:
3497: oRSet.close();
3498: oStmt.close();
3499:
3500: if (DebugFile.trace) {
3501: DebugFile.decIdent();
3502: if (oRetVal == null)
3503: DebugFile
3504: .writeln("End DBFolder.getMessageHeaders() : null");
3505: else
3506: DebugFile
3507: .writeln("End DBFolder.getMessageHeaders() : Properties["
3508: + String.valueOf(oRetVal.size()) + "]");
3509: }
3510:
3511: return oRetVal;
3512: } // getMessageHeaders
3513:
3514: // ---------------------------------------------------------------------------
3515:
3516: public int importMbox(String sMboxFilePath)
3517: throws FileNotFoundException, IOException,
3518: MessagingException {
3519:
3520: MimeMessage oMsg;
3521: InputStream oMsgStrm;
3522: Session oSession = ((DBStore) getStore()).getSession();
3523: MboxFile oInputMbox = new MboxFile(sMboxFilePath,
3524: MboxFile.READ_ONLY);
3525:
3526: final int iMsgCount = oInputMbox.getMessageCount();
3527:
3528: for (int m = 0; m < iMsgCount; m++) {
3529: oMsgStrm = oInputMbox.getMessageAsStream(m);
3530: oMsg = new MimeMessage(oSession, oMsgStrm);
3531: appendMessage(oMsg);
3532: oMsgStrm.close();
3533: }
3534:
3535: oInputMbox.close();
3536:
3537: return iMsgCount;
3538: } // importMbox
3539:
3540: // ---------------------------------------------------------------------------
3541:
3542: /**
3543: * Delete every message from the index and rebuild it by re-reading the specified MBOX file
3544: * @param sMboxFilePath String Full path to MBOX file
3545: * @throws FileNotFoundException
3546: * @throws IOException
3547: * @throws MessagingException
3548: * @throws SQLException
3549: */
3550: public void reindexMbox(String sMboxFilePath)
3551: throws FileNotFoundException, IOException,
3552: MessagingException, SQLException {
3553:
3554: MimeMessage oMsg;
3555: InputStream oMsgStrm;
3556: int iMsgCount;
3557: HeadersHelper oHlpr;
3558: RecipientsHelper oRecps;
3559: BigDecimal dPgMessage;
3560: String sGuMimeMsg;
3561: String sMessageID;
3562: String sMsgCharSeq;
3563: String sContentMD5;
3564: int iSize;
3565: Integer oSize;
3566: MboxFile oInputMbox = null;
3567:
3568: if (DebugFile.trace) {
3569: DebugFile.writeln("Begin DBFolder.reindexMbox("
3570: + sMboxFilePath + ")");
3571: DebugFile.incIdent();
3572: }
3573:
3574: try {
3575: ByteArrayOutputStream byOutStrm = null;
3576: Session oSession = ((DBStore) getStore()).getSession();
3577: String sGuWorkArea = ((DBStore) getStore()).getUser()
3578: .getString(DB.gu_workarea);
3579: String sGuFolder = getCategoryGuid();
3580: oInputMbox = new MboxFile(sMboxFilePath, MboxFile.READ_ONLY);
3581: DBSubset oMsgs = new DBSubset(DB.k_mime_msgs, DB.gu_mimemsg
3582: + "," + DB.gu_workarea, DB.gu_category + "=?", 1000);
3583: iMsgCount = oMsgs.load(oConn, new Object[] { sGuFolder });
3584:
3585: if (DebugFile.trace)
3586: DebugFile.writeln(String.valueOf(iMsgCount)
3587: + " indexed messages");
3588:
3589: for (int m = 0; m < iMsgCount; m++)
3590: DBMimeMessage.delete(oConn, sGuFolder, oMsgs.getString(
3591: 0, m));
3592:
3593: iMsgCount = oInputMbox.getMessageCount();
3594:
3595: if (DebugFile.trace)
3596: DebugFile.writeln(String.valueOf(iMsgCount)
3597: + " stored messages");
3598:
3599: for (int m = 0; m < iMsgCount; m++) {
3600: sGuMimeMsg = Gadgets.generateUUID();
3601: oMsgStrm = oInputMbox.getMessageAsStream(m);
3602: oMsg = new MimeMessage(oSession, oMsgStrm);
3603: oHlpr = new HeadersHelper(oMsg);
3604: oRecps = new RecipientsHelper(oMsg);
3605: dPgMessage = new BigDecimal(m);
3606: sMessageID = oHlpr.decodeMessageId(sGuMimeMsg);
3607: sMsgCharSeq = DBMimeMessage.source(oMsg, "ISO8859_1");
3608: sContentMD5 = oHlpr.getContentMD5();
3609: if (null == sContentMD5)
3610: sContentMD5 = HeadersHelper
3611: .computeContentMD5(sMsgCharSeq.getBytes());
3612: iSize = ((iOpenMode & MODE_MBOX) != 0) ? sMsgCharSeq
3613: .length() : oMsg.getSize();
3614: oSize = (iSize >= 0 ? new Integer(iSize) : null);
3615: byOutStrm = getBodyAsStream(oMsg);
3616:
3617: indexMessage(
3618: Gadgets.generateUUID(),
3619: sGuWorkArea,
3620: oMsg,
3621: oSize,
3622: ((iOpenMode & MODE_MBOX) != 0) ? new BigDecimal(
3623: oInputMbox.getMessagePosition(m))
3624: : null,
3625: oHlpr.getContentType(),
3626: oHlpr.getContentID(),
3627: sMessageID,
3628: oHlpr.getDisposition(),
3629: sContentMD5,
3630: oHlpr.getDescription(),
3631: oHlpr.getFileName(),
3632: oHlpr.getEncoding(),
3633: oHlpr.getSubject(),
3634: oHlpr.getPriority(),
3635: oHlpr.getFlags(),
3636: oHlpr.getSentTimestamp(),
3637: oHlpr.getReceivedTimestamp(),
3638: RecipientsHelper.getFromAddress(oMsg),
3639: RecipientsHelper.getReplyAddress(oMsg),
3640: oRecps.getRecipients(Message.RecipientType.TO),
3641: oRecps.getRecipients(Message.RecipientType.CC),
3642: oRecps.getRecipients(Message.RecipientType.BCC),
3643: oHlpr.isSpam(), byOutStrm, sMsgCharSeq);
3644:
3645: byOutStrm.close();
3646: oMsgStrm.close();
3647: } // next
3648: oInputMbox.close();
3649: oInputMbox = null;
3650: oConn.commit();
3651: } catch (FileNotFoundException fnfe) {
3652: try {
3653: oConn.rollback();
3654: } catch (Exception ignore) {
3655: }
3656: throw fnfe;
3657: } catch (IOException ioe) {
3658: try {
3659: oConn.rollback();
3660: } catch (Exception ignore) {
3661: }
3662: throw ioe;
3663: } catch (MessagingException me) {
3664: try {
3665: oConn.rollback();
3666: } catch (Exception ignore) {
3667: }
3668: throw me;
3669: } catch (SQLException sqle) {
3670: try {
3671: oConn.rollback();
3672: } catch (Exception ignore) {
3673: }
3674: throw sqle;
3675: } finally {
3676: try {
3677: if (null != oInputMbox)
3678: oInputMbox.close();
3679: } catch (Exception ignore) {
3680: }
3681: }
3682: if (DebugFile.trace) {
3683: DebugFile.decIdent();
3684: DebugFile.writeln("End DBFolder.reindexMbox()");
3685: }
3686: } // reindexMbox
3687:
3688: // ---------------------------------------------------------------------------
3689:
3690: /**
3691: * Delete very message from th eindex and rebuild it by reading the default MBOX file for this folder
3692: * @throws FileNotFoundException
3693: * @throws IOException
3694: * @throws MessagingException
3695: * @throws SQLException
3696: */
3697: public void reindexMbox() throws FileNotFoundException,
3698: IOException, MessagingException, SQLException {
3699: reindexMbox(getFilePath());
3700: }
3701:
3702: // ===========================================================================
3703: public static final short ClassId = 800;
3704: }
|