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 com.knowgate.debug.DebugFile;
0036: import com.knowgate.dataobjs.DB;
0037: import com.knowgate.dataobjs.DBBind;
0038: import com.knowgate.jdc.JDCConnection;
0039: import com.knowgate.misc.Gadgets;
0040:
0041: import java.io.StringBufferInputStream;
0042: import java.io.InputStream;
0043: import java.io.IOException;
0044: import java.io.OutputStream;
0045: import java.io.UnsupportedEncodingException;
0046: import java.io.FileInputStream;
0047: import java.io.File;
0048:
0049: import java.util.LinkedList;
0050: import java.util.Properties;
0051: import java.util.Enumeration;
0052:
0053: import java.math.BigDecimal;
0054:
0055: import java.net.URL;
0056: import java.net.MalformedURLException;
0057:
0058: import java.sql.Blob;
0059: import java.sql.ResultSet;
0060: import java.sql.Statement;
0061: import java.sql.CallableStatement;
0062: import java.sql.PreparedStatement;
0063: import java.sql.SQLException;
0064: import java.sql.Timestamp;
0065:
0066: import javax.activation.DataHandler;
0067:
0068: import javax.mail.Multipart;
0069: import javax.mail.BodyPart;
0070: import javax.mail.internet.MimeMessage;
0071: import javax.mail.internet.MimePart;
0072: import javax.mail.internet.MimeMultipart;
0073: import javax.mail.internet.MimeBodyPart;
0074: import javax.mail.MessagingException;
0075:
0076: import org.apache.oro.text.regex.MalformedPatternException;
0077: import org.apache.oro.text.regex.Perl5Compiler;
0078:
0079: import javax.activation.DataHandler;
0080: import javax.activation.FileDataSource;
0081:
0082: import com.knowgate.dfs.ByteArrayDataSource;
0083: import com.knowgate.dfs.FileSystem;
0084:
0085: /**
0086: * @author Sergio Montoro Ten
0087: * @version 1.0
0088: */
0089:
0090: public class DBMimePart extends BodyPart implements MimePart {
0091: private int iPartId, iSize;
0092: private String sMD5, sFile;
0093: private MimeBodyPart oMimeBody;
0094: private Multipart oParent;
0095: private Properties oHeaders;
0096:
0097: public DBMimePart(Multipart oMultipart) {
0098: oMimeBody = null;
0099: oParent = oMultipart;
0100: oHeaders = new Properties();
0101: }
0102:
0103: public DBMimePart(InputStream oInStrm) throws MessagingException {
0104: oMimeBody = new MimeBodyPart(oInStrm);
0105:
0106: iPartId = -1;
0107: iSize = oMimeBody.getSize();
0108:
0109: oHeaders = new Properties();
0110: oHeaders.setProperty("Content-ID", oMimeBody.getContentID());
0111: oHeaders
0112: .setProperty("Content-Type", oMimeBody.getContentType());
0113: oHeaders.setProperty("Content-Transfer-Encoding", oMimeBody
0114: .getEncoding());
0115: oHeaders.setProperty("Content-Description", oMimeBody
0116: .getDescription());
0117: oHeaders.setProperty("Content-Disposition", oMimeBody
0118: .getDisposition());
0119:
0120: sMD5 = oMimeBody.getContentMD5();
0121: sFile = oMimeBody.getFileName();
0122: }
0123:
0124: // ---------------------------------------------------------------------------
0125:
0126: public DBMimePart(Multipart oMultipart, int iIdPart,
0127: String sIdContent, String sContentType, String sContentMD5,
0128: String sDescription, String sDisposition, String sEncoding,
0129: String sFileName, int nBytes) throws MessagingException {
0130:
0131: oMimeBody = null;
0132:
0133: oParent = oMultipart;
0134: iPartId = iIdPart;
0135: sMD5 = sContentMD5;
0136: sFile = sFileName;
0137: iSize = nBytes;
0138:
0139: oHeaders = new Properties();
0140: if (null != sIdContent)
0141: oHeaders.setProperty("Content-ID", sIdContent);
0142: if (null != sContentType)
0143: oHeaders.setProperty("Content-Type", sContentType);
0144: if (null != sDescription)
0145: oHeaders.setProperty("Content-Description", sDescription);
0146: if (null != sDisposition)
0147: oHeaders.setProperty("Content-Disposition", sDisposition);
0148: if (null != sEncoding)
0149: oHeaders
0150: .setProperty("Content-Transfer-Encoding", sEncoding);
0151: }
0152:
0153: // ---------------------------------------------------------------------------
0154:
0155: private DBMimeMessage getMessage() {
0156: return (DBMimeMessage) (oParent.getParent());
0157: }
0158:
0159: // ---------------------------------------------------------------------------
0160:
0161: public String[] getHeader(String name) throws MessagingException {
0162: return new String[] { oHeaders.getProperty(name) };
0163: }
0164:
0165: // ---------------------------------------------------------------------------
0166:
0167: public String getHeader(String name, String delimiter)
0168: throws MessagingException {
0169: return oHeaders.getProperty(name);
0170: }
0171:
0172: // ---------------------------------------------------------------------------
0173:
0174: public java.util.Enumeration getAllHeaders()
0175: throws MessagingException {
0176: return oHeaders.keys();
0177: }
0178:
0179: // ---------------------------------------------------------------------------
0180:
0181: public java.util.Enumeration getMatchingHeaders(
0182: java.lang.String[] names) throws MessagingException {
0183: return null;
0184: }
0185:
0186: // ---------------------------------------------------------------------------
0187:
0188: public java.util.Enumeration getNonMatchingHeaders(
0189: java.lang.String[] names) throws MessagingException {
0190: return null;
0191: }
0192:
0193: // ---------------------------------------------------------------------------
0194:
0195: public void addHeader(String s1, String s2)
0196: throws MessagingException {
0197: throw new UnsupportedOperationException(
0198: "Cannot call addHeader() on DBMimePart)");
0199: }
0200:
0201: // ---------------------------------------------------------------------------
0202:
0203: public void setHeader(String s1, String s2)
0204: throws MessagingException {
0205: throw new UnsupportedOperationException(
0206: "Cannot call setHeader() on DBMimePart)");
0207: }
0208:
0209: // ---------------------------------------------------------------------------
0210:
0211: public void removeHeader(String header) throws MessagingException {
0212: throw new UnsupportedOperationException(
0213: "Cannot call removeHeader() on DBMimePart)");
0214: }
0215:
0216: // ---------------------------------------------------------------------------
0217:
0218: public void addHeaderLine(java.lang.String line)
0219: throws MessagingException {
0220: throw new UnsupportedOperationException(
0221: "Cannot call addHeaderLine() on DBMimePart)");
0222: }
0223:
0224: // ---------------------------------------------------------------------------
0225:
0226: public java.util.Enumeration getAllHeaderLines()
0227: throws MessagingException {
0228: throw new UnsupportedOperationException(
0229: "Cannot call getAllHeaderLines() on DBMimePart)");
0230: }
0231:
0232: // ---------------------------------------------------------------------------
0233:
0234: public java.util.Enumeration getMatchingHeaderLines(
0235: java.lang.String[] names) throws MessagingException {
0236: throw new UnsupportedOperationException(
0237: "Cannot call getMatchingHeaderLines() on DBMimePart)");
0238: }
0239:
0240: // ---------------------------------------------------------------------------
0241:
0242: public java.util.Enumeration getNonMatchingHeaderLines(
0243: java.lang.String[] names) throws MessagingException {
0244: throw new UnsupportedOperationException(
0245: "Cannot call getNonMatchingHeaderLines() on DBMimePart)");
0246: }
0247:
0248: // ---------------------------------------------------------------------------
0249:
0250: public Object getContent() throws MessagingException, IOException {
0251:
0252: int iLen;
0253: long lPos, lOff;
0254: String sFilePath;
0255: PreparedStatement oStmt = null;
0256: ResultSet oRSet = null;
0257: Object oRetVal = null;
0258: DBFolder oFldr = (DBFolder) getMessage().getFolder();
0259: String sSQL;
0260:
0261: if (DebugFile.trace) {
0262: DebugFile.writeln("Begin DBMimePart.getContent()");
0263: DebugFile.incIdent();
0264: DebugFile.writeln("Message Content-Id is "
0265: + getMessage().getContentID() + " and Part Id is "
0266: + String.valueOf(iPartId));
0267: }
0268:
0269: if (oFldr == null && oMimeBody != null) {
0270: if (DebugFile.trace)
0271: DebugFile.decIdent();
0272: return oMimeBody.getContent();
0273: }
0274:
0275: try {
0276: if (null == oFldr) {
0277: sSQL = "SELECT m.pg_message,p.id_disposition,m.nu_position,p.file_name,p.len_part,p.nu_offset,p.id_content,m.by_content FROM k_mime_msgs m, k_mime_parts p WHERE (m.gu_mimemsg=? OR m.id_message=?) AND m.gu_mimemsg=p.gu_mimemsg AND p.id_part=?";
0278: if (DebugFile.trace)
0279: DebugFile.writeln("Connection.prepareStatement("
0280: + sSQL + ")");
0281: oStmt = oFldr.getConnection().prepareStatement(sSQL);
0282: oStmt.setString(1, getMessage().getMessageGuid());
0283: oStmt.setString(2, getMessage().getContentID());
0284: oStmt.setInt(3, iPartId);
0285: } else {
0286: sSQL = "SELECT m.pg_message,p.id_disposition,m.nu_position,p.file_name,p.len_part,p.nu_offset,p.id_content,m.by_content FROM k_mime_msgs m, k_mime_parts p WHERE (m.gu_mimemsg=? OR m.id_message=?) AND m.gu_mimemsg=p.gu_mimemsg AND p.id_part=? AND m.gu_category=?";
0287: if (DebugFile.trace)
0288: DebugFile.writeln("Connection.prepareStatement("
0289: + sSQL + ")");
0290: oStmt = oFldr.getConnection().prepareStatement(sSQL);
0291: oStmt.setString(1, getMessage().getMessageGuid());
0292: oStmt.setString(2, getMessage().getContentID());
0293: oStmt.setInt(3, iPartId);
0294: oStmt.setString(4, oFldr.getCategoryGuid());
0295: }
0296:
0297: if (DebugFile.trace)
0298: DebugFile.writeln("PreparedStatement.executeQuery()");
0299: oRSet = oStmt.executeQuery();
0300:
0301: if (oRSet.next()) {
0302: String id_disposition = oRSet.getString(2);
0303:
0304: if (oRSet.wasNull())
0305: id_disposition = "inline";
0306:
0307: if (id_disposition.equals("reference")) {
0308: if (DebugFile.trace)
0309: DebugFile
0310: .writeln("content disposition is reference");
0311: sFilePath = oRSet.getString(4);
0312:
0313: FileSystem oFS = new FileSystem();
0314: byte[] byData = oFS.readfilebin(sFilePath);
0315: String sContentType = oRSet.getString(7);
0316: if (DebugFile.trace)
0317: DebugFile
0318: .writeln("new ByteArrayDataSource("
0319: + sFilePath + ", "
0320: + sContentType + ")");
0321: ByteArrayDataSource baDataSrc = new ByteArrayDataSource(
0322: byData, sContentType);
0323:
0324: oMimeBody = new MimeBodyPart();
0325: oMimeBody
0326: .setDataHandler(new DataHandler(baDataSrc));
0327: } else if (id_disposition.equals("pointer")) {
0328: if (DebugFile.trace)
0329: DebugFile
0330: .writeln("content disposition is pointer");
0331: lPos = oRSet.getBigDecimal(3).longValue();
0332: sFilePath = oRSet.getString(4);
0333: iLen = oRSet.getInt(5);
0334: lOff = oRSet.getBigDecimal(6).longValue();
0335: MboxFile oMbox = new MboxFile(sFilePath,
0336: MboxFile.READ_ONLY);
0337: InputStream oPartStrm = oMbox.getPartAsStream(lPos,
0338: lOff, iLen);
0339: oMimeBody = new MimeBodyPart(oPartStrm);
0340: } else if ((oFldr.getType() & DBFolder.MODE_BLOB) != 0) {
0341: if (DebugFile.trace)
0342: DebugFile.writeln("content disposition is "
0343: + id_disposition + " mode is BLOB");
0344: if (DebugFile.trace)
0345: DebugFile
0346: .writeln("new MimeBodyPart([InputStream])");
0347: oMimeBody = new MimeBodyPart(oRSet
0348: .getBinaryStream(8));
0349: } else {
0350: if (DebugFile.trace)
0351: DebugFile.writeln("content disposition is "
0352: + id_disposition + " mode is MBOX");
0353: BigDecimal oPosition;
0354: Object oLenPart, oOffset;
0355:
0356: oPosition = oRSet.getBigDecimal(3);
0357: if (!oRSet.wasNull())
0358: lPos = Long.parseLong(oPosition.toString());
0359: else
0360: lPos = -1;
0361: oLenPart = oRSet.getObject(5);
0362: if (!oRSet.wasNull())
0363: iLen = Integer.parseInt(oLenPart.toString());
0364: else
0365: iLen = -1;
0366: oOffset = oRSet.getObject(6);
0367: if (!oRSet.wasNull())
0368: lOff = Long.parseLong(oOffset.toString());
0369: else
0370: lOff = -1;
0371:
0372: if (lPos != -1) {
0373: if (iLen == -1)
0374: throw new MessagingException(
0375: "Part "
0376: + String.valueOf(iPartId)
0377: + " length not set at k_mime_parts table for message "
0378: + getMessage()
0379: .getMessageGuid());
0380: if (lOff == -1)
0381: throw new MessagingException(
0382: "Part "
0383: + String.valueOf(iPartId)
0384: + " offset not set at k_mime_parts table for message "
0385: + getMessage()
0386: .getMessageGuid());
0387:
0388: if (DebugFile.trace)
0389: DebugFile.writeln("new MboxFile("
0390: + ((DBFolder) getMessage()
0391: .getFolder()).getFile()
0392: + ")");
0393:
0394: MboxFile oMbox = new MboxFile(
0395: ((DBFolder) getMessage().getFolder())
0396: .getFile(), MboxFile.READ_ONLY);
0397:
0398: InputStream oInStrm = oMbox.getPartAsStream(
0399: lPos, lOff, iLen);
0400: oMimeBody = new MimeBodyPart(oInStrm);
0401: oInStrm.close();
0402:
0403: oMbox.close();
0404: } else {
0405: if (DebugFile.trace)
0406: DebugFile.decIdent();
0407: throw new MessagingException("Part "
0408: + String.valueOf(iPartId)
0409: + " not found for message "
0410: + getMessage().getContentID());
0411: }
0412: } // fi (MODE_MBOX)
0413: } else {
0414: if (DebugFile.trace) {
0415: if (null == oFldr)
0416: DebugFile.writeln("Part "
0417: + String.valueOf(iPartId)
0418: + " not found in message ["
0419: + getMessage().getMessageGuid() + "] "
0420: + getMessage().getContentID());
0421: else
0422: DebugFile.writeln("Part "
0423: + String.valueOf(iPartId)
0424: + " not found in message ["
0425: + getMessage().getMessageGuid() + "] "
0426: + getMessage().getContentID()
0427: + " at folder "
0428: + oFldr.getCategoryGuid());
0429: }
0430: } // fi (oRset.next();
0431:
0432: oRSet.close();
0433: oRSet = null;
0434: oStmt.close();
0435: oStmt = null;
0436: } catch (SQLException sqle) {
0437: try {
0438: if (null != oRSet)
0439: oRSet.close();
0440: } catch (Exception ignore) {
0441: }
0442: try {
0443: if (null != oStmt)
0444: oStmt.close();
0445: } catch (Exception ignore) {
0446: }
0447: throw new MessagingException(sqle.getMessage(), sqle);
0448: } catch (com.enterprisedt.net.ftp.FTPException xcpt) {
0449: try {
0450: if (null != oRSet)
0451: oRSet.close();
0452: } catch (Exception ignore) {
0453: }
0454: try {
0455: if (null != oStmt)
0456: oStmt.close();
0457: } catch (Exception ignore) {
0458: }
0459: throw new MessagingException(xcpt.getMessage(), xcpt);
0460: }
0461:
0462: if (oMimeBody != null) {
0463: if (DebugFile.trace)
0464: DebugFile.writeln("MimeBodyPart.getContent()");
0465: oRetVal = oMimeBody.getContent();
0466: }
0467:
0468: if (DebugFile.trace) {
0469: DebugFile.decIdent();
0470: if (null == oRetVal)
0471: DebugFile.writeln("End DBMimePart.getContent() : null");
0472: else
0473: DebugFile.writeln("End DBMimePart.getContent() : "
0474: + oRetVal.getClass().getName());
0475: }
0476:
0477: return oRetVal;
0478: } // getContent ()
0479:
0480: // ---------------------------------------------------------------------------
0481:
0482: public DataHandler getDataHandler() throws MessagingException {
0483: throw new UnsupportedOperationException(
0484: "Method getDataHandler() not implemented for DBMimePart");
0485: }
0486:
0487: // ---------------------------------------------------------------------------
0488:
0489: public InputStream getInputStream() throws MessagingException,
0490: IOException {
0491: PreparedStatement oStmt = null;
0492: ResultSet oRSet = null;
0493: InputStream oRetVal = null;
0494: DBFolder oFldr = (DBFolder) getMessage().getFolder();
0495:
0496: if (DebugFile.trace) {
0497: DebugFile.writeln("Begin DBMimePart.getInputStream()");
0498: DebugFile.incIdent();
0499: }
0500:
0501: if (oMimeBody != null) {
0502: if (DebugFile.trace)
0503: DebugFile.writeln("BodyPart.getInputStream()");
0504: if (DebugFile.trace)
0505: DebugFile.decIdent();
0506: return oMimeBody.getInputStream();
0507: }
0508:
0509: try {
0510:
0511: if (null != getMessage().getMessageGuid()) {
0512: if (DebugFile.trace)
0513: DebugFile
0514: .writeln("Connection.prepareStatement(SELECT m.pg_message,m.nu_position,p.id_disposition,p.file_name,p.len_part,p.nu_offset,m.by_content FROM k_mime_msgs m, k_mime_parts p WHERE m.gu_mimemsg='"
0515: + getMessage().getMessageGuid()
0516: + "' AND m.gu_mimemsg=p.gu_mimemsg AND p.id_part="
0517: + String.valueOf(iPartId) + ")");
0518: oStmt = ((DBFolder) getMessage().getFolder())
0519: .getConnection()
0520: .prepareStatement(
0521: "SELECT m.pg_message,m.nu_position,p.id_disposition,p.file_name,p.len_part,p.nu_offset,m.by_content FROM k_mime_msgs m, k_mime_parts p WHERE m.gu_mimemsg=? AND m.gu_mimemsg=p.gu_mimemsg AND p.id_part=?");
0522: oStmt.setString(1, getMessage().getMessageGuid());
0523: oStmt.setInt(2, iPartId);
0524: } else {
0525: if (DebugFile.trace)
0526: DebugFile
0527: .writeln("Connection.prepareStatement(SELECT m.pg_message,m.nu_position,p.id_disposition,p.file_name,p.len_part,p.nu_offset,m.by_content FROM k_mime_msgs m, k_mime_parts p WHERE m.id_message='"
0528: + getMessage().getMessageID()
0529: + "' AND m.gu_mimemsg=p.gu_mimemsg AND p.id_part="
0530: + String.valueOf(iPartId) + ")");
0531: oStmt = ((DBFolder) getMessage().getFolder())
0532: .getConnection()
0533: .prepareStatement(
0534: "SELECT m.pg_message,m.nu_position,p.id_disposition,p.file_name,p.len_part,p.nu_offset,m.by_content FROM k_mime_msgs m, k_mime_parts p WHERE m.id_message=? AND m.gu_mimemsg=p.gu_mimemsg AND p.id_part=?");
0535: oStmt.setString(1, getMessage().getMessageID());
0536: oStmt.setInt(2, iPartId);
0537: }
0538:
0539: oRSet = oStmt.executeQuery();
0540:
0541: if (oRSet.next()) {
0542: BigDecimal oMsgPos = oRSet.getBigDecimal(2);
0543: if (oRSet.wasNull())
0544: oMsgPos = null;
0545: String id_disposition = oRSet.getString(3);
0546: if (oRSet.wasNull())
0547: id_disposition = "inline";
0548: String sTmpFilePath = oRSet.getString(4);
0549:
0550: if (id_disposition.equals("reference")) {
0551: if (DebugFile.trace)
0552: DebugFile.writeln("new FileInputStream("
0553: + sTmpFilePath + ")");
0554: oRetVal = new FileInputStream(sTmpFilePath);
0555: } else if (id_disposition.equals("pointer")) {
0556: if (null == oMsgPos)
0557: throw new SQLException(
0558: "nu_position column may not be null for parts with pointer disposition",
0559: "22002", 22002);
0560: Object oPartLen = oRSet.getObject(5);
0561: if (oRSet.wasNull())
0562: throw new SQLException(
0563: "len_part column may not be null for parts with pointer disposition",
0564: "22002", 22002);
0565: BigDecimal oPartOffset = oRSet.getBigDecimal(6);
0566: if (oRSet.wasNull())
0567: throw new SQLException(
0568: "nu_offset column may not be null for parts with pointer disposition",
0569: "22002", 22002);
0570: if (DebugFile.trace)
0571: DebugFile.writeln("new File(" + sTmpFilePath
0572: + ")");
0573: File oFile = new File(sTmpFilePath);
0574: MboxFile oMbox = new MboxFile(oFile,
0575: MboxFile.READ_ONLY);
0576: oRetVal = oMbox.getPartAsStream(
0577: oMsgPos.longValue(), oPartOffset
0578: .longValue(), Integer
0579: .parseInt(oPartLen.toString()));
0580: oMimeBody = new MimeBodyPart(oRetVal);
0581: oRetVal.close();
0582: } else if ((oFldr.getType() & DBFolder.MODE_BLOB) != 0) {
0583: if (DebugFile.trace)
0584: DebugFile
0585: .writeln("new MimeBodyPart(ResultSet.getBinaryStream(...))");
0586: oMimeBody = new MimeBodyPart(oRSet
0587: .getBinaryStream(7));
0588: } else {
0589: BigDecimal oPosition;
0590: Object oMsgNum, oLenPart, oOffset;
0591: long iPosition = -1, iOffset = -1;
0592: int iLenPart = -1;
0593:
0594: oMsgNum = oRSet.getObject(1);
0595: oPosition = oRSet.getBigDecimal(2);
0596: if (!oRSet.wasNull())
0597: iPosition = Long
0598: .parseLong(oPosition.toString());
0599: oLenPart = oRSet.getObject(5);
0600: if (!oRSet.wasNull())
0601: iLenPart = oRSet.getInt(5);
0602: oOffset = oRSet.getObject(6);
0603: if (!oRSet.wasNull())
0604: iOffset = oRSet.getInt(6);
0605:
0606: if (iPosition != -1) {
0607: if (iLenPart == -1)
0608: throw new MessagingException(
0609: "Part "
0610: + String.valueOf(iPartId)
0611: + " length not set at k_mime_parts table");
0612: if (iOffset == -1)
0613: throw new MessagingException(
0614: "Part "
0615: + String.valueOf(iPartId)
0616: + " offset not set at k_mime_parts table");
0617:
0618: if (DebugFile.trace)
0619: DebugFile.writeln("new MboxFile("
0620: + ((DBFolder) getMessage()
0621: .getFolder()).getFile()
0622: + ")");
0623:
0624: MboxFile oMbox = new MboxFile(
0625: ((DBFolder) getMessage().getFolder())
0626: .getFile(), MboxFile.READ_ONLY);
0627:
0628: oMimeBody = new MimeBodyPart(oMbox
0629: .getPartAsStream(iPosition, iOffset,
0630: iLenPart));
0631:
0632: oMbox.close();
0633: } else {
0634: if (DebugFile.trace)
0635: DebugFile.decIdent();
0636: throw new MessagingException("Part "
0637: + String.valueOf(iPartId)
0638: + " not found for message "
0639: + getMessage().getContentID());
0640: }
0641: } // fi (MODE_MBOX)
0642: } // fi (oRset.next();
0643:
0644: oRSet.close();
0645: oRSet = null;
0646: oStmt.close();
0647: oStmt = null;
0648: } catch (SQLException sqle) {
0649: try {
0650: if (null != oRSet)
0651: oRSet.close();
0652: } catch (Exception ignore) {
0653: }
0654: try {
0655: if (null != oStmt)
0656: oStmt.close();
0657: } catch (Exception ignore) {
0658: }
0659: throw new MessagingException(sqle.getMessage(), sqle);
0660: }
0661:
0662: if (oMimeBody != null)
0663: oRetVal = oMimeBody.getInputStream();
0664:
0665: if (DebugFile.trace) {
0666: DebugFile.decIdent();
0667: if (null == oRetVal)
0668: DebugFile
0669: .writeln("End DBMimePart.getInputStream() : null");
0670: else
0671: DebugFile.writeln("End DBMimePart.getInputStream() : "
0672: + oRetVal.getClass().getName());
0673: }
0674:
0675: return oRetVal;
0676: } // getInputStream
0677:
0678: // ---------------------------------------------------------------------------
0679:
0680: public String getContentMD5() throws MessagingException {
0681: throw new UnsupportedOperationException(
0682: "Method getContentMD5() not implemented for DBMimePart");
0683: }
0684:
0685: // ---------------------------------------------------------------------------
0686:
0687: public int getLineCount() throws MessagingException {
0688: throw new UnsupportedOperationException(
0689: "Method getLineCount() not implemented for DBMimePart");
0690: }
0691:
0692: // ---------------------------------------------------------------------------
0693:
0694: public boolean isMimeType(String sMimeTp) throws MessagingException {
0695: throw new UnsupportedOperationException(
0696: "Method isMimeType() not implemented for DBMimePart");
0697: }
0698:
0699: // ---------------------------------------------------------------------------
0700:
0701: public String getContentID() {
0702: return oHeaders.getProperty("Content-ID");
0703: }
0704:
0705: // ---------------------------------------------------------------------------
0706:
0707: public void setDisposition(String sDisposition) {
0708: throw new UnsupportedOperationException(
0709: "Method setDisposition() not implemented for DBMimePart");
0710: }
0711:
0712: // ---------------------------------------------------------------------------
0713:
0714: public void setContentLanguage(String[] aLangs) {
0715: throw new UnsupportedOperationException(
0716: "Method setContentLanguage() not implemented for DBMimePart");
0717: }
0718:
0719: // ---------------------------------------------------------------------------
0720:
0721: public String[] getContentLanguage() {
0722: throw new UnsupportedOperationException(
0723: "Method getContentLanguage() not implemented for DBMimePart");
0724: }
0725:
0726: // ---------------------------------------------------------------------------
0727:
0728: public String getDescription() throws MessagingException {
0729: return oHeaders.getProperty("Content-Description");
0730: }
0731:
0732: // ---------------------------------------------------------------------------
0733:
0734: public String getDisposition() throws MessagingException {
0735: return oHeaders.getProperty("Content-Disposition");
0736: }
0737:
0738: // ---------------------------------------------------------------------------
0739:
0740: public String getFileName() throws MessagingException {
0741:
0742: DBFolder oFldr = (DBFolder) getMessage().getFolder();
0743: PreparedStatement oStmt = null;
0744: String sFileName;
0745:
0746: if (DebugFile.trace) {
0747: DebugFile.writeln("Begin DBMimePart.getFileName()");
0748: DebugFile.incIdent();
0749: if (oFldr == null)
0750: DebugFile.writeln("Folder is null");
0751: if (oMimeBody == null)
0752: DebugFile.writeln("MimeBody is null");
0753: }
0754:
0755: if (sFile != null)
0756: sFileName = sFile;
0757: else if (oFldr == null && oMimeBody != null) {
0758: sFileName = oMimeBody.getFileName();
0759: } else if (oFldr == null) {
0760: try {
0761: if (getMessage().getMessageGuid() != null) {
0762: if (DebugFile.trace)
0763: DebugFile
0764: .writeln("Connection.prepareStatement(SELECT "
0765: + DB.file_name
0766: + " FROM "
0767: + DB.k_mime_parts
0768: + " WHERE "
0769: + DB.gu_mimemsg
0770: + "='"
0771: + getMessage().getMessageGuid()
0772: + "' AND "
0773: + DB.id_part
0774: + "="
0775: + String.valueOf(iPartId) + ")");
0776: oStmt = oFldr.getConnection().prepareStatement(
0777: "SELECT " + DB.file_name + " FROM "
0778: + DB.k_mime_parts + " WHERE "
0779: + DB.gu_mimemsg + "=? AND "
0780: + DB.id_part + "=?",
0781: ResultSet.TYPE_FORWARD_ONLY,
0782: ResultSet.CONCUR_READ_ONLY);
0783: oStmt.setString(1, getMessage().getMessageGuid());
0784: } else {
0785: if (DebugFile.trace)
0786: DebugFile
0787: .writeln("Connection.prepareStatement(SELECT "
0788: + DB.file_name
0789: + " FROM "
0790: + DB.k_mime_parts
0791: + " WHERE "
0792: + DB.id_message
0793: + "='"
0794: + getMessage().getContentID()
0795: + "' AND "
0796: + DB.id_part
0797: + "="
0798: + String.valueOf(iPartId) + ")");
0799: oStmt = oFldr.getConnection().prepareStatement(
0800: "SELECT " + DB.file_name + " FROM "
0801: + DB.k_mime_parts + " WHERE "
0802: + DB.id_message + "=? AND "
0803: + DB.id_part + "=?",
0804: ResultSet.TYPE_FORWARD_ONLY,
0805: ResultSet.CONCUR_READ_ONLY);
0806: oStmt.setString(1, getMessage().getContentID());
0807: }
0808:
0809: oStmt.setInt(2, iPartId);
0810:
0811: ResultSet oRSet = oStmt.executeQuery();
0812:
0813: if (oRSet.next())
0814: sFileName = oRSet.getString(1);
0815: else
0816: sFileName = null;
0817:
0818: oRSet.close();
0819: oRSet = null;
0820: oStmt.close();
0821: oStmt = null;
0822: } catch (SQLException sqle) {
0823: sFileName = null;
0824: if (oStmt != null) {
0825: try {
0826: oStmt.close();
0827: } catch (Exception ignore) {
0828: }
0829: }
0830: if (DebugFile.trace)
0831: DebugFile.decIdent();
0832: throw new MessagingException(sqle.getMessage(), sqle);
0833: }
0834: } else {
0835: sFileName = null;
0836: }
0837:
0838: if (DebugFile.trace) {
0839: DebugFile.decIdent();
0840: DebugFile.writeln("End DBMimePart.getFileName() : "
0841: + sFileName);
0842: }
0843:
0844: return sFileName;
0845: } // getFileName
0846:
0847: // ---------------------------------------------------------------------------
0848:
0849: public String getContentType() {
0850: return oHeaders.getProperty("Content-Type");
0851: }
0852:
0853: // ---------------------------------------------------------------------------
0854:
0855: public String getEncoding() {
0856: return oHeaders.getProperty("Content-Transfer-Encoding");
0857: }
0858:
0859: // ---------------------------------------------------------------------------
0860:
0861: public int getPartId() {
0862: return iPartId;
0863: }
0864:
0865: // ---------------------------------------------------------------------------
0866:
0867: public int getSize() {
0868: return iSize;
0869: }
0870:
0871: // ---------------------------------------------------------------------------
0872:
0873: public String getText() throws SQLException,
0874: UnsupportedEncodingException, MessagingException,
0875: IOException {
0876:
0877: String sMsgGuid = getMessage().getMessageGuid();
0878: JDCConnection oConn = ((DBFolder) getMessage().getFolder())
0879: .getConnection();
0880: String sText = null;
0881:
0882: if (DebugFile.trace) {
0883: DebugFile.writeln("Begin DBMimePart.getText()");
0884: DebugFile.incIdent();
0885: DebugFile.writeln("Connection.prepareStatement(SELECT "
0886: + DB.id_message + "," + DBBind.Functions.ISNULL
0887: + "(len_part,0),id_encoding,by_content FROM "
0888: + DB.k_mime_parts + " WHERE (" + DB.gu_mimemsg
0889: + "='" + sMsgGuid + "') AND id_part='"
0890: + String.valueOf(iPartId) + ")");
0891: }
0892:
0893: PreparedStatement oStmt = oConn.prepareStatement("SELECT "
0894: + DB.id_message + "," + DBBind.Functions.ISNULL
0895: + "(len_part,0),id_encoding,by_content FROM "
0896: + DB.k_mime_parts + " WHERE (" + DB.gu_mimemsg
0897: + "=?) AND id_part=?", ResultSet.TYPE_FORWARD_ONLY,
0898: ResultSet.CONCUR_READ_ONLY);
0899:
0900: oStmt.setString(1, sMsgGuid);
0901: oStmt.setInt(2, iPartId);
0902:
0903: ResultSet oRSet = oStmt.executeQuery();
0904:
0905: if (oRSet.next()) {
0906:
0907: oMimeBody = new MimeBodyPart(oRSet.getBinaryStream(4));
0908:
0909: oRSet.close();
0910: oStmt.close();
0911:
0912: StringBuffer oText = new StringBuffer();
0913:
0914: parseMimePart(oText, null, getMessage().getFolder()
0915: .getName(),
0916: getMessage().getMessageID() != null ? getMessage()
0917: .getMessageID() : getMessage()
0918: .getContentID(), oMimeBody, iPartId);
0919:
0920: sText = oText.toString();
0921: } else {
0922: oRSet.close();
0923: oStmt.close();
0924: }
0925:
0926: if (DebugFile.trace) {
0927: DebugFile.decIdent();
0928: DebugFile.writeln("End DBMimePart.getText()");
0929: }
0930:
0931: return sText;
0932: }
0933:
0934: // ---------------------------------------------------------------------------
0935:
0936: public void setDataHandler(DataHandler oDataHndlr) {
0937: throw new UnsupportedOperationException(
0938: "DBMimePart objects are read-only. Cannot setDataHandler() for them");
0939: }
0940:
0941: // ---------------------------------------------------------------------------
0942:
0943: public void setText(String sTxt) {
0944: throw new UnsupportedOperationException(
0945: "DBMimePart objects are read-only. Cannot setText() for them");
0946: }
0947:
0948: // ---------------------------------------------------------------------------
0949:
0950: public void setText(String sTxt, String sEncoding) {
0951: throw new UnsupportedOperationException(
0952: "DBMimePart objects are read-only. Cannot setText() for them");
0953: }
0954:
0955: // ---------------------------------------------------------------------------
0956:
0957: public void setText(String sTxt, String sEncoding, String sStr) {
0958: throw new UnsupportedOperationException(
0959: "DBMimePart objects are read-only. Cannot setText() for them");
0960: }
0961:
0962: // ---------------------------------------------------------------------------
0963:
0964: public void setContentMD5(String sMD5) {
0965: throw new UnsupportedOperationException(
0966: "DBMimePart objects are read-only. Cannot setContentMD5() for them");
0967: }
0968:
0969: // ---------------------------------------------------------------------------
0970:
0971: public void setContent(Object oObj) {
0972: throw new UnsupportedOperationException(
0973: "DBMimePart objects are read-only. Cannot setContent() for them");
0974: }
0975:
0976: // ---------------------------------------------------------------------------
0977:
0978: public void setContent(Object oObj, String s) {
0979: throw new UnsupportedOperationException(
0980: "DBMimePart objects are read-only. Cannot setContent() for them");
0981: }
0982:
0983: // ---------------------------------------------------------------------------
0984:
0985: public void setContent(Multipart oPart) {
0986: throw new UnsupportedOperationException(
0987: "DBMimePart objects are read-only. Cannot setContent() for them");
0988: }
0989:
0990: // ---------------------------------------------------------------------------
0991:
0992: public void setFileName(String sName) {
0993: throw new UnsupportedOperationException(
0994: "DBMimePart objects are read-only. Cannot setFileName() for them");
0995: }
0996:
0997: // ---------------------------------------------------------------------------
0998:
0999: public void setDescription(String sDesc) {
1000: throw new UnsupportedOperationException(
1001: "DBMimePart objects are read-only. Cannot setDescription() for them");
1002: }
1003:
1004: // ---------------------------------------------------------------------------
1005:
1006: public void setContentId(String sId) {
1007: oHeaders.setProperty("Content-ID", sId);
1008: }
1009:
1010: // --------------------------------------------------------------------------
1011:
1012: public void setEncoding(String sEncoding) {
1013: oHeaders.setProperty("Content-Transfer-Encoding", sEncoding);
1014: }
1015:
1016: // --------------------------------------------------------------------------
1017:
1018: public void setPartId(int iId) {
1019: iPartId = iId;
1020: }
1021:
1022: // --------------------------------------------------------------------------
1023:
1024: public void setSize(int nBytes) {
1025: iSize = nBytes;
1026: }
1027:
1028: // --------------------------------------------------------------------------
1029:
1030: public static String textToHtml(String sText) {
1031:
1032: try {
1033: sText = Gadgets
1034: .replace(
1035: sText,
1036: "(http|https):\\/\\/(\\S*)",
1037: "<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>",
1038: Perl5Compiler.CASE_INSENSITIVE_MASK);
1039: } catch (Exception ignore) {
1040: }
1041:
1042: final int iLen = sText.length();
1043: StringBuffer oHtml = new StringBuffer(iLen + 1000);
1044: char cAt;
1045:
1046: for (int i = 0; i < iLen; i++) {
1047: cAt = sText.charAt(i);
1048:
1049: switch (cAt) {
1050: case 10:
1051: oHtml.append("<BR>");
1052: break;
1053: case 13:
1054: break;
1055: default:
1056: oHtml.append(cAt);
1057: }
1058: }
1059:
1060: return oHtml.toString();
1061: } // textToHtml
1062:
1063: // ---------------------------------------------------------------------------
1064:
1065: public static MimePart getMessagePart(MimePart oPart, int nPart)
1066: throws MessagingException, IOException,
1067: UnsupportedEncodingException {
1068:
1069: MimeBodyPart oNext = null;
1070: MimeMultipart oAlt;
1071: String sType;
1072: MimePart oRetVal;
1073:
1074: sType = oPart.getContentType().toUpperCase();
1075:
1076: if (DebugFile.trace)
1077: DebugFile
1078: .writeln("Begin DBMimePart.getMessagePart("
1079: + String.valueOf(nPart)
1080: + ", "
1081: + sType.replace('\n', ' ').replace('\r',
1082: ' ') + ")");
1083:
1084: if (sType.startsWith("MESSAGE/RFC822")) {
1085: DBMimeMessage oAttachment = new DBMimeMessage(
1086: (MimeMessage) oPart.getContent());
1087: oRetVal = oAttachment.getBody();
1088: } else if (sType.startsWith("MULTIPART/ALTERNATIVE")
1089: || sType.startsWith("MULTIPART/RELATED")
1090: || sType.startsWith("MULTIPART/SIGNED")) {
1091: oAlt = (MimeMultipart) oPart.getContent();
1092:
1093: int iAlt = 0;
1094: String[] aPreferred = { "TEXT/HTML", "TEXT" };
1095: boolean bFound = false;
1096:
1097: while (iAlt < aPreferred.length && !bFound) {
1098: for (int q = 0; q < oAlt.getCount(); q++) {
1099: oNext = (MimeBodyPart) oAlt.getBodyPart(q);
1100: if (DebugFile.trace && (iAlt == 0))
1101: DebugFile.writeln(" "
1102: + oNext.getContentType().toUpperCase()
1103: .replace('\n', ' ').replace(
1104: '\r', ' ') + " ID="
1105: + oNext.getContentID());
1106: bFound = oNext.getContentType().toUpperCase()
1107: .startsWith(aPreferred[iAlt]);
1108: if (bFound)
1109: break;
1110: } // next
1111: iAlt++;
1112: } // wend
1113:
1114: if (bFound)
1115: oRetVal = getMessagePart(oNext, -1);
1116: else
1117: oRetVal = getMessagePart((MimeBodyPart) oAlt
1118: .getBodyPart(0), -1);
1119: } else {
1120: oRetVal = oPart;
1121: }
1122:
1123: if (DebugFile.trace)
1124: DebugFile.writeln("End DBMimePart.getMessagePart() : "
1125: + oRetVal.getContentType().replace('\n', ' ')
1126: .replace('\r', ' '));
1127:
1128: return oRetVal;
1129: } // getMessagePart
1130:
1131: // --------------------------------------------------------------------------
1132:
1133: public static int parseMimePart(StringBuffer oStrBuff,
1134: LinkedList oAttachments, String sFolder, String sMsgId,
1135: MimePart oPart, int nPart) throws MessagingException,
1136: IOException, UnsupportedEncodingException {
1137:
1138: MimeBodyPart oNext = null;
1139: MimeMultipart oAlt;
1140: String sType;
1141: int iRetVal;
1142: String sContent;
1143:
1144: sType = oPart.getContentType().toUpperCase();
1145:
1146: if (DebugFile.trace) {
1147: DebugFile
1148: .writeln("Begin DBMimePart.parseMimePart("
1149: + sMsgId
1150: + ","
1151: + String.valueOf(nPart)
1152: + ","
1153: + sType.replace('\n', ' ').replace('\r',
1154: ' ') + ")");
1155: DebugFile.incIdent();
1156: }
1157:
1158: oPart = getMessagePart(oPart, nPart);
1159: sType = oPart.getContentType().toUpperCase();
1160:
1161: if (DebugFile.trace)
1162: DebugFile.writeln("body type = " + sType);
1163:
1164: if (sType.startsWith("TEXT/PLAIN")) {
1165: sContent = (String) oPart.getContent();
1166: if (null == sContent)
1167: sContent = "";
1168:
1169: boolean bHtml = false;
1170: int iLT = 0, iLen = sContent.length();
1171: for (int p = 0; p < iLen; p++) {
1172: char cAt = sContent.charAt(p);
1173: if (cAt == '<') {
1174: if (cAt < iLen - 6) {
1175: bHtml = sContent.substring(p + 1, p + 5)
1176: .equalsIgnoreCase("HTML");
1177: }
1178: break;
1179: } // fi (<)
1180: } // next (p)
1181:
1182: if (bHtml)
1183: oStrBuff.append(sContent);
1184: else
1185: oStrBuff.append(textToHtml(sContent));
1186:
1187: iRetVal = nPart;
1188: } else if (sType.startsWith("TEXT/HTML")) {
1189:
1190: sContent = (String) oPart.getContent();
1191: if (null == sContent)
1192: sContent = "";
1193:
1194: try {
1195: StringBuffer sMsgIdEsc = new StringBuffer(sMsgId
1196: .length() + 10);
1197: final int iMsgLen = sMsgId.length();
1198: for (int i = 0; i < iMsgLen; i++) {
1199: char c = sMsgId.charAt(i);
1200: if (c == '$')
1201: sMsgIdEsc.append("\\");
1202: sMsgIdEsc.append(c);
1203: }
1204:
1205: if (sFolder != null) {
1206: // Replace image cid: with relative references to msg_part.jsp
1207: sContent = Gadgets.replace(sContent,
1208: "src\\s*=\\s*(\"|')cid:(.*?)(\"|')",
1209: "src=\"msg_part.jsp\\?folder=" + sFolder
1210: + "&msgid=" + sMsgIdEsc
1211: + "&cid=$2\"",
1212: Perl5Compiler.CASE_INSENSITIVE_MASK);
1213:
1214: // Set all anchor targets to _blank
1215: sContent = Gadgets
1216: .replace(
1217: sContent,
1218: "<a\\s*href=(.*?)\\s*target\\s*=\\s*(\"|')?(\\w*)(\"|')?",
1219: "<a href=$1 target=\"_blank\"",
1220: Perl5Compiler.CASE_INSENSITIVE_MASK);
1221: }
1222: } catch (MalformedPatternException neverthrown) {
1223: }
1224:
1225: oStrBuff.append(sContent);
1226:
1227: iRetVal = nPart;
1228: } else if (sType.startsWith("APPLICATION/")) {
1229:
1230: if ((nPart != -1) && (null != oAttachments)) {
1231: Properties oAttachment = new Properties();
1232: String sFile_Name = oPart.getFileName();
1233: if (null != oPart.getContentID())
1234: oAttachment.setProperty("Content-Id", oPart
1235: .getContentID());
1236: oAttachment.setProperty("Part-Number", String
1237: .valueOf(nPart));
1238: oAttachment.setProperty("Part-Number", String
1239: .valueOf(nPart));
1240: oAttachment.setProperty("File-Name",
1241: sFile_Name == null ? "file"
1242: + String.valueOf(nPart) : sFile_Name);
1243:
1244: if (DebugFile.trace)
1245: DebugFile.writeln("size = "
1246: + String.valueOf(oPart.getSize()));
1247:
1248: if (oPart.getSize() > 1048576) {
1249: oAttachment.setProperty("File-Length", String
1250: .valueOf(oPart.getSize() / 1048576)
1251: + "Mb");
1252: } else if (oPart.getSize() > 1024) {
1253: oAttachment.setProperty("File-Length", String
1254: .valueOf(oPart.getSize() / 1024)
1255: + "Kb");
1256: } else {
1257: oAttachment.setProperty("File-Length", String
1258: .valueOf(oPart.getSize())
1259: + "bytes");
1260: }
1261:
1262: oAttachments.addLast(oAttachment);
1263: } // fi (nPart!=-1 && null!=oAttachments)
1264: iRetVal = -1;
1265: } else {
1266: oStrBuff.append("Type: " + sType);
1267: oStrBuff.append(" ");
1268: oStrBuff.append("Id:" + oPart.getContentID());
1269: oStrBuff.append(" ");
1270: oStrBuff.append("File:" + oPart.getFileName());
1271: oStrBuff.append(" ");
1272: oStrBuff.append("Desc:" + oPart.getDescription());
1273: oStrBuff.append("<BR/>");
1274: iRetVal = -1;
1275: }
1276:
1277: if (DebugFile.trace) {
1278: DebugFile.decIdent();
1279: DebugFile.writeln("End MimePartDB.parseMimePart() : "
1280: + String.valueOf(iRetVal));
1281: }
1282:
1283: return iRetVal;
1284: } // parseMimePart
1285:
1286: // ---------------------------------------------------------------------------
1287:
1288: public static String getMimeType(JDCConnection oConn,
1289: String sFileName) throws SQLException {
1290: String sMimeType;
1291:
1292: if (null == sFileName)
1293: return null;
1294:
1295: int iDot = sFileName.lastIndexOf('.');
1296:
1297: if (iDot < 0 || iDot == sFileName.length() - 1)
1298: return "application/octec-stream";
1299:
1300: String sFileExtension = sFileName.substring(++iDot)
1301: .toUpperCase();
1302:
1303: PreparedStatement oStmt = oConn
1304: .prepareStatement("SELECT " + DB.mime_type + " FROM "
1305: + DB.k_lu_prod_types + " WHERE "
1306: + DB.id_prod_type + "=?",
1307: ResultSet.TYPE_FORWARD_ONLY,
1308: ResultSet.CONCUR_READ_ONLY);
1309: oStmt.setString(1, sFileExtension);
1310:
1311: ResultSet oRSet = oStmt.executeQuery();
1312:
1313: if (oRSet.next())
1314: sMimeType = oRSet.getString(1);
1315: else
1316: sMimeType = null;
1317:
1318: oRSet.close();
1319: oStmt.close();
1320:
1321: return (sMimeType == null ? "application/octec-stream"
1322: : sMimeType);
1323: } // getMimeType
1324:
1325: // ---------------------------------------------------------------------------
1326:
1327: public void writeTo(OutputStream oOutStrm) throws IOException,
1328: MessagingException {
1329: }
1330: }
|