KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > knowgate > hipermail > DBFolder


1 /*
2   Copyright (C) 2004 Know Gate S.L. All rights reserved.
3                       C/Oņa, 107 1š2 28050 Madrid (Spain)
4
5   Redistribution and use in source and binary forms, with or without
6   modification, are permitted provided that the following conditions
7   are met:
8
9   1. Redistributions of source code must retain the above copyright
10      notice, this list of conditions and the following disclaimer.
11
12   2. The end-user documentation included with the redistribution,
13      if any, must include the following acknowledgment:
14      "This product includes software parts from hipergate
15      (http://www.hipergate.org/)."
16      Alternately, this acknowledgment may appear in the software itself,
17      if and wherever such third-party acknowledgments normally appear.
18
19   3. The name hipergate must not be used to endorse or promote products
20      derived from this software without prior written permission.
21      Products derived from this software may not be called hipergate,
22      nor may hipergate appear in their name, without prior written
23      permission.
24
25   This library is distributed in the hope that it will be useful,
26   but WITHOUT ANY WARRANTY; without even the implied warranty of
27   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
28
29   You should have received a copy of hipergate License with this code;
30   if not, visit http://www.hipergate.org or mail to info@hipergate.org
31 */

32
33 package com.knowgate.hipermail;
34
35 import java.sql.SQLException JavaDoc;
36 import java.sql.PreparedStatement JavaDoc;
37 import java.sql.ResultSet JavaDoc;
38 import java.sql.ResultSetMetaData JavaDoc;
39 import java.sql.Timestamp JavaDoc;
40 import java.sql.Blob JavaDoc;
41 import java.sql.Types JavaDoc;
42 import java.sql.Statement JavaDoc;
43 import java.sql.CallableStatement JavaDoc;
44
45 import java.math.BigDecimal JavaDoc;
46
47 import java.io.UnsupportedEncodingException JavaDoc;
48 import java.io.ByteArrayInputStream JavaDoc;
49 import java.io.ByteArrayOutputStream JavaDoc;
50 import java.io.IOException JavaDoc;
51 import java.io.File JavaDoc;
52 import java.io.BufferedOutputStream JavaDoc;
53 import java.io.FileOutputStream JavaDoc;
54 import java.io.FileNotFoundException JavaDoc;
55 import java.io.InputStream JavaDoc;
56
57 import javax.mail.Session JavaDoc;
58 import javax.mail.Folder JavaDoc;
59 import javax.mail.UIDFolder JavaDoc;
60 import javax.mail.Store JavaDoc;
61 import javax.mail.Message JavaDoc;
62 import javax.mail.MessagingException JavaDoc;
63 import javax.mail.StoreClosedException JavaDoc;
64 import javax.mail.FolderClosedException JavaDoc;
65 import javax.mail.MessagingException JavaDoc;
66 import javax.mail.FetchProfile JavaDoc;
67 import javax.mail.Flags JavaDoc;
68 import javax.mail.Multipart JavaDoc;
69 import javax.mail.URLName JavaDoc;
70 import javax.mail.BodyPart JavaDoc;
71 import javax.mail.Address JavaDoc;
72 import javax.mail.Flags JavaDoc;
73 import javax.mail.Session JavaDoc;
74
75 import javax.mail.internet.AddressException JavaDoc;
76 import javax.mail.internet.InternetAddress JavaDoc;
77 import javax.mail.internet.MimeMessage JavaDoc;
78 import javax.mail.internet.MimeBodyPart JavaDoc;
79 import javax.mail.internet.InternetAddress JavaDoc;
80 import javax.mail.internet.ParseException JavaDoc;
81 import javax.mail.internet.MimeMultipart JavaDoc;
82 import javax.mail.internet.MimePart JavaDoc;
83 import javax.mail.internet.MimeUtility JavaDoc;
84
85 import java.util.Properties JavaDoc;
86 import java.util.NoSuchElementException JavaDoc;
87
88 import com.sun.mail.util.BASE64DecoderStream;
89
90 import com.knowgate.jdc.JDCConnection;
91 import com.knowgate.debug.DebugFile;
92 import com.knowgate.dfs.FileSystem;
93 import com.knowgate.dataobjs.DB;
94 import com.knowgate.dataobjs.DBTable;
95 import com.knowgate.dataobjs.DBBind;
96 import com.knowgate.dataobjs.DBSubset;
97 import com.knowgate.dataobjs.DBPersist;
98 import com.knowgate.dataobjs.DBSubset;
99 import com.knowgate.dataobjs.DBKeySet;
100 import com.knowgate.hipergate.Category;
101 import com.knowgate.misc.Gadgets;
102 import com.knowgate.misc.MD5;
103 import com.knowgate.hipergate.Product;
104 import com.knowgate.hipergate.ProductLocation;
105
106 /**
107  * <p>A subclass of javax.mail.Folder providing storage for MimeMessages at database
108  * LONGVARBINARY columns and MBOX files.</p>
109  * Folders are also a subclass of com.knowgate.hipergate.Category<br>
110  * Category behaviour is obtained by delegation to a private Category instance.<br>
111  * For each DBFolder there is a corresponding row at k_categories database table.
112  * @author Sergio Montoro Ten
113  * @version 3.0
114  */

115
116 public class DBFolder extends Folder JavaDoc {
117
118   // Store Messages using an MBOX file
119
public static final int MODE_MBOX = 64;
120
121   // Store Messages using database BLOB columns
122
public static final int MODE_BLOB = 128;
123
124   private int iOpenMode;
125
126   private Category oCatg;
127
128   private JDCConnection oConn;
129
130   private String JavaDoc sFolderDir, sFolderName;
131
132   // ---------------------------------------------------------------------------
133

134   protected DBFolder(Store JavaDoc oStor, String JavaDoc sName) {
135     super(oStor);
136     oCatg = new Category();
137     iOpenMode = 0;
138     sFolderName = sName;
139   }
140
141   // ---------------------------------------------------------------------------
142

143   protected JDCConnection getConnection() {
144     return ((DBStore) getStore()).getConnection();
145   }
146
147   // ---------------------------------------------------------------------------
148

149   /**
150    * Get instance of com.knowgate.hipergate.Category object
151    */

152   public Category getCategory() {
153     return oCatg;
154   }
155
156   // ---------------------------------------------------------------------------
157

158   /**
159    * <p>Get Category GUID</p>
160    * Each folder has a Global Unique Identifier which is stored at column
161    * gu_category of table k_categories
162    * @return String Category GUID or <b>null</b> if category is not set
163    */

164   public String JavaDoc getCategoryGuid() {
165     if (null==oCatg)
166       return null;
167     else
168       return oCatg.getStringNull(DB.gu_category,null);
169   }
170
171   // ---------------------------------------------------------------------------
172

173   /**
174    * <p>Get set of identifiers for messages at this folder</p>
175    * Set entries are the mime identifiers for each message
176    * @return DBKeySet
177    * @throws SQLException
178    */

179   public DBKeySet keySet() throws SQLException JavaDoc {
180     if (DebugFile.trace) {
181       DebugFile.writeln("Begin DBFolder.keySet()");
182       DebugFile.incIdent();
183     }
184     DBKeySet oKeySet = new DBKeySet(DB.k_mime_msgs,
185                                     DB.id_message,
186                                     DB.id_message+" IS NOT NULL AND "+DB.gu_category+"=? AND "+DB.bo_deleted+"<>1 AND "+DB.gu_parent_msg+" IS NULL",0);
187     oKeySet.load(getConnection(),new Object JavaDoc[]{oCatg.getString(DB.gu_category)});
188     if (DebugFile.trace) {
189       DebugFile.decIdent();
190       DebugFile.writeln("End DBFolder.keySet() : " + String.valueOf(oKeySet.size()));
191     }
192     return oKeySet;
193   } // keySet
194

195   // ---------------------------------------------------------------------------
196

197   /**
198    * Append messages to this DBFolder
199    * @param msgs Array of mime messages to be appended
200    * @throws MessagingException
201    * @throws ArrayIndexOutOfBoundsException
202    */

203   public void appendMessages(Message JavaDoc[] msgs)
204     throws MessagingException JavaDoc, ArrayIndexOutOfBoundsException JavaDoc {
205
206     for (int m=0; m<msgs.length; m++)
207       appendMessage((MimeMessage JavaDoc) msgs[m]);
208   }
209
210   // ---------------------------------------------------------------------------
211

212   /**
213    * Copy a DBMimeMessage from another DBFolder to this DBFolder
214    * @param oSrcMsg Source message.
215    * @return GUID of new message
216    * @throws MessagingException
217    */

218   public String JavaDoc copyMessage(DBMimeMessage oSrcMsg)
219       throws MessagingException JavaDoc {
220
221     if (DebugFile.trace) {
222       DebugFile.writeln("Begin DBFolder.copyMessage()");
223       DebugFile.incIdent();
224     }
225
226     BigDecimal JavaDoc oPg = null;
227     BigDecimal JavaDoc oPos = null;
228     int iLen = 0;
229     String JavaDoc sId = null;
230     try {
231       String JavaDoc sSQL = "SELECT "+DB.pg_message+","+DB.id_message+","+DB.nu_position+","+DB.len_mimemsg+" FROM "+DB.k_mime_msgs+" WHERE "+DB.gu_mimemsg+"=";
232       if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement("+sSQL+"'"+oSrcMsg.getMessageGuid()+"')");
233
234       PreparedStatement JavaDoc oStmt = getConnection().prepareStatement(sSQL+"?",ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
235       oStmt.setString(1, oSrcMsg.getMessageGuid());
236       ResultSet JavaDoc oRSet = oStmt.executeQuery();
237       if (!oRSet.next())
238         throw new MessagingException JavaDoc("DBFolder.copyMessage() could not find source message " + oSrcMsg.getMessageGuid());
239       oPg = oRSet.getBigDecimal(1);
240       sId = oRSet.getString(2);
241       oPos= oRSet.getBigDecimal(3);
242       iLen= oRSet.getInt(4);
243       oRSet.close();
244       oStmt.close();
245     }
246     catch (SQLException JavaDoc sqle) {
247       try { getConnection().rollback(); } catch (Exception JavaDoc ignore) {}
248       if (DebugFile.trace) {
249         DebugFile.writeln("DBFolder.copyMessage() SQLException " + sqle.getMessage());
250         DebugFile.decIdent();
251       }
252       throw new MessagingException JavaDoc("DBFolder.copyMessage() SQLException " + sqle.getMessage(), sqle);
253     }
254
255     if (null==oPg) throw new MessagingException JavaDoc("DBFolder.copyMessage() Source Message not found");
256
257     DBFolder oSrcFldr = (DBFolder) oSrcMsg.getFolder();
258
259     MboxFile oMboxSrc = null;
260     MimeMessage JavaDoc oMimeSrc;
261     String JavaDoc sNewGuid = null;
262     try {
263       if ((oSrcFldr.mode&MODE_MBOX)!=0) {
264         oMboxSrc = new MboxFile(oSrcFldr.getFile(), MboxFile.READ_ONLY);
265         InputStream JavaDoc oInStrm = oMboxSrc.getMessageAsStream(oPos.longValue(), iLen);
266         oMimeSrc = new MimeMessage JavaDoc(Session.getDefaultInstance(new Properties JavaDoc()), oInStrm);
267         oInStrm.close();
268         oMboxSrc.close();
269         oMboxSrc=null;
270
271         String JavaDoc sId2 = oMimeSrc.getMessageID();
272         if ((sId!=null) && (sId2!=null)) {
273           if (!sId.trim().equals(sId2.trim())) {
274             throw new MessagingException JavaDoc("MessageID "+ sId + " at database does not match MessageID " + oMimeSrc.getMessageID() + " at MBOX file " + oSrcFldr.getFile().getName() + " for message index " + oPg.toString());
275           }
276         } // fi (sId!=null && sId2!=null)
277

278         appendMessage(oMimeSrc);
279       }
280       else {
281         ByteArrayOutputStream JavaDoc oByOutStrm = new ByteArrayOutputStream JavaDoc();
282         oSrcMsg.writeTo(oByOutStrm);
283         ByteArrayInputStream JavaDoc oByInStrm = new ByteArrayInputStream JavaDoc(oByOutStrm.toByteArray());
284         oByOutStrm.close();
285         oMimeSrc = new MimeMessage JavaDoc(Session.getDefaultInstance(new Properties JavaDoc()), oByInStrm);
286         oByInStrm.close();
287         appendMessage(oMimeSrc);
288       }
289     }
290     catch (Exception JavaDoc e) {
291       if (oMboxSrc!=null) { try { oMboxSrc.close(); } catch (Exception JavaDoc ignore) {} }
292       try { oSrcFldr.getConnection().rollback(); } catch (Exception JavaDoc ignore) {}
293       if (DebugFile.trace) {
294         DebugFile.writeln("DBFolder.copyMessage() " + e.getClass().getName() + e.getMessage());
295         DebugFile.decIdent();
296       }
297       throw new MessagingException JavaDoc(e.getMessage(), e);
298     }
299
300     if (DebugFile.trace) {
301       DebugFile.decIdent();
302       DebugFile.writeln("End DBFolder.copyMessage() : " + sNewGuid);
303     }
304
305     return sNewGuid;
306   } // copyMessage
307

308   // ---------------------------------------------------------------------------
309

310   /**
311    * Move a DBMimeMessage from another DBFolder to this DBFolder
312    * @param oSrcMsg Source message
313    * @throws MessagingException
314    */

315   public void moveMessage(DBMimeMessage oSrcMsg)
316     throws MessagingException JavaDoc {
317
318     if (DebugFile.trace) {
319       DebugFile.writeln("Begin DBFolder.moveMessage([DBMimeMessage])");
320       DebugFile.incIdent();
321     }
322
323     PreparedStatement JavaDoc oStmt = null;
324     ResultSet JavaDoc oRSet = null;
325     BigDecimal JavaDoc oPg = null;
326     BigDecimal JavaDoc oPos = null;
327     int iLen = 0;
328     boolean bNullLen = true;
329
330     boolean bWasOpen = isOpen();
331     if (!bWasOpen) open(Folder.READ_WRITE);
332
333     try {
334       oConn = getConnection();
335       if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(SELECT "+DB.pg_message+","+DB.nu_position+","+DB.len_mimemsg+" FROM "+DB.k_mime_msgs+" WHERE "+DB.gu_mimemsg+"='"+oSrcMsg.getMessageGuid()+"')");
336       oStmt = oConn.prepareStatement("SELECT "+DB.pg_message+","+DB.nu_position+","+DB.len_mimemsg+" FROM "+DB.k_mime_msgs+" WHERE "+DB.gu_mimemsg+"=?");
337       oStmt.setString(1, oSrcMsg.getMessageGuid());
338       oRSet = oStmt.executeQuery();
339       if (oRSet.next()) {
340         oPg = oRSet.getBigDecimal(1);
341         oPos = oRSet.getBigDecimal(2);
342         iLen = oRSet.getInt(3);
343         bNullLen = oRSet.wasNull();
344       }
345       oRSet.close();
346       oRSet=null;
347       oStmt.close();
348       oStmt=null;
349
350       if (DebugFile.trace) {
351         if (oPg!=null) DebugFile.writeln("message number is "+oPg.toString()); else DebugFile.writeln("message number is null");
352         if (oPos!=null) DebugFile.writeln("message position is "+oPos.toString()); else DebugFile.writeln("message position is null");
353         if (!bNullLen) DebugFile.writeln("message length is "+String.valueOf(iLen)); else DebugFile.writeln("message length is null");
354       }
355
356       oConn.setAutoCommit(false);
357
358       String JavaDoc sSrcCatg = null;
359       if (DebugFile.trace) {
360         DBFolder oSrcFldr = (DBFolder) oSrcMsg.getFolder();
361         if (null==oSrcFldr)
362           DebugFile.writeln("Source message folder is null");
363         else {
364           Category oSrcCatg = oSrcFldr.getCategory();
365           if (null==oSrcCatg)
366             DebugFile.writeln("Source message category is null");
367           else {
368             sSrcCatg = oSrcCatg.getStringNull(DB.gu_category,null);
369           }
370         }
371         if (null==sSrcCatg) {
372           DebugFile.decIdent();
373           throw new MessagingException JavaDoc("Could not find folder for source message");
374         }
375         if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(UPDATE "+DB.k_categories+" SET "+DB.len_size+"="+DB.len_size+"-"+String.valueOf(iLen)+" WHERE "+DB.gu_category+"='"+sSrcCatg+"')");
376       }
377       sSrcCatg = ((DBFolder)(oSrcMsg.getFolder())).getCategory().getString(DB.gu_category);
378       oStmt = oConn.prepareStatement("UPDATE "+DB.k_categories+" SET "+DB.len_size+"="+DB.len_size+"-"+String.valueOf(iLen)+" WHERE "+DB.gu_category+"=?");
379       oStmt.setString(1, sSrcCatg);
380       oStmt.executeUpdate();
381       oStmt.close();
382       oStmt=null;
383       if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(UPDATE "+DB.k_categories+" SET "+DB.len_size+"="+DB.len_size+"-"+String.valueOf(iLen)+" WHERE "+DB.gu_category+"='"+getCategory().getStringNull(DB.gu_category,"null")+"')");
384       oStmt = oConn.prepareStatement("UPDATE "+DB.k_categories+" SET "+DB.len_size+"="+DB.len_size+"+"+String.valueOf(iLen)+" WHERE "+DB.gu_category+"=?");
385       oStmt.setString(1, getCategory().getString(DB.gu_category));
386       oStmt.executeUpdate();
387       oStmt.close();
388       oStmt=null;
389       oConn.commit();
390     }
391     catch (SQLException JavaDoc sqle) {
392       if (null!=oRSet) { try {oRSet.close(); } catch (Exception JavaDoc ignore) {} }
393       if (null!=oStmt) { try {oStmt.close(); } catch (Exception JavaDoc ignore) {} }
394       if (null!=oConn) { try {oConn.rollback(); } catch (Exception JavaDoc ignore) {} }
395       if (!bWasOpen) { try { close(false); } catch (Exception JavaDoc ignore) {} }
396       throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
397     }
398
399     if (null==oPg) {
400       if (!bWasOpen) { try { close(false); } catch (Exception JavaDoc ignore) {} }
401       throw new MessagingException JavaDoc("Source message "+oSrcMsg.getMessageGuid()+" not found");
402     }
403
404     // If position is null then message is only at the database and not also at
405
// an MBOX file so skip moving from one MBOX file to another
406
if (null!=oPos) {
407
408       DBFolder oSrcFldr = (DBFolder) oSrcMsg.getFolder();
409
410       MboxFile oMboxSrc = null, oMboxThis = null;
411       try {
412         oMboxSrc = new MboxFile(oSrcFldr.getFile(), MboxFile.READ_WRITE);
413         oMboxThis = new MboxFile(oSrcFldr.getFile(), MboxFile.READ_WRITE);
414
415         oMboxThis.appendMessage(oMboxSrc, oPos.longValue(), iLen);
416         oMboxThis.close();
417         oMboxThis=null;
418
419         oMboxSrc.purge (new int[]{oPg.intValue()});
420
421         oMboxSrc.close();
422         oMboxSrc=null;
423       }
424       catch (Exception JavaDoc e) {
425         if (oMboxThis!=null) { try { oMboxThis.close(); } catch (Exception JavaDoc ignore) {} }
426         if (oMboxSrc!=null) { try { oMboxSrc.close(); } catch (Exception JavaDoc ignore) {} }
427         if (!bWasOpen) { try { close(false); } catch (Exception JavaDoc ignore) {} }
428         throw new MessagingException JavaDoc(e.getMessage(), e);
429       }
430     } // fi (oPos)
431

432     try {
433       oConn = getConnection();
434       String JavaDoc sCatGuid = getCategory().getString(DB.gu_category);
435       BigDecimal JavaDoc dNext = getNextMessage();
436       oStmt = oConn.prepareStatement("UPDATE "+DB.k_mime_msgs+" SET "+DB.gu_category+"=?,"+DB.pg_message+"=? WHERE "+DB.gu_mimemsg+"=?");
437       oStmt.setString(1, sCatGuid);
438       oStmt.setBigDecimal(2, dNext);
439       oStmt.setString(3, oSrcMsg.getMessageGuid());
440       oStmt.executeUpdate();
441       oStmt.close();
442       oStmt=null;
443       oConn.commit();
444     }
445     catch (SQLException JavaDoc sqle) {
446       if (null!=oStmt) { try {oStmt.close(); } catch (Exception JavaDoc ignore) {}}
447       if (null!=oConn) { try {oConn.rollback();} catch (Exception JavaDoc ignore) {} }
448       if (!bWasOpen) { try { close(false); } catch (Exception JavaDoc ignore) {} }
449       throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
450     }
451
452     if (!bWasOpen) close(false);
453
454     if (DebugFile.trace) {
455       DebugFile.decIdent();
456       DebugFile.writeln("End DBFolder.moveMessage()");
457     }
458   } // moveMessage
459

460   // ---------------------------------------------------------------------------
461

462   /**
463    * This method is not implemented and will always raise UnsupportedOperationException
464    * @throws UnsupportedOperationException
465    */

466   public boolean create(int type) throws MessagingException JavaDoc {
467     throw new UnsupportedOperationException JavaDoc("DBFolder.create()");
468   }
469
470   // ---------------------------------------------------------------------------
471

472   /**
473    * Create DBFolder with given name under current user mailroot Category
474    * @param sFolderName Folder Name
475    * @return <b>true</b>
476    * @throws MessagingException
477    */

478   public boolean create(String JavaDoc sFolderName) throws MessagingException JavaDoc {
479
480     try {
481       String JavaDoc sGuid = ((DBStore) getStore()).getUser().getMailFolder(getConnection(),
482                      Category.makeName(getConnection(), sFolderName));
483       oCatg = new Category(getConnection(), sGuid);
484     } catch (SQLException JavaDoc sqle) {
485       throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
486     }
487     return true;
488   }
489
490   // ---------------------------------------------------------------------------
491

492   /**
493    * Open this DBFolder
494    * @param mode {READ_ONLY|READ_WRITE}
495    * @throws MessagingException
496    */

497   public void open(int mode) throws MessagingException JavaDoc {
498     final int ALL_OPTIONS = READ_ONLY|READ_WRITE|MODE_MBOX|MODE_BLOB;
499
500     if (DebugFile.trace) {
501       DebugFile.writeln("DBFolder.open("+String.valueOf(mode)+ ")");
502       DebugFile.incIdent();
503     }
504
505     if ((0==(mode&READ_ONLY)) && (0==(mode&READ_WRITE))) {
506       if (DebugFile.trace) DebugFile.decIdent();
507       throw new MessagingException JavaDoc("Folder must be opened in either READ_ONLY or READ_WRITE mode");
508     }
509     else if (ALL_OPTIONS!=(mode|ALL_OPTIONS)) {
510       if (DebugFile.trace) DebugFile.decIdent();
511       throw new MessagingException JavaDoc("Invalid DBFolder open() option mode");
512     } else {
513       if ((0==(mode&MODE_MBOX)) && (0==(mode&MODE_BLOB)))
514         mode |= MODE_MBOX;
515
516       iOpenMode = mode;
517       oConn = getConnection();
518
519       if ((iOpenMode&MODE_MBOX)!=0) {
520         String JavaDoc sFolderUrl;
521         try {
522           sFolderUrl = Gadgets.chomp(getStore().getURLName().getFile(), File.separator) + oCatg.getPath(oConn);
523           if (DebugFile.trace) DebugFile.writeln("mail folder directory is " + sFolderUrl);
524           if (sFolderUrl.startsWith("file://"))
525             sFolderDir = sFolderUrl.substring(7);
526           else
527             sFolderDir = sFolderUrl;
528         } catch (SQLException JavaDoc sqle) {
529           iOpenMode = 0;
530           oConn = null;
531           if (DebugFile.trace) DebugFile.decIdent();
532           throw new MessagingException JavaDoc (sqle.getMessage(), sqle);
533         }
534         try {
535           File JavaDoc oDir = new File JavaDoc (sFolderDir);
536           if (!oDir.exists()) {
537             FileSystem oFS = new FileSystem();
538             oFS.mkdirs(sFolderUrl);
539           }
540         } catch (IOException JavaDoc ioe) {
541           iOpenMode = 0;
542           oConn = null;
543           if (DebugFile.trace) DebugFile.decIdent();
544           throw new MessagingException JavaDoc (ioe.getMessage(), ioe);
545         } catch (SecurityException JavaDoc se) {
546           iOpenMode = 0;
547           oConn = null;
548           if (DebugFile.trace) DebugFile.decIdent();
549           throw new MessagingException JavaDoc (se.getMessage(), se);
550         } catch (Exception JavaDoc je) {
551           iOpenMode = 0;
552           oConn = null;
553           if (DebugFile.trace) DebugFile.decIdent();
554           throw new MessagingException JavaDoc (je.getMessage(), je);
555         }
556
557         // Create a ProductLocation pointing to the MBOX file if it does not exist
558
oConn = getConnection();
559         PreparedStatement JavaDoc oStmt = null;
560         ResultSet JavaDoc oRSet = null;
561         boolean bHasFilePointer;
562         try {
563           oStmt = oConn.prepareStatement("SELECT NULL FROM "+DB.k_x_cat_objs+ " WHERE "+DB.gu_category+"=? AND "+DB.id_class+"=15",
564                                          ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
565           oStmt.setString(1, getCategory().getString(DB.gu_category));
566           oRSet = oStmt.executeQuery();
567           bHasFilePointer = oRSet.next();
568           oRSet.close();
569           oRSet = null;
570           oStmt.close();
571           oStmt = null;
572
573           if (!bHasFilePointer) {
574             oConn.setAutoCommit(false);
575
576             Product oProd = new Product();
577             oProd.put(DB.gu_owner, oCatg.getString(DB.gu_owner));
578             oProd.put(DB.nm_product, oCatg.getString(DB.nm_category));
579             oProd.store(oConn);
580
581             ProductLocation oLoca = new ProductLocation();
582             oLoca.put(DB.gu_product, oProd.getString(DB.gu_product));
583             oLoca.put(DB.gu_owner, oCatg.getString(DB.gu_owner));
584             oLoca.put(DB.pg_prod_locat, 1);
585             oLoca.put(DB.id_cont_type, 1);
586             oLoca.put(DB.id_prod_type, "MBOX");
587             oLoca.put(DB.len_file, 0);
588             oLoca.put(DB.xprotocol, "file://");
589             oLoca.put(DB.xhost, "localhost");
590             oLoca.put(DB.xpath, Gadgets.chomp(sFolderDir, File.separator));
591             oLoca.put(DB.xfile, oCatg.getString(DB.nm_category)+".mbox");
592             oLoca.put(DB.xoriginalfile, oCatg.getString(DB.nm_category)+".mbox");
593             oLoca.store(oConn);
594
595             oStmt = oConn.prepareStatement("INSERT INTO "+DB.k_x_cat_objs+" ("+DB.gu_category+","+DB.gu_object+","+DB.id_class+") VALUES (?,?,15)");
596             oStmt.setString(1, oCatg.getString(DB.gu_category));
597             oStmt.setString(2, oProd.getString(DB.gu_product));
598             oStmt.executeUpdate();
599             oStmt.close();
600             oStmt = null;
601
602             oConn.commit();
603           }
604         }
605         catch (SQLException JavaDoc sqle) {
606           if (DebugFile.trace) {
607             DebugFile.writeln("SQLException " + sqle.getMessage());
608             DebugFile.decIdent();
609           }
610           if (oStmt!=null) { try { oStmt.close(); } catch (SQLException JavaDoc ignore) {} }
611           if (oConn!=null) { try { oConn.rollback(); } catch (SQLException JavaDoc ignore) {} }
612           throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
613         }
614       }
615       else {
616         sFolderDir = null;
617       }
618
619       if (DebugFile.trace) {
620         DebugFile.decIdent();
621         String JavaDoc sMode = "";
622         if ((iOpenMode&READ_WRITE)!=0) sMode += " READ_WRITE ";
623         if ((iOpenMode&READ_ONLY)!=0) sMode += " READ_ONLY ";
624         if ((iOpenMode&MODE_BLOB)!=0) sMode += " MODE_BLOB ";
625         if ((iOpenMode&MODE_MBOX)!=0) sMode += " MODE_MBOX ";
626         DebugFile.writeln("End DBFolder.open() :");
627       }
628
629     }
630   } // open
631

632   // ---------------------------------------------------------------------------
633

634   /**
635    * Close this folder
636    * @param expunge
637    * @throws MessagingException
638    */

639   public void close(boolean expunge) throws MessagingException JavaDoc {
640     if (expunge) expunge();
641     iOpenMode = 0;
642     oConn = null;
643     sFolderDir = null;
644   }
645
646   // ---------------------------------------------------------------------------
647

648   /**
649    * Wipe all messages and delete this folder
650    * @param recurse boolean
651    * @return boolean
652    * @throws MessagingException
653    */

654   public boolean delete(boolean recurse) throws MessagingException JavaDoc {
655     try {
656       wipe();
657       return oCatg.delete(getConnection());
658     } catch (SQLException JavaDoc sqle) {
659       throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
660     }
661   }
662
663   // ---------------------------------------------------------------------------
664

665   /**
666    * Get folder by name or GUID
667    * @param name String Folder name or GUID
668    * @return Folder
669    * @throws MessagingException
670    */

671   public Folder JavaDoc getFolder(String JavaDoc name) throws MessagingException JavaDoc {
672     return ((DBStore) getStore()).getFolder(name);
673   }
674
675   // ---------------------------------------------------------------------------
676

677   /**
678    * This method is not implemented and will always raise UnsupportedOperationException
679    * @throws UnsupportedOperationException
680    */

681
682   public boolean hasNewMessages() throws MessagingException JavaDoc {
683     throw new UnsupportedOperationException JavaDoc("DBFolder.hasNewMessages()");
684   }
685
686   // ---------------------------------------------------------------------------
687

688   public boolean renameTo(Folder JavaDoc f)
689     throws MessagingException JavaDoc,StoreClosedException JavaDoc,NullPointerException JavaDoc {
690
691     String JavaDoc[] aLabels = new String JavaDoc[]{"en","es","fr","de","it","pt","ca","ja","cn","tw","fi","ru","pl","nl","xx"};
692     PreparedStatement JavaDoc oUpdt = null;
693
694     if (!((DBStore)getStore()).isConnected())
695       throw new StoreClosedException JavaDoc(getStore(), "Store is not connected");
696
697     if (oCatg.isNull(DB.gu_category))
698       throw new NullPointerException JavaDoc("Folder is closed");
699
700     try {
701
702       oUpdt = getConnection().prepareStatement("DELETE FROM " + DB.k_cat_labels + " WHERE " + DB.gu_category + "=?");
703       oUpdt.setString(1, oCatg.getString(DB.gu_category));
704       oUpdt.executeUpdate();
705       oUpdt.close();
706
707       oUpdt.getConnection().prepareStatement("INSERT INTO "+DB.k_cat_labels+" ("+DB.gu_category+","+DB.id_language+","+DB.tr_category+","+DB.url_category+") VALUES (?,?,?,NULL)");
708       oUpdt.setString(1, oCatg.getString(DB.gu_category));
709
710       for (int l=0; l<aLabels.length; l++) {
711         oUpdt.setString(2, aLabels[l]);
712         oUpdt.setString(3, f.getName().substring(0,1).toUpperCase()+f.getName().substring(1).toLowerCase());
713         oUpdt.executeUpdate();
714       }
715       oUpdt.close();
716       oUpdt=null;
717       getConnection().commit();
718     } catch (SQLException JavaDoc sqle) {
719       try { if (null!=oUpdt) oUpdt.close(); } catch (SQLException JavaDoc ignore) {}
720       try { getConnection().rollback(); } catch (SQLException JavaDoc ignore) {}
721       throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
722     }
723     return true;
724   } // renameTo
725

726   // ---------------------------------------------------------------------------
727

728   public boolean exists() throws MessagingException JavaDoc,StoreClosedException JavaDoc {
729     if (!((DBStore)getStore()).isConnected())
730       throw new StoreClosedException JavaDoc(getStore(), "Store is not connected");
731
732     try {
733       return oCatg.exists(getConnection());
734     } catch (SQLException JavaDoc sqle) {
735       throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
736     }
737   }
738
739   // ---------------------------------------------------------------------------
740

741   /**
742    * <p>Expunge deleted messages</p>
743    * This method removes from the database and the MBOX file those messages flagged
744    * as deleted at k_mime_msgs table
745    * @return <b>null</b>
746    * @throws MessagingException
747    */

748   public Message JavaDoc[] expunge() throws MessagingException JavaDoc {
749     Statement JavaDoc oStmt = null;
750     CallableStatement JavaDoc oCall = null;
751     PreparedStatement JavaDoc oUpdt = null;
752     PreparedStatement JavaDoc oPart = null;
753     PreparedStatement JavaDoc oAddr = null;
754     ResultSet JavaDoc oRSet;
755
756     if (DebugFile.trace) {
757       DebugFile.writeln("Begin DBFolder.expunge()");
758       DebugFile.incIdent();
759     }
760
761     // *************************************************************************
762
// If Folder is not opened is read-write mode then raise an exception
763
if (0==(iOpenMode&READ_WRITE)) {
764       if (DebugFile.trace) DebugFile.decIdent();
765       throw new javax.mail.FolderClosedException JavaDoc(this, "Folder is not open is READ_WRITE mode");
766     }
767
768     if ((0==(iOpenMode&MODE_MBOX)) && (0==(iOpenMode&MODE_BLOB))) {
769       if (DebugFile.trace) DebugFile.decIdent();
770       throw new javax.mail.FolderClosedException JavaDoc(this, "Folder is not open in MBOX nor BLOB mode");
771     }
772
773     // ***********************************************
774
// Get the list of deleted and not purged messages
775

776     MboxFile oMBox = null;
777     DBSubset oDeleted = new DBSubset(DB.k_mime_msgs, DB.gu_mimemsg+","+DB.pg_message, DB.bo_deleted+"=1 AND "+DB.gu_category+"='"+oCatg.getString(DB.gu_category)+"'", 100);
778
779     try {
780       int iDeleted = oDeleted.load(getConnection());
781
782       File JavaDoc oFile = getFile();
783
784       // *************************************
785
// Purge deleted messages from MBOX file
786

787       if (oFile.exists() && iDeleted>0) {
788         oMBox = new MboxFile(oFile, MboxFile.READ_WRITE);
789         int[] msgnums = new int[iDeleted];
790         for (int m=0; m<iDeleted; m++)
791           msgnums[m] = oDeleted.getInt(1, m);
792         oMBox.purge(msgnums);
793         oMBox.close();
794       }
795
796       // ******************************************
797
// Erase files referenced by deleted messages
798

799       oStmt = oConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
800       oRSet = oStmt.executeQuery("SELECT p." + DB.file_name + " FROM " + DB.k_mime_parts + " p," + DB.k_mime_msgs + " m WHERE p." + DB.gu_mimemsg + "=m."+ DB.gu_mimemsg + " AND m." + DB.id_disposition + "='reference' AND m." + DB.bo_deleted + "=1 AND m." + DB.gu_category +"='"+oCatg.getString(DB.gu_category)+"'");
801
802       while (oRSet.next()) {
803         String JavaDoc sFileName = oRSet.getString(1);
804         if (!oRSet.wasNull()) {
805           try {
806             File JavaDoc oRef = new File JavaDoc(sFileName);
807             if (oRef.exists()) oRef.delete();
808           }
809           catch (SecurityException JavaDoc se) {
810             if (DebugFile.trace) DebugFile.writeln("SecurityException " + sFileName + " " + se.getMessage());
811           }
812         }
813       } // wend
814

815       oRSet.close();
816       oRSet = null;
817       oStmt.close();
818       oStmt = null;
819
820       // ****************************************************
821
// Set Category size to length of MBOX file after purge
822

823       oFile = getFile();
824       oStmt = oConn.createStatement();
825       oStmt.executeUpdate("UPDATE "+DB.k_categories+" SET "+DB.len_size+"="+String.valueOf(oFile.length())+" WHERE "+DB.gu_category+"='"+getCategory().getString(DB.gu_category)+"'");
826       oStmt.close();
827       oStmt=null;
828
829       // *********************************************
830
// Actually delete messages from database tables
831

832       if (oConn.getDataBaseProduct()==JDCConnection.DBMS_POSTGRESQL) {
833         oStmt = oConn.createStatement();
834         for (int d=0; d<iDeleted; d++)
835           oStmt.executeQuery("SELECT k_sp_del_mime_msg('" + oDeleted.getString(0,d) + "')");
836         oStmt.close();
837         oStmt=null;
838       }
839       else {
840         oCall = oConn.prepareCall("{ call k_sp_del_mime_msg(?) }");
841
842         for (int d=0; d<iDeleted; d++) {
843           oCall.setString(1, oDeleted.getString(0,d));
844           oCall.execute();
845         } // next
846
oCall.close();
847         oCall=null;
848       }
849
850       if (oFile.exists() && iDeleted>0) {
851
852         // ***********************************************************************
853
// Temporary move all messages at k_mime_msgs, k_mime_parts & k_inet_addrs
854
// beyond its maximum so they do not clash when progressive identifiers
855
// are re-assigned
856

857         BigDecimal JavaDoc oUnit = new BigDecimal JavaDoc(1);
858         oStmt = oConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
859         oRSet = oStmt.executeQuery("SELECT MAX("+DB.pg_message+") FROM "+DB.k_mime_msgs+" WHERE "+DB.gu_category+"='"+getCategory().getString(DB.gu_category)+"'");
860         oRSet.next();
861         BigDecimal JavaDoc oMaxPg = oRSet.getBigDecimal(1);
862         if (oRSet.wasNull()) oMaxPg = new BigDecimal JavaDoc(0);
863         oRSet.close();
864         oRSet = null;
865         oStmt.close();
866         oStmt = null;
867         oMaxPg = oMaxPg.add(oUnit);
868
869         String JavaDoc sCat = getCategory().getString(DB.gu_category);
870         oStmt = oConn.createStatement();
871         oStmt.executeUpdate("UPDATE "+DB.k_mime_msgs+" SET "+DB.pg_message+"="+DB.pg_message+"+"+oMaxPg.toString()+" WHERE "+DB.gu_category+"='"+sCat+"'");
872         oStmt.close();
873         oStmt = null;
874
875         // *********************************************************************************
876
// Re-assign ordinal position and byte offset for all messages remaining after purge
877

878         DBSubset oMsgSet = new DBSubset(DB.k_mime_msgs, DB.gu_mimemsg+","+DB.pg_message, DB.gu_category+"='"+getCategory().getString(DB.gu_category)+"' ORDER BY "+DB.pg_message, 1000);
879         int iMsgCount = oMsgSet.load(oConn);
880
881         oMBox = new MboxFile(oFile, MboxFile.READ_ONLY);
882         long[] aPositions = oMBox.getMessagePositions();
883         oMBox.close();
884
885         oMaxPg = new BigDecimal JavaDoc(0);
886         oUpdt = oConn.prepareStatement("UPDATE "+DB.k_mime_msgs+" SET "+DB.pg_message+"=?,"+DB.nu_position+"=? WHERE "+DB.gu_mimemsg+"=?");
887         oPart = oConn.prepareStatement("UPDATE "+DB.k_mime_parts+" SET "+DB.pg_message+"=? WHERE "+DB.gu_mimemsg+"=?");
888         oAddr = oConn.prepareStatement("UPDATE "+DB.k_inet_addrs+" SET "+DB.pg_message+"=? WHERE "+DB.gu_mimemsg+"=?");
889         for (int m=0; m<iMsgCount; m++) {
890           String JavaDoc sGuMsg = oMsgSet.getString(0,m);
891           oUpdt.setBigDecimal(1, oMaxPg);
892           oUpdt.setBigDecimal(2, new BigDecimal JavaDoc(aPositions[m]));
893           oUpdt.setString(3, sGuMsg);
894           oUpdt.executeUpdate();
895           oPart.setBigDecimal(1, oMaxPg);
896           oPart.setString(2, sGuMsg);
897           oPart.executeUpdate();
898           oAddr.setBigDecimal(1, oMaxPg);
899           oAddr.setString(2, sGuMsg);
900           oAddr.executeUpdate();
901           oMaxPg = oMaxPg.add(oUnit);
902         }
903         oUpdt.close();
904         oPart.close();
905         oAddr.close();
906       }
907       oConn.commit();
908     } catch (SQLException JavaDoc sqle) {
909       try { if (oMBox!=null) oMBox.close(); } catch (Exception JavaDoc e) {}
910       try { if (oStmt!=null) oStmt.close(); } catch (Exception JavaDoc e) {}
911       try { if (oCall!=null) oCall.close(); } catch (Exception JavaDoc e) {}
912       try { if (oConn!=null) oConn.rollback(); } catch (Exception JavaDoc e) {}
913       throw new MessagingException JavaDoc (sqle.getMessage(), sqle);
914     }
915     catch (IOException JavaDoc sqle) {
916       try { if (oMBox!=null) oMBox.close(); } catch (Exception JavaDoc e) {}
917       try { if (oStmt!=null) oStmt.close(); } catch (Exception JavaDoc e) {}
918       try { if (oCall!=null) oCall.close(); } catch (Exception JavaDoc e) {}
919       try { if (oConn!=null) oConn.rollback(); } catch (Exception JavaDoc e) {}
920       throw new MessagingException JavaDoc (sqle.getMessage(), sqle);
921     }
922
923     if (DebugFile.trace) {
924       DebugFile.decIdent();
925       DebugFile.writeln("End DBFolder.expunge()");
926     }
927
928     return null;
929   } // expunge
930

931   // ---------------------------------------------------------------------------
932

933   /**
934    * Delete all messages from this folder and clear MBOX file
935    * @throws MessagingException
936    */

937   public void wipe() throws MessagingException JavaDoc {
938     Statement JavaDoc oStmt = null;
939     CallableStatement JavaDoc oCall = null;
940     PreparedStatement JavaDoc oUpdt = null;
941     PreparedStatement JavaDoc oPart = null;
942     PreparedStatement JavaDoc oAddr = null;
943     ResultSet JavaDoc oRSet;
944
945     if (DebugFile.trace) {
946       DebugFile.writeln("Begin DBFolder.wipe()");
947       DebugFile.incIdent();
948     }
949
950     // *************************************************************************
951
// If Folder is not opened is read-write mode then raise an exception
952
if (0==(iOpenMode&READ_WRITE)) {
953       if (DebugFile.trace) DebugFile.decIdent();
954       throw new javax.mail.FolderClosedException JavaDoc(this, "Folder is not open is READ_WRITE mode");
955     }
956
957     if ((0==(iOpenMode&MODE_MBOX)) && (0==(iOpenMode&MODE_BLOB))) {
958       if (DebugFile.trace) DebugFile.decIdent();
959       throw new javax.mail.FolderClosedException JavaDoc(this, "Folder is not open in MBOX nor BLOB mode");
960     }
961
962     // *************************************************
963
// Get the list of all messages stored at this folder
964

965     MboxFile oMBox = null;
966     DBSubset oDeleted = new DBSubset(DB.k_mime_msgs, DB.gu_mimemsg+","+DB.pg_message, DB.gu_category+"='"+oCatg.getString(DB.gu_category)+"'", 100);
967
968     try {
969       int iDeleted = oDeleted.load(getConnection());
970       if (DebugFile.trace) DebugFile.writeln("there are "+String.valueOf(iDeleted)+" messages to be deleted");
971
972       // ****************************************
973
// Erase files referenced by draft messages
974

975       oStmt = oConn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
976       if (DebugFile.trace) DebugFile.writeln("Statement.executeQuery(SELECT p." + DB.file_name + " FROM " + DB.k_mime_parts + " p," + DB.k_mime_msgs + " m WHERE p." + DB.gu_mimemsg + "=m."+ DB.gu_mimemsg + " AND m." + DB.id_disposition + "='reference' AND m." + DB.bo_deleted + "=1 AND m." + DB.gu_category +"='"+oCatg.getString(DB.gu_category)+"')");
977       oRSet = oStmt.executeQuery("SELECT p." + DB.file_name + " FROM " + DB.k_mime_parts + " p," + DB.k_mime_msgs + " m WHERE p." + DB.gu_mimemsg + "=m."+ DB.gu_mimemsg + " AND m." + DB.id_disposition + "='reference' AND m." + DB.bo_deleted + "=1 AND m." + DB.gu_category +"='"+oCatg.getString(DB.gu_category)+"'");
978
979       while (oRSet.next()) {
980         String JavaDoc sFileName = oRSet.getString(1);
981         if (!oRSet.wasNull()) {
982           try {
983             File JavaDoc oRef = new File JavaDoc(sFileName);
984             if (oRef.exists()) oRef.delete();
985           }
986           catch (SecurityException JavaDoc se) {
987             if (DebugFile.trace) DebugFile.writeln("SecurityException " + sFileName + " " + se.getMessage());
988           }
989         }
990       } // wend
991

992       oRSet.close();
993       oRSet = null;
994       oStmt.close();
995       oStmt = null;
996
997       // *************************
998
// Set Category size to zero
999

1000      oStmt = oConn.createStatement();
1001      if (DebugFile.trace) DebugFile.writeln("Statement.executeUpdate(UPDATE "+DB.k_categories+" SET "+DB.len_size+"=0 WHERE "+DB.gu_category+"='"+getCategory().getString(DB.gu_category)+"')");
1002      oStmt.executeUpdate("UPDATE "+DB.k_categories+" SET "+DB.len_size+"=0 WHERE "+DB.gu_category+"='"+getCategory().getString(DB.gu_category)+"'");
1003      oStmt.close();
1004      oStmt=null;
1005
1006      // *********************************************
1007
// Actually delete messages from database tables
1008

1009      if (oConn.getDataBaseProduct()==JDCConnection.DBMS_POSTGRESQL) {
1010        oStmt = oConn.createStatement();
1011        for (int d=0; d<iDeleted; d++)
1012          oStmt.executeQuery("SELECT k_sp_del_mime_msg('" + oDeleted.getString(0,d) + "')");
1013        oStmt.close();
1014        oStmt=null;
1015      }
1016      else {
1017        oCall = oConn.prepareCall("{ call k_sp_del_mime_msg(?) }");
1018
1019        for (int d=0; d<iDeleted; d++) {
1020          oCall.setString(1, oDeleted.getString(0,d));
1021          oCall.execute();
1022        } // next
1023
oCall.close();
1024        oCall=null;
1025      }
1026
1027      // *************************************
1028
// Truncate MBOX file
1029

1030      File JavaDoc oFile = getFile();
1031      if (oFile.exists()) {
1032        if (DebugFile.trace) DebugFile.writeln("File.delete("+getFilePath()+")");
1033        oFile.delete();
1034      }
1035
1036      if (DebugFile.trace) DebugFile.writeln("Connection.commit()");
1037
1038      oConn.commit();
1039    } catch (Exception JavaDoc sqle) {
1040      try { if (oMBox!=null) oMBox.close(); } catch (Exception JavaDoc e) {}
1041      try { if (oStmt!=null) oStmt.close(); } catch (Exception JavaDoc e) {}
1042      try { if (oCall!=null) oCall.close(); } catch (Exception JavaDoc e) {}
1043      try { if (oConn!=null) oConn.rollback(); } catch (Exception JavaDoc e) {}
1044      throw new MessagingException JavaDoc (sqle.getMessage(), sqle);
1045    }
1046
1047    if (DebugFile.trace) {
1048      DebugFile.decIdent();
1049      DebugFile.writeln("End DBFolder.wipe()");
1050    }
1051  } // wipe
1052

1053  // ---------------------------------------------------------------------------
1054

1055  /**
1056   * <p>Get category subpath to directory holding MBOX files for this folder</p>
1057   * The category path is composed by concatenating the names of all the parent
1058   * folders separated by a slash. The name of a folder is stored at column nm_category
1059   * of table k_categories
1060   * @return String
1061   */

1062  public String JavaDoc getFullName() {
1063    try {
1064      if (oCatg.exists(getConnection()))
1065        return oCatg.getPath(getConnection());
1066      else
1067        return null;
1068    } catch (SQLException JavaDoc sqle) {
1069      return null;
1070    }
1071  }
1072
1073  // ---------------------------------------------------------------------------
1074

1075  /**
1076   * Get path to directory containing files belonging to this folder
1077   * @return String
1078   */

1079  public String JavaDoc getDirectoryPath() {
1080    return Gadgets.chomp(sFolderDir, File.separator);
1081  }
1082
1083  // ---------------------------------------------------------------------------
1084

1085  /**
1086   * Get full path to MBOX file containing mime messages
1087   * @return String
1088   */

1089  public String JavaDoc getFilePath() {
1090    return Gadgets.chomp(sFolderDir, File.separator)+oCatg.getString(DB.nm_category)+".mbox";
1091  }
1092
1093  // ---------------------------------------------------------------------------
1094

1095  /**
1096   * Get MBOX file that holds messages for this DBFolder
1097   * @return java.io.File object representing MBOX file.
1098   */

1099  public File JavaDoc getFile() {
1100    return new File JavaDoc(getFilePath());
1101  }
1102
1103  // ---------------------------------------------------------------------------
1104

1105  /**
1106   * Get column nm_category from table k_categories for this folder
1107   * @return String
1108   */

1109  public String JavaDoc getName() {
1110    return sFolderName==null ? oCatg.getString(DB.nm_category) : sFolderName;
1111  }
1112
1113  // ---------------------------------------------------------------------------
1114

1115  public URLName JavaDoc getURLName()
1116    throws MessagingException JavaDoc,StoreClosedException JavaDoc {
1117
1118    if (!((DBStore)getStore()).isConnected())
1119      throw new StoreClosedException JavaDoc(getStore(), "Store is not connected");
1120
1121    com.knowgate.acl.ACLUser oUsr = ((DBStore)getStore()).getUser();
1122    return new URLName JavaDoc("jdbc://", "localhost", -1, oCatg.getString(DB.gu_category), oUsr.getString(DB.gu_user), oUsr.getString(DB.tx_pwd));
1123  }
1124
1125  // ---------------------------------------------------------------------------
1126

1127  protected Message JavaDoc getMessage(String JavaDoc sMsgId, int IdType)
1128    throws MessagingException JavaDoc {
1129
1130    if (DebugFile.trace) {
1131      DebugFile.writeln("Begin DBFolder.getMessage(" + sMsgId + "," + String.valueOf(IdType) + ")");
1132      DebugFile.incIdent();
1133    }
1134
1135    // *************************************************************************
1136
// If Folder is not opened then raise an exception
1137
if (!isOpen()) {
1138      if (DebugFile.trace) DebugFile.decIdent();
1139      throw new javax.mail.FolderClosedException JavaDoc(this, "Folder is closed");
1140    }
1141
1142    DBMimeMessage oRetVal = null;
1143
1144    PreparedStatement JavaDoc oStmt = null;
1145    ResultSet JavaDoc oRSet = null;
1146    String JavaDoc sSQL;
1147    Timestamp JavaDoc tsSent;
1148    String JavaDoc sMsgGuid, sContentId, sMsgDesc, sMsgDisposition, sMsgMD5, sMsgSubject, sMsgFrom, sReplyTo, sDisplayName;
1149    short iAnswered, iDeleted, iDraft, iFlagged, iRecent, iSeen;
1150    final String JavaDoc sColList = DB.gu_mimemsg+","+DB.id_message+","+DB.id_disposition+","+
1151                             DB.tx_md5+","+DB.de_mimemsg+","+DB.tx_subject+","+
1152                             DB.dt_sent+","+DB.bo_answered+","+DB.bo_deleted+","+
1153                             DB.bo_draft+","+DB.bo_flagged+","+DB.bo_recent+","+
1154                             DB.bo_seen+","+DB.tx_email_from+","+DB.tx_email_reply+","+
1155                             DB.nm_from+","+DB.by_content;
1156    InternetAddress JavaDoc oFrom = null, oReply = null;
1157    MimeMultipart JavaDoc oParts = new MimeMultipart JavaDoc();
1158
1159    try {
1160      switch (IdType) {
1161        case 1:
1162          sSQL = "SELECT "+sColList+" FROM " + DB.k_mime_msgs + " WHERE " + DB.gu_mimemsg + "=?";
1163          if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement("+sSQL+")");
1164
1165          oStmt = oConn.prepareStatement(sSQL, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
1166          oStmt.setString(1, sMsgId);
1167          break;
1168        case 2:
1169          sSQL = "SELECT "+sColList+" FROM " + DB.k_mime_msgs + " WHERE " + DB.id_message + "=?";
1170          if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement("+sSQL+")");
1171
1172          oStmt = oConn.prepareStatement(sSQL, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
1173          oStmt.setString(1, sMsgId);
1174          break;
1175        case 3:
1176          sSQL = "SELECT "+sColList+" FROM " + DB.k_mime_msgs + " WHERE " + DB.pg_message + "=?";
1177          if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement("+sSQL+")");
1178
1179          oStmt = oConn.prepareStatement(sSQL, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
1180          oStmt.setBigDecimal(1, new java.math.BigDecimal JavaDoc(sMsgId));
1181          break;
1182      }
1183
1184      oRSet = oStmt.executeQuery();
1185
1186      if (oRSet.next()) {
1187        sMsgGuid = oRSet.getString(1);
1188
1189        if (DebugFile.trace) DebugFile.writeln("gu_mimemsg="+sMsgGuid);
1190
1191        sContentId = oRSet.getString(2);
1192        sMsgDisposition = oRSet.getString(3);
1193        sMsgMD5 = oRSet.getString(4);
1194        sMsgDesc = oRSet.getString(5);
1195        sMsgSubject = oRSet.getString(6);
1196        tsSent = oRSet.getTimestamp(7);
1197        iAnswered=oRSet.getShort(8);
1198        iDeleted=oRSet.getShort(9);
1199        iDraft=oRSet.getShort(10);
1200        iFlagged=oRSet.getShort(11);
1201        iRecent=oRSet.getShort(12);
1202        iSeen=oRSet.getShort(13);
1203        sMsgFrom = oRSet.getString(14);
1204        sReplyTo = oRSet.getString(15);
1205        sDisplayName = oRSet.getString(15);
1206
1207        if (DebugFile.trace) DebugFile.writeln("ResultSet.getBinaryStream("+DB.by_content+")");
1208
1209        InputStream JavaDoc oLongVarBin = oRSet.getBinaryStream(16);
1210
1211        if (!oRSet.wasNull()) {
1212          if (DebugFile.trace) DebugFile.writeln("MimeMultipart.addBodyPart(new MimeBodyPart(InputStream)");
1213          oParts.addBodyPart(new MimeBodyPart JavaDoc(oLongVarBin));
1214        }
1215
1216        oRSet.close();
1217        oRSet = null;
1218
1219        oRetVal = new DBMimeMessage(this, sMsgGuid);
1220
1221        oRetVal.setContentID(sContentId);
1222        oRetVal.setDisposition(sMsgDisposition);
1223        oRetVal.setContentMD5(sMsgMD5);
1224        oRetVal.setDescription(sMsgDesc);
1225
1226        if (sMsgSubject!=null) {
1227          if (sMsgSubject.length()>0) {
1228            if (DebugFile.trace) DebugFile.writeln("tx_subject="+sMsgSubject);
1229            oRetVal.setSubject(sMsgSubject);
1230          }
1231        }
1232
1233        oRetVal.setSentDate(tsSent);
1234        oRetVal.setFlag(Flags.Flag.ANSWERED, iAnswered!=0);
1235        oRetVal.setFlag(Flags.Flag.DELETED, iDeleted!=0);
1236        oRetVal.setFlag(Flags.Flag.DRAFT, iDraft!=0);
1237        oRetVal.setFlag(Flags.Flag.FLAGGED, iFlagged!=0);
1238        oRetVal.setFlag(Flags.Flag.RECENT, iRecent!=0);
1239        oRetVal.setFlag(Flags.Flag.SEEN, iSeen!=0);
1240
1241        if (sMsgFrom!=null) {
1242          if (DebugFile.trace) DebugFile.writeln("from: "+sMsgFrom);
1243          if (null==sDisplayName)
1244            oFrom = new InternetAddress JavaDoc(sMsgFrom);
1245          else
1246            oFrom = new InternetAddress JavaDoc(sMsgFrom, sDisplayName);
1247          oRetVal.setFrom(oFrom);
1248        }
1249
1250        if (sReplyTo!=null) {
1251          if (DebugFile.trace) DebugFile.writeln("reply to: "+sReplyTo);
1252          oReply = new InternetAddress JavaDoc(sReplyTo);
1253          oRetVal.setReplyTo(new Address JavaDoc[]{oReply});
1254        }
1255
1256        oRetVal.setRecipients(Message.RecipientType.TO, oRetVal.getRecipients(Message.RecipientType.TO));
1257        oRetVal.setRecipients(Message.RecipientType.CC, oRetVal.getRecipients(Message.RecipientType.CC));
1258        oRetVal.setRecipients(Message.RecipientType.BCC, oRetVal.getRecipients(Message.RecipientType.BCC));
1259
1260        if (DebugFile.trace) DebugFile.writeln("MimeMessage.setContent(MimeMultipart)");
1261
1262        oRetVal.setContent(oParts);
1263      } else {
1264        oRSet.close();
1265        oRSet = null;
1266      }// fi (oRSet.next())
1267

1268      oStmt.close();
1269      oStmt = null;
1270    } catch (SQLException JavaDoc sqle) {
1271      try { if (oRSet!=null) oRSet.close(); } catch (SQLException JavaDoc ignore) { }
1272      try { if (oStmt!=null) oStmt.close(); } catch (SQLException JavaDoc ignore) { }
1273
1274      throw new MessagingException JavaDoc (sqle.getMessage(), sqle);
1275    }
1276    catch (UnsupportedEncodingException JavaDoc uee) {
1277      try { if (oRSet!=null) oRSet.close(); } catch (SQLException JavaDoc ignore) { }
1278      try { if (oStmt!=null) oStmt.close(); } catch (SQLException JavaDoc ignore) { }
1279
1280      throw new MessagingException JavaDoc (uee.getMessage(), uee);
1281    }
1282
1283    if (DebugFile.trace) {
1284        DebugFile.decIdent();
1285        DebugFile.writeln("End DBFolder.getMessage() : " + (oRetVal!=null ? "[MimeMessage]" : "null"));
1286    }
1287
1288    return oRetVal;
1289  } // getMessage
1290

1291  // ---------------------------------------------------------------------------
1292

1293  private void saveMimeParts (MimeMessage JavaDoc oMsg, String JavaDoc sMsgCharSeq,
1294                              String JavaDoc sBoundary, String JavaDoc sMsgGuid,
1295                              String JavaDoc sMsgId, int iPgMessage, int iOffset)
1296    throws MessagingException JavaDoc,OutOfMemoryError JavaDoc {
1297
1298    if (DebugFile.trace) {
1299      DebugFile.writeln("Begin DBFolder.saveMimeParts([Connection], [MimeMessage], " + sBoundary + ", " + sMsgGuid + "," + sMsgId + ", " + String.valueOf(iPgMessage) + ", " + String.valueOf(iOffset) + ", [Properties])");
1300      DebugFile.incIdent();
1301    }
1302
1303    PreparedStatement JavaDoc oStmt = null;
1304    Blob JavaDoc oContentTxt;
1305    ByteArrayOutputStream JavaDoc byOutPart;
1306    int iPrevPart = 0, iThisPart = 0, iNextPart = 0, iPartStart = 0;
1307
1308    try {
1309      MimeMultipart JavaDoc oParts = (MimeMultipart JavaDoc) oMsg.getContent();
1310
1311      final int iParts = oParts.getCount();
1312
1313      if (DebugFile.trace) DebugFile.writeln("message has " + String.valueOf(iParts) + " parts");
1314
1315      if (iParts>0) {
1316        // Skip boundary="..."; from Mime header
1317
// and boundaries from all previous parts
1318
if (sMsgCharSeq!=null && sBoundary!=null && ((iOpenMode&MODE_MBOX)!=0)) {
1319          // First boundary substring acurrence is the one from the message headers
1320
iPrevPart = sMsgCharSeq.indexOf(sBoundary, iPrevPart);
1321          if (iPrevPart>0) {
1322            iPrevPart += sBoundary.length();
1323            if (DebugFile.trace) DebugFile.writeln("found message boundary token at " + String.valueOf(iPrevPart));
1324          } // fi (message boundary)
1325
} // fi (sMsgCharSeq && sBoundary)
1326

1327        String JavaDoc sSQL = "INSERT INTO " + DB.k_mime_parts + "(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 ('"+sMsgGuid+"',?,?,?,?,?,?,?,?,?,NULL,?,?)";
1328
1329        if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(" + sSQL + ")");
1330
1331        oStmt = oConn.prepareStatement(sSQL);
1332
1333        for (int p = 0; p < iParts; p++) {
1334          if (DebugFile.trace) {
1335            DebugFile.writeln("processing part " + String.valueOf(p));
1336            DebugFile.writeln("previous part at " + String.valueOf(iPrevPart));
1337            DebugFile.writeln("part boundary is " + sBoundary);
1338            if (null==sMsgCharSeq) DebugFile.writeln("characer sequence is null");
1339          }
1340
1341          BodyPart JavaDoc oPart = oParts.getBodyPart(p);
1342          byOutPart = new ByteArrayOutputStream JavaDoc(oPart.getSize() > 0 ? oPart.getSize() : 131072);
1343          oPart.writeTo(byOutPart);
1344
1345          if (sMsgCharSeq!=null && sBoundary!=null && iPrevPart>0) {
1346            iThisPart = sMsgCharSeq.indexOf(sBoundary, iPrevPart);
1347            if (iThisPart>0) {
1348              if (DebugFile.trace) DebugFile.writeln("found part " + String.valueOf(p+iOffset) + " boundary at " + String.valueOf(iThisPart));
1349              iPartStart = iThisPart + sBoundary.length();
1350              while (iPartStart<sMsgCharSeq.length()) {
1351                if (sMsgCharSeq.charAt(iPartStart)!=' ' && sMsgCharSeq.charAt(iPartStart)!='\r' && sMsgCharSeq.charAt(iPartStart)!='\n' && sMsgCharSeq.charAt(iPartStart)!='\t')
1352                  break;
1353                else
1354                  iPartStart++;
1355              } // wend
1356
}
1357            iNextPart = sMsgCharSeq.indexOf(sBoundary, iPartStart);
1358            if (iNextPart<0) {
1359              if (DebugFile.trace) DebugFile.writeln("no next part found");
1360              iNextPart = sMsgCharSeq.length();
1361            }
1362            else {
1363              if (DebugFile.trace) DebugFile.writeln("next part boundary found at " + String.valueOf(iNextPart));
1364            }
1365          } // fi (sMsgCharSeq!=null && sBoundary!=null && iPrevPart>0)
1366

1367          String JavaDoc sContentType = oPart.getContentType();
1368          if (sContentType!=null) sContentType = MimeUtility.decodeText(sContentType);
1369
1370          boolean bForwardedAttachment = false;
1371
1372          if ((null!=sContentType) && (null!=((DBStore) getStore()).getSession())) {
1373            if (DebugFile.trace) DebugFile.writeln("Part Content-Type: " + sContentType.replace('\r',' ').replace('\n',' '));
1374
1375            if (sContentType.toUpperCase().startsWith("MULTIPART/ALTERNATIVE") ||
1376              sContentType.toUpperCase().startsWith("MULTIPART/RELATED") ||
1377              sContentType.toUpperCase().startsWith("MULTIPART/SIGNED")) {
1378              try {
1379                ByteArrayInputStream JavaDoc byInStrm = new ByteArrayInputStream JavaDoc(byOutPart.toByteArray());
1380
1381                MimeMessage JavaDoc oForwarded = new MimeMessage JavaDoc (((DBStore) getStore()).getSession(), byInStrm);
1382
1383                saveMimeParts (oForwarded, sMsgCharSeq, getPartsBoundary(oForwarded), sMsgGuid, sMsgId, iPgMessage, iOffset+iParts);
1384
1385                byInStrm.close();
1386                byInStrm = null;
1387
1388                bForwardedAttachment = true;
1389              }
1390              catch (Exception JavaDoc e) {
1391               if (DebugFile.trace) DebugFile.writeln(e.getClass().getName() + " " + e.getMessage());
1392              }
1393            } // fi (MULTIPART/ALTERNATIVE)
1394
} // fi (null!=sContentType && null!=getSession())
1395

1396          if (!bForwardedAttachment) {
1397            if (DebugFile.trace) {
1398              if ((iOpenMode&MODE_MBOX)!=0) {
1399                DebugFile.writeln("MBOX mode");
1400                DebugFile.writeln("nu_offset=" + String.valueOf(iPartStart));
1401                DebugFile.writeln("nu_len=" + String.valueOf(iNextPart-iPartStart));
1402              } else if ((iOpenMode&MODE_BLOB)!=0) {
1403                DebugFile.writeln("BLOB mode");
1404                DebugFile.writeln("nu_offset=null");
1405                DebugFile.writeln("nu_len=" + String.valueOf(oPart.getSize() > 0 ? oPart.getSize() : byOutPart.size()));
1406              }
1407              DebugFile.writeln("id_message=" + sMsgId);
1408              DebugFile.writeln("id_part=" + String.valueOf(p+iOffset));
1409              DebugFile.writeln("pg_message=" + String.valueOf(iPgMessage));
1410            }
1411
1412            oStmt.setString(1, sMsgId); // id_message
1413
oStmt.setBigDecimal(2, new BigDecimal JavaDoc(iPgMessage)); // pg_message
1414

1415            if ((iPartStart>0) && ((iOpenMode&MODE_MBOX)!=0))
1416              oStmt.setBigDecimal(3, new BigDecimal JavaDoc(iPartStart)); // nu_offset
1417
else
1418              oStmt.setNull(3, oConn.getDataBaseProduct()==JDCConnection.DBMS_ORACLE ? Types.NUMERIC : Types.DECIMAL);
1419
1420            oStmt.setInt(4, p+iOffset); // id_part
1421
oStmt.setString(5, ((javax.mail.internet.MimeBodyPart JavaDoc) oPart).getContentID()); // id_content
1422
oStmt.setString(6, Gadgets.left(sContentType, 254)); // id_type
1423
oStmt.setString(7, Gadgets.left(oPart.getDisposition(), 100));
1424
1425            if ((iOpenMode&MODE_MBOX)!=0)
1426              oStmt.setInt(8, iNextPart-iPartStart);
1427            else
1428              oStmt.setInt(8, oPart.getSize() > 0 ? oPart.getSize() : byOutPart.size());
1429
1430            if (oPart.getDescription()!=null)
1431              oStmt.setString(9, Gadgets.left(MimeUtility.decodeText(oPart.getDescription()), 254));
1432            else
1433              oStmt.setNull(9, Types.VARCHAR);
1434
1435            if (DebugFile.trace) DebugFile.writeln("file name is " + oPart.getFileName());
1436
1437            if (oPart.getFileName()!=null)
1438              oStmt.setString(10, Gadgets.left(MimeUtility.decodeText(oPart.getFileName()), 254));
1439            else
1440              oStmt.setNull(10, Types.VARCHAR);
1441
1442            if ((iOpenMode&MODE_BLOB)!=0)
1443              oStmt.setBinaryStream(11, new ByteArrayInputStream JavaDoc(byOutPart.toByteArray()),byOutPart.size());
1444            else
1445              oStmt.setNull (11, Types.LONGVARBINARY);
1446
1447            if (DebugFile.trace) DebugFile.writeln("PreparedStatement.executeUpdate()");
1448
1449            oStmt.executeUpdate();
1450          } // fi (bForwardedAttachment)
1451

1452          byOutPart.close();
1453          byOutPart = null;
1454          oContentTxt = null;
1455
1456          if ((iOpenMode&MODE_MBOX)!=0) iPrevPart = iNextPart;
1457
1458        } // next (p)
1459

1460        if (DebugFile.trace) DebugFile.writeln("PreparedStatement.close()");
1461        oStmt.close();
1462      } // fi (iParts>0)
1463
} catch (SQLException JavaDoc e) {
1464      if (DebugFile.trace) {
1465        DebugFile.writeln("SQLException " + e.getMessage());
1466        DebugFile.decIdent();
1467      }
1468      // Ensure that statement is closed and re-throw
1469
if (null!=oStmt) { try {oStmt.close();} catch (Exception JavaDoc ignore) {} }
1470      try { if (null!=oConn) oConn.rollback(); } catch (Exception JavaDoc ignore) {}
1471      throw new MessagingException JavaDoc (e.getMessage(), e);
1472    }
1473    catch (IOException JavaDoc e) {
1474      if (DebugFile.trace) {
1475        DebugFile.writeln("IOException " + e.getMessage());
1476        DebugFile.decIdent();
1477      }
1478      // Ensure that statement is closed and re-throw
1479
if (null!=oStmt) { try {oStmt.close();} catch (Exception JavaDoc ignore) {} }
1480      throw new MessagingException JavaDoc (e.getMessage(), e);
1481    }
1482    catch (Exception JavaDoc e) {
1483      if (DebugFile.trace) {
1484        DebugFile.writeln(e.getClass().getName() + " " + e.getMessage());
1485        DebugFile.decIdent();
1486      }
1487      // Ensure that statement is closed and re-throw
1488
if (null!=oStmt) { try {oStmt.close();} catch (Exception JavaDoc ignore) {} }
1489      throw new MessagingException JavaDoc (e.getMessage(), e);
1490    }
1491
1492    if (DebugFile.trace) {
1493      DebugFile.decIdent();
1494      DebugFile.writeln("End DBFolder.saveMimeParts()");
1495    }
1496  } // saveMimeParts
1497

1498  // ---------------------------------------------------------------------------
1499

1500  private static String JavaDoc getPartsBoundary(MimeMessage JavaDoc oMsg) throws MessagingException JavaDoc {
1501    if (DebugFile.trace) {
1502      DebugFile.writeln("Begin DBFolder.getPartsBoundary([MimeMessage])");
1503      DebugFile.incIdent();
1504    }
1505
1506    String JavaDoc sBoundary = null;
1507    String JavaDoc sContentType = oMsg.getContentType();
1508
1509    if (DebugFile.trace) DebugFile.writeln("Content-Type: "+sContentType);
1510
1511    if (null!=sContentType) {
1512      int iTypeLen = sContentType.length();
1513      // Find first occurrence of "boundary" substring
1514
int iBoundary = sContentType.toLowerCase().indexOf("boundary");
1515      if (iBoundary>0) {
1516        // If "boundary" is found find first equals sign
1517
int iEq = sContentType.indexOf("=",iBoundary+8);
1518        if (iEq>0) {
1519          iEq++;
1520          // If equals sign is found skip any blank spaces and quotes
1521
while (iEq<iTypeLen) {
1522            char cAt = sContentType.charAt(iEq);
1523            if (cAt!=' ' && cAt!='"')
1524              break;
1525            else
1526              iEq++;
1527          } // wend
1528
if (iEq<iTypeLen) {
1529            int iEnd = iEq;
1530            // Look forward in character sequence until quote, semi-colon or new line is found
1531
while (iEnd<iTypeLen) {
1532              char cAt = sContentType.charAt(iEnd);
1533              if (cAt!='"' && cAt!=';' && cAt!='\r' && cAt!='\n' && cAt!='\t')
1534                iEnd++;
1535              else
1536                break;
1537            } // wend
1538
if (iEnd==iTypeLen)
1539              sBoundary = sContentType.substring(iEq);
1540            else
1541              sBoundary = sContentType.substring(iEq, iEnd);
1542          }
1543        } // fi (indexOf("="))
1544
} // fi (indexOf("boundary"))
1545
} // fi (sContentType)
1546

1547    if (DebugFile.trace) {
1548      DebugFile.decIdent();
1549      DebugFile.writeln("End DBFolder.getPartsBoundary() : " + sBoundary);
1550    }
1551
1552    return sBoundary;
1553  } // getPartsBoundary
1554

1555  // ---------------------------------------------------------------------------
1556

1557  private synchronized BigDecimal JavaDoc getNextMessage() throws MessagingException JavaDoc {
1558    PreparedStatement JavaDoc oStmt = null;
1559    ResultSet JavaDoc oRSet = null;
1560    BigDecimal JavaDoc oNext;
1561
1562    try {
1563      oConn = getConnection();
1564
1565      oStmt = oConn.prepareStatement("SELECT MAX("+DB.pg_message+") FROM "+DB.k_mime_msgs+" WHERE "+DB.gu_category+"=?",
1566                                     ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_READ_ONLY);
1567      oStmt.setString(1, getCategory().getString(DB.gu_category));
1568      oRSet = oStmt.executeQuery();
1569      oRSet.next();
1570      oNext = oRSet.getBigDecimal(1);
1571      if (oRSet.wasNull())
1572        oNext = new BigDecimal JavaDoc(0);
1573      else
1574        oNext = oNext.add(new BigDecimal JavaDoc(1));
1575      oRSet.close();
1576      oRSet=null;
1577      oStmt.close();
1578      oStmt=null;
1579    } catch (Exception JavaDoc xcpt) {
1580      try { if (null!=oRSet) oRSet.close(); } catch (Exception JavaDoc ignore) {}
1581      try { if (null!=oStmt) oStmt.close(); } catch (Exception JavaDoc ignore) {}
1582      throw new MessagingException JavaDoc(xcpt.getMessage(),xcpt);
1583    }
1584    return oNext;
1585  } // getNextMessage()
1586

1587  // ---------------------------------------------------------------------------
1588

1589  private void indexMessage(String JavaDoc sGuMimeMsg, String JavaDoc sGuWorkArea,
1590                              MimeMessage JavaDoc oMsg, Integer JavaDoc iSize,
1591                              BigDecimal JavaDoc dPosition, String JavaDoc sContentType,
1592                              String JavaDoc sContentID, String JavaDoc sMessageID,
1593                              String JavaDoc sDisposition, String JavaDoc sContentMD5,
1594                              String JavaDoc sDescription, String JavaDoc sFileName,
1595                              String JavaDoc sEncoding, String JavaDoc sSubject,
1596                              String JavaDoc sPriority, Flags JavaDoc oFlgs,
1597                              Timestamp JavaDoc tsSent, Timestamp JavaDoc tsReceived,
1598                              InternetAddress JavaDoc oFrom, InternetAddress JavaDoc oReply,
1599                              Address JavaDoc[] oTo, Address JavaDoc[] oCC, Address JavaDoc[] oBCC,
1600                              boolean bIsSpam, ByteArrayOutputStream JavaDoc byOutStrm,
1601                              String JavaDoc sMsgCharSeq)
1602    throws MessagingException JavaDoc {
1603
1604    // *************************************************************************
1605
// Prepare insert statement for k_mime_msgs table.
1606
// This is the main table for referencing messages.
1607

1608    if (DebugFile.trace) {
1609      DebugFile.writeln("Begin DBFolder.indexMessage()");
1610      DebugFile.incIdent();
1611    }
1612
1613    Properties JavaDoc pFrom = new Properties JavaDoc(), pTo = new Properties JavaDoc(), pCC = new Properties JavaDoc(), pBCC = new Properties JavaDoc();
1614    PreparedStatement JavaDoc oStmt = null;
1615    BigDecimal JavaDoc dPgMessage;
1616    String JavaDoc sSQL;
1617
1618    String JavaDoc sBoundary = getPartsBoundary(oMsg);
1619    if (DebugFile.trace) DebugFile.writeln("part boundary is \"" + (sBoundary==null ? "null" : sBoundary) + "\"");
1620
1621    try {
1622      sSQL = "INSERT INTO " + DB.k_mime_msgs + "(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 (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
1623
1624      if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(" + sSQL + ")");
1625
1626      oStmt = oConn.prepareStatement(sSQL);
1627      oStmt.setString(1, sGuMimeMsg);
1628      oStmt.setString(2, sGuWorkArea);
1629
1630      if (oCatg.isNull(DB.gu_category))
1631        oStmt.setNull(3,Types.CHAR);
1632      else
1633        oStmt.setString(3, oCatg.getString(DB.gu_category));
1634
1635      oStmt.setString(4, Gadgets.left(sContentType,254));
1636      oStmt.setString(5, Gadgets.left(sContentID,254));
1637      oStmt.setString(6, Gadgets.left(sMessageID, 254));
1638      oStmt.setString(7, Gadgets.left(sDisposition, 100));
1639      oStmt.setObject(8, iSize, Types.INTEGER);
1640
1641      oStmt.setString(9, Gadgets.left(sContentMD5, 32));
1642      oStmt.setString(10, Gadgets.left(sDescription, 254));
1643      oStmt.setString(11, Gadgets.left(sFileName, 254));
1644      oStmt.setString(12, Gadgets.left(sEncoding,16));
1645      oStmt.setString(13, Gadgets.left(sSubject,254));
1646      oStmt.setTimestamp(14, tsSent);
1647      oStmt.setTimestamp(15, tsReceived);
1648
1649      if (null==oFrom) {
1650        oStmt.setNull(16, Types.VARCHAR);
1651        oStmt.setNull(17, Types.VARCHAR);
1652      }
1653      else {
1654        oStmt.setString(16, Gadgets.left(oFrom.getAddress(),254));
1655        oStmt.setString(17, Gadgets.left(oFrom.getPersonal(),254));
1656      }
1657
1658      if (null==oReply)
1659        oStmt.setNull(18, Types.VARCHAR);
1660      else
1661        oStmt.setString(18, Gadgets.left(oReply.getAddress(),254));
1662
1663      Address JavaDoc[] aRecipients;
1664      String JavaDoc sRecipientName;
1665
1666      aRecipients = oTo;
1667      if (null!=aRecipients) if (aRecipients.length==0) aRecipients=null;
1668
1669      if (null!=aRecipients) {
1670        sRecipientName = ((InternetAddress JavaDoc) aRecipients[0]).getPersonal();
1671        if (null==sRecipientName) sRecipientName = ((InternetAddress JavaDoc) aRecipients[0]).getAddress();
1672        oStmt.setString(19, Gadgets.left(sRecipientName,254));
1673      } else {
1674        aRecipients = oCC;
1675        if (null!=aRecipients) {
1676          if (aRecipients.length>0) {
1677            sRecipientName = ((InternetAddress JavaDoc) aRecipients[0]).getPersonal();
1678            if (null==sRecipientName)
1679              sRecipientName = ((InternetAddress JavaDoc) aRecipients[0]).getAddress();
1680            oStmt.setString(19, Gadgets.left(sRecipientName,254));
1681          }
1682          else
1683            oStmt.setNull(19, Types.VARCHAR);
1684        }
1685        else {
1686          aRecipients = oBCC;
1687          if (null!=aRecipients) {
1688            if (aRecipients.length>0) {
1689              sRecipientName = ( (InternetAddress JavaDoc) aRecipients[0]).getPersonal();
1690              if (null == sRecipientName)
1691                sRecipientName = ( (InternetAddress JavaDoc) aRecipients[0]).getAddress();
1692              oStmt.setString(19, Gadgets.left(sRecipientName,254));
1693            }
1694            else
1695              oStmt.setNull(19, Types.VARCHAR);
1696          }
1697          else {
1698            oStmt.setNull(19, Types.VARCHAR);
1699          } // fi (MimeMessage.RecipientType.BCC)
1700
} // fi (MimeMessage.RecipientType.CC)
1701
} // fi (MimeMessage.RecipientType.TO)
1702

1703      if (null==sPriority)
1704        oStmt.setNull(20, Types.VARCHAR);
1705      else
1706        oStmt.setString(20, sPriority);
1707
1708      // For Oracle insert flags in NUMBER columns and message body in a BLOB column.
1709
// for any other RDBMS use SMALLINT columns for Flags and a LONGVARBINARY column for the body.
1710

1711      dPgMessage = getNextMessage();
1712
1713      if (oConn.getDataBaseProduct()==JDCConnection.DBMS_ORACLE) {
1714        if (DebugFile.trace) DebugFile.writeln("PreparedStatement.setBigDecimal(21, ...)");
1715
1716        oStmt.setBigDecimal(21, new BigDecimal JavaDoc(oFlgs.contains(Flags.Flag.ANSWERED) ? "1" : "0"));
1717        oStmt.setBigDecimal(22, new BigDecimal JavaDoc(oFlgs.contains(Flags.Flag.DELETED) ? "1" : "0"));
1718        oStmt.setBigDecimal(23, new BigDecimal JavaDoc(0));
1719        oStmt.setBigDecimal(24, new BigDecimal JavaDoc(oFlgs.contains(Flags.Flag.FLAGGED) ? "1" : "0"));
1720        oStmt.setBigDecimal(25, new BigDecimal JavaDoc(oFlgs.contains(Flags.Flag.RECENT) ? "1" : "0"));
1721        oStmt.setBigDecimal(26, new BigDecimal JavaDoc(oFlgs.contains(Flags.Flag.SEEN) ? "1" : "0"));
1722        oStmt.setBigDecimal(27, new BigDecimal JavaDoc(bIsSpam ? "1" : "0"));
1723        oStmt.setBigDecimal(28, dPgMessage);
1724        oStmt.setBigDecimal(29, dPosition);
1725
1726        if (DebugFile.trace) DebugFile.writeln("PreparedStatement.setBinaryStream(30, new ByteArrayInputStream("+String.valueOf(byOutStrm.size())+"))");
1727
1728        if (byOutStrm.size()>0)
1729          oStmt.setBinaryStream(30, new ByteArrayInputStream JavaDoc(byOutStrm.toByteArray()), byOutStrm.size());
1730        else
1731          oStmt.setNull(30, Types.LONGVARBINARY);
1732      }
1733      else {
1734        if (DebugFile.trace) DebugFile.writeln("PreparedStatement.setShort(21, ...)");
1735
1736        oStmt.setShort(21, (short) (oFlgs.contains(Flags.Flag.ANSWERED) ? 1 : 0));
1737        oStmt.setShort(22, (short) (oFlgs.contains(Flags.Flag.DELETED) ? 1 : 0));
1738        oStmt.setShort(23, (short) (0));
1739        oStmt.setShort(24, (short) (oFlgs.contains(Flags.Flag.FLAGGED) ? 1 : 0));
1740        oStmt.setShort(25, (short) (oFlgs.contains(Flags.Flag.RECENT) ? 1 : 0));
1741        oStmt.setShort(26, (short) (oFlgs.contains(Flags.Flag.SEEN) ? 1 : 0));
1742        oStmt.setShort(27, (short) (bIsSpam ? 1 : 0));
1743        oStmt.setBigDecimal(28, dPgMessage);
1744        oStmt.setBigDecimal(29, dPosition);
1745
1746        if (DebugFile.trace) DebugFile.writeln("PreparedStatement.setBinaryStream(30, new ByteArrayInputStream("+String.valueOf(byOutStrm.size())+"))");
1747
1748        if (byOutStrm.size()>0)
1749          oStmt.setBinaryStream(30, new ByteArrayInputStream JavaDoc(byOutStrm.toByteArray()), byOutStrm.size());
1750        else
1751          oStmt.setNull(30, Types.LONGVARBINARY);
1752      }
1753
1754      if (DebugFile.trace) DebugFile.writeln("Statement.executeUpdate()");
1755
1756      oStmt.executeUpdate();
1757      oStmt.close();
1758      oStmt=null;
1759
1760    } catch (SQLException JavaDoc sqle) {
1761      try { if (null!=oStmt) oStmt.close(); oStmt=null; } catch (Exception JavaDoc ignore) {}
1762      try { if (null!=oConn) oConn.rollback(); } catch (Exception JavaDoc ignore) {}
1763      throw new MessagingException JavaDoc(DB.k_mime_msgs + " " + sqle.getMessage(), sqle);
1764    }
1765    if ((iOpenMode&MODE_BLOB)!=0) {
1766      // Deallocate byte array containing message body for freeing memory as soon as possible
1767
try { byOutStrm.close(); } catch (IOException JavaDoc ignore) {}
1768      byOutStrm = null;
1769    }
1770
1771    // *************************************************************************
1772
// Now that we have saved the main message reference proceed to store
1773
// its parts into k_mime_parts
1774

1775    try {
1776      Object JavaDoc oContent = oMsg.getContent();
1777      if (oContent instanceof MimeMultipart JavaDoc) {
1778        try {
1779          saveMimeParts(oMsg, sMsgCharSeq, sBoundary, sGuMimeMsg, sMessageID, dPgMessage.intValue(), 0);
1780        } catch (MessagingException JavaDoc msge) {
1781          // Close Mbox file rollback and re-throw
1782
try { oConn.rollback(); } catch (Exception JavaDoc ignore) {}
1783          throw new MessagingException JavaDoc(msge.getMessage(), msge.getNextException());
1784        }
1785      } // fi (MimeMultipart)
1786
} catch (Exception JavaDoc xcpt) {
1787      try { oConn.rollback(); } catch (Exception JavaDoc ignore) {}
1788      throw new MessagingException JavaDoc("MimeMessage.getContent() " + xcpt.getMessage(), xcpt);
1789    }
1790
1791    // *************************************************************************
1792
// Store message recipients at k_mime_addrs
1793

1794    try {
1795      if (oConn.getDataBaseProduct()==JDCConnection.DBMS_MYSQL)
1796        sSQL = "SELECT "+DB.gu_contact+","+DB.gu_company+","+DB.tx_name+","+DB.tx_surname+","+DB.tx_surname+" FROM "+DB.k_member_address+" WHERE "+DB.tx_email+"=? AND "+DB.gu_workarea+"=? UNION SELECT "+DB.gu_user+",CONVERT('****************************USER' USING utf8),"+DB.nm_user+","+DB.tx_surname1+","+DB.tx_surname2+" FROM "+DB.k_users+" WHERE ("+DB.tx_main_email+"=? OR "+DB.tx_alt_email+"=?) AND "+DB.gu_workarea+"=?";
1797      else
1798        sSQL = "SELECT "+DB.gu_contact+","+DB.gu_company+","+DB.tx_name+","+DB.tx_surname+","+DB.tx_surname+" FROM "+DB.k_member_address+" WHERE "+DB.tx_email+"=? AND "+DB.gu_workarea+"=? UNION SELECT "+DB.gu_user+",'****************************USER',"+DB.nm_user+","+DB.tx_surname1+","+DB.tx_surname2+" FROM "+DB.k_users+" WHERE ("+DB.tx_main_email+"=? OR "+DB.tx_alt_email+"=?) AND "+DB.gu_workarea+"=?";
1799    } catch (SQLException JavaDoc sqle) {
1800      if (DebugFile.trace) DebugFile.writeln("SQLException " + sqle.getMessage());
1801      sSQL = "SELECT "+DB.gu_contact+","+DB.gu_company+","+DB.tx_name+","+DB.tx_surname+","+DB.tx_surname+" FROM "+DB.k_member_address+" WHERE "+DB.tx_email+"=? AND "+DB.gu_workarea+"=? UNION SELECT "+DB.gu_user+",'****************************USER',"+DB.nm_user+","+DB.tx_surname1+","+DB.tx_surname2+" FROM "+DB.k_users+" WHERE ("+DB.tx_main_email+"=? OR "+DB.tx_alt_email+"=?) AND "+DB.gu_workarea+"=?";
1802    }
1803
1804    if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(" + sSQL + ")");
1805
1806    PreparedStatement JavaDoc oAddr = null;
1807
1808    try {
1809      oAddr = oConn.prepareStatement(sSQL, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
1810      ResultSet JavaDoc oRSet;
1811
1812      InternetAddress JavaDoc oInetAdr;
1813      String JavaDoc sTxEmail, sGuCompany, sGuContact, sTxName, sTxSurname1, sTxSurname2, sTxPersonal;
1814
1815      // Get From address and keep them into pFrom properties
1816

1817      if (oFrom!=null) {
1818        oAddr.setString(1, oFrom.getAddress());
1819        oAddr.setString(2, sGuWorkArea);
1820        oAddr.setString(3, oFrom.getAddress());
1821        oAddr.setString(4, oFrom.getAddress());
1822        oAddr.setString(5, sGuWorkArea);
1823
1824        oRSet = oAddr.executeQuery();
1825        if (oRSet.next()) {
1826          sGuContact = oRSet.getString(1);
1827          if (oRSet.wasNull()) sGuContact = "null";
1828          sGuCompany = oRSet.getString(2);
1829          if (oRSet.wasNull()) sGuCompany = "null";
1830
1831          if (sGuCompany.equals("****************************USER")) {
1832            sTxName = oRSet.getString(3);
1833            if (oRSet.wasNull()) sTxName = "";
1834            sTxSurname1 = oRSet.getString(4);
1835            if (oRSet.wasNull()) sTxSurname1 = "";
1836            sTxSurname2 = oRSet.getString(4);
1837            if (oRSet.wasNull()) sTxSurname2 = "";
1838            sTxPersonal = Gadgets.left(sTxName+" "+sTxSurname1+" "+sTxSurname2, 254).replace(',',' ').trim();
1839          }
1840          else
1841            sTxPersonal = "null";
1842
1843          pFrom.put(oFrom.getAddress(), sGuContact+","+sGuCompany+","+sTxPersonal);
1844        }
1845        else
1846          pFrom.put(oFrom.getAddress(), "null,null,null");
1847
1848      oRSet.close();
1849      } // fi (oFrom)
1850

1851      if (DebugFile.trace) DebugFile.writeln("from count = " + pFrom.size());
1852
1853      // Get TO address and keep them into pTo properties
1854

1855      if (oTo!=null) {
1856        for (int t=0; t<oTo.length; t++) {
1857          oInetAdr = (InternetAddress JavaDoc) oTo[t];
1858          sTxEmail = Gadgets.left(oInetAdr.getAddress(), 254);
1859
1860          oAddr.setString(1, sTxEmail);
1861          oAddr.setString(2, sGuWorkArea);
1862          oAddr.setString(3, sTxEmail);
1863          oAddr.setString(4, sTxEmail);
1864          oAddr.setString(5, sGuWorkArea);
1865
1866          oRSet = oAddr.executeQuery();
1867          if (oRSet.next()) {
1868            sGuContact = oRSet.getString(1);
1869            if (oRSet.wasNull()) sGuContact = "null";
1870            sGuCompany = oRSet.getString(2);
1871            if (oRSet.wasNull()) sGuCompany = "null";
1872            if (sGuCompany.equals("****************************USER")) {
1873              sTxName = oRSet.getString(3);
1874              if (oRSet.wasNull()) sTxName = "";
1875              sTxSurname1 = oRSet.getString(4);
1876              if (oRSet.wasNull()) sTxSurname1 = "";
1877              sTxSurname2 = oRSet.getString(4);
1878              if (oRSet.wasNull()) sTxSurname2 = "";
1879              sTxPersonal = Gadgets.left(sTxName+" "+sTxSurname1+" "+sTxSurname2, 254).replace(',',' ').trim();
1880            }
1881            else
1882              sTxPersonal = "null";
1883
1884            pTo.put(sTxEmail, sGuContact+","+sGuCompany+","+sTxPersonal);
1885          } // fi (oRSet.next())
1886
else
1887            pTo.put(sTxEmail, "null,null,null");
1888
1889          oRSet.close();
1890        } // next (t)
1891
} // fi (oTo)
1892

1893      if (DebugFile.trace) DebugFile.writeln("to count = " + pTo.size());
1894
1895      // Get CC address and keep them into pTo properties
1896

1897      if (oCC!=null) {
1898        for (int c=0; c<oCC.length; c++) {
1899          oInetAdr = (InternetAddress JavaDoc) oCC[c];
1900          sTxEmail = Gadgets.left(oInetAdr.getAddress(), 254);
1901
1902          oAddr.setString(1, sTxEmail);
1903          oAddr.setString(2, sGuWorkArea);
1904          oAddr.setString(3, sTxEmail);
1905          oAddr.setString(4, sTxEmail);
1906          oAddr.setString(5, sGuWorkArea);
1907
1908          oRSet = oAddr.executeQuery();
1909          if (oRSet.next()) {
1910            sGuContact = oRSet.getString(1);
1911            if (oRSet.wasNull()) sGuContact = "null";
1912            sGuCompany = oRSet.getString(2);
1913            if (oRSet.wasNull()) sGuCompany = "null";
1914            if (sGuCompany.equals("****************************USER")) {
1915              sTxName = oRSet.getString(3);
1916              if (oRSet.wasNull()) sTxName = "";
1917              sTxSurname1 = oRSet.getString(4);
1918              if (oRSet.wasNull()) sTxSurname1 = "";
1919              sTxSurname2 = oRSet.getString(4);
1920              if (oRSet.wasNull()) sTxSurname2 = "";
1921              sTxPersonal = Gadgets.left(sTxName+" "+sTxSurname1+" "+sTxSurname2, 254).replace(',',' ').trim();
1922            }
1923            else
1924              sTxPersonal = "null";
1925
1926            pCC.put(sTxEmail, sGuContact+","+sGuCompany+","+sTxPersonal);
1927          } // fi (oRSet.next())
1928
else
1929            pCC.put(sTxEmail, "null,null,null");
1930
1931          oRSet.close();
1932        } // next (c)
1933
} // fi (oCC)
1934

1935      if (DebugFile.trace) DebugFile.writeln("cc count = " + pCC.size());
1936
1937      // Get BCC address and keep them into pTo properties
1938

1939      if (oBCC!=null) {
1940        for (int b=0; b<oBCC.length; b++) {
1941          oInetAdr = (InternetAddress JavaDoc) oBCC[b];
1942          sTxEmail = Gadgets.left(oInetAdr.getAddress(), 254);
1943
1944          oAddr.setString(1, sTxEmail);
1945          oAddr.setString(2, sGuWorkArea);
1946          oAddr.setString(3, sTxEmail);
1947          oAddr.setString(4, sTxEmail);
1948          oAddr.setString(5, sGuWorkArea);
1949
1950          oRSet = oAddr.executeQuery();
1951          if (oRSet.next()) {
1952            sGuContact = oRSet.getString(1);
1953            if (oRSet.wasNull()) sGuContact = "null";
1954            sGuCompany = oRSet.getString(2);
1955            if (oRSet.wasNull()) sGuCompany = "null";
1956            if (sGuCompany.equals("****************************USER")) {
1957              sTxName = oRSet.getString(3);
1958              if (oRSet.wasNull()) sTxName = "";
1959              sTxSurname1 = oRSet.getString(4);
1960              if (oRSet.wasNull()) sTxSurname1 = "";
1961              sTxSurname2 = oRSet.getString(4);
1962              if (oRSet.wasNull()) sTxSurname2 = "";
1963              sTxPersonal = Gadgets.left(sTxName+" "+sTxSurname1+" "+sTxSurname2, 254).replace(',',' ').trim();
1964            }
1965            else
1966              sTxPersonal = "null";
1967
1968            pBCC.put(sTxEmail, sGuContact+","+sGuCompany);
1969          } // fi (oRSet.next())
1970
else
1971            pBCC.put(sTxEmail, "null,null,null");
1972
1973          oRSet.close();
1974        } // next (b)
1975
} // fi (oCBB)
1976

1977      if (DebugFile.trace) DebugFile.writeln("bcc count = " + pBCC.size());
1978
1979      oAddr.close();
1980
1981      sSQL = "INSERT INTO " + DB.k_inet_addrs + " (gu_mimemsg,id_message,tx_email,tp_recipient,gu_user,gu_contact,gu_company,tx_personal) VALUES ('"+sGuMimeMsg+"',?,?,?,?,?,?,?)";
1982
1983      if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(" + sSQL + ")");
1984
1985      oStmt = oConn.prepareStatement(sSQL);
1986
1987      java.util.Enumeration JavaDoc oMailEnum;
1988      String JavaDoc[] aRecipient;
1989
1990      if (!pFrom.isEmpty()) {
1991        oMailEnum = pFrom.keys();
1992        while (oMailEnum.hasMoreElements()) {
1993          oStmt.setString(1, sMessageID);
1994          sTxEmail = (String JavaDoc) oMailEnum.nextElement();
1995          if (DebugFile.trace) DebugFile.writeln("processing mail address "+sTxEmail);
1996          aRecipient = Gadgets.split(pFrom.getProperty(sTxEmail),',');
1997
1998          oStmt.setString(2, sTxEmail);
1999          oStmt.setString(3, "from");
2000
2001          if (aRecipient[0].equals("null") && aRecipient[1].equals("null")) {
2002            oStmt.setNull(4, Types.CHAR);
2003            oStmt.setNull(5, Types.CHAR);
2004            oStmt.setNull(6, Types.CHAR);
2005          }
2006          else if (aRecipient[1].equals("****************************USER")) {
2007            oStmt.setString(4, aRecipient[0]);
2008            oStmt.setNull(5, Types.CHAR);
2009            oStmt.setNull(6, Types.CHAR);
2010          }
2011          else {
2012            oStmt.setNull(4, Types.CHAR);
2013            oStmt.setString(5, aRecipient[0].equals("null") ? null : aRecipient[0]);
2014            oStmt.setString(6, aRecipient[1].equals("null") ? null : aRecipient[1]);
2015          }
2016
2017          if (aRecipient[2].equals("null"))
2018            oStmt.setNull(7, Types.VARCHAR);
2019          else
2020            oStmt.setString(7, aRecipient[2]);
2021
2022          if (DebugFile.trace) DebugFile.writeln("Statement.executeUpdate()");
2023          oStmt.executeUpdate();
2024        } // wend
2025
} // fi (from)
2026

2027      if (!pTo.isEmpty()) {
2028        oMailEnum = pTo.keys();
2029        while (oMailEnum.hasMoreElements()) {
2030          oStmt.setString(1, sMessageID);
2031          sTxEmail = (String JavaDoc) oMailEnum.nextElement();
2032          aRecipient = Gadgets.split(pTo.getProperty(sTxEmail),',');
2033
2034          oStmt.setString(2, sTxEmail);
2035          oStmt.setString(3, "to");
2036
2037          if (aRecipient[0].equals("null") && aRecipient[1].equals("null")) {
2038            oStmt.setNull(4, Types.CHAR);
2039            oStmt.setNull(5, Types.CHAR);
2040            oStmt.setNull(6, Types.CHAR);
2041          }
2042          else if (aRecipient[1].equals("****************************USER")) {
2043            oStmt.setString(4, aRecipient[0]);
2044            oStmt.setNull(5, Types.CHAR);
2045            oStmt.setNull(6, Types.CHAR);
2046          }
2047          else {
2048            oStmt.setNull(4, Types.CHAR);
2049            oStmt.setString(5, aRecipient[0].equals("null") ? null : aRecipient[0]);
2050            oStmt.setString(6, aRecipient[1].equals("null") ? null : aRecipient[1]);
2051          }
2052
2053          if (aRecipient[2].equals("null"))
2054            oStmt.setNull(7, Types.VARCHAR);
2055          else
2056            oStmt.setString(7, aRecipient[2]);
2057
2058          if (DebugFile.trace) DebugFile.writeln("Statement.executeUpdate()");
2059
2060          oStmt.executeUpdate();
2061        } // wend
2062
} // fi (to)
2063

2064      if (!pCC.isEmpty()) {
2065        oMailEnum = pCC.keys();
2066        while (oMailEnum.hasMoreElements()) {
2067          oStmt.setString(1, sMessageID);
2068          sTxEmail = (String JavaDoc) oMailEnum.nextElement();
2069          aRecipient = Gadgets.split(pCC.getProperty(sTxEmail),',');
2070
2071          oStmt.setString(2, sTxEmail);
2072          oStmt.setString(3, "cc");
2073
2074          if (aRecipient[0].equals("null") && aRecipient[1].equals("null")) {
2075            oStmt.setNull(4, Types.CHAR);
2076            oStmt.setNull(5, Types.CHAR);
2077            oStmt.setNull(6, Types.CHAR);
2078          }
2079          else if (aRecipient[1].equals("****************************USER")) {
2080            oStmt.setString(4, aRecipient[0]);
2081            oStmt.setString(5, null);
2082            oStmt.setString(6, null);
2083          }
2084          else {
2085            oStmt.setString(4, null);
2086            oStmt.setString(5, aRecipient[0].equals("null") ? null : aRecipient[0]);
2087            oStmt.setString(6, aRecipient[1].equals("null") ? null : aRecipient[1]);
2088          }
2089
2090          if (aRecipient[2].equals("null"))
2091            oStmt.setNull(7, Types.VARCHAR);
2092          else
2093            oStmt.setString(7, aRecipient[2]);
2094
2095          if (DebugFile.trace) DebugFile.writeln("Statement.executeUpdate()");
2096
2097          oStmt.executeUpdate();
2098        } // wend
2099
} // fi (cc)
2100

2101      if (!pBCC.isEmpty()) {
2102        oMailEnum = pBCC.keys();
2103        while (oMailEnum.hasMoreElements()) {
2104          oStmt.setString(1, sMessageID);
2105          sTxEmail = (String JavaDoc) oMailEnum.nextElement();
2106          aRecipient = Gadgets.split(pBCC.getProperty(sTxEmail),',');
2107
2108          oStmt.setString(2, sTxEmail);
2109          oStmt.setString(3, "bcc");
2110
2111          if (aRecipient[0].equals("null") && aRecipient[1].equals("null")) {
2112            oStmt.setNull(4, Types.CHAR);
2113            oStmt.setNull(5, Types.CHAR);
2114            oStmt.setNull(6, Types.CHAR);
2115          }
2116          else if (aRecipient[1].equals("****************************USER")) {
2117            oStmt.setString(4, aRecipient[0]);
2118            oStmt.setNull(5, Types.CHAR);
2119            oStmt.setNull(6, Types.CHAR);
2120          }
2121          else {
2122            oStmt.setNull(4, Types.CHAR);
2123            oStmt.setString(5, aRecipient[0].equals("null") ? null : aRecipient[0]);
2124            oStmt.setString(6, aRecipient[1].equals("null") ? null : aRecipient[1]);
2125          }
2126
2127          if (aRecipient[2].equals("null"))
2128            oStmt.setNull(7, Types.VARCHAR);
2129          else
2130            oStmt.setString(7, aRecipient[2]);
2131
2132          oStmt.executeUpdate();
2133        } // wend
2134
} // fi (bcc)
2135

2136      oStmt.close();
2137      oStmt=null;
2138
2139      oStmt = oConn.prepareStatement("UPDATE "+DB.k_categories+" SET "+DB.len_size+"="+DB.len_size+"+"+String.valueOf(iSize)+" WHERE "+DB.gu_category+"=?");
2140      oStmt.setString(1, getCategory().getString(DB.gu_category));
2141      oStmt.executeUpdate();
2142      oStmt.close();
2143      oStmt=null;
2144
2145    } catch (SQLException JavaDoc sqle) {
2146      try { if (null!=oStmt) oStmt.close(); oStmt=null; } catch (Exception JavaDoc ignore) {}
2147      try { if (null!=oAddr) oAddr.close(); oAddr=null; } catch (Exception JavaDoc ignore) {}
2148      if (DebugFile.trace) DebugFile.decIdent();
2149      throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
2150    }
2151    if (DebugFile.trace) {
2152      DebugFile.decIdent();
2153      DebugFile.writeln("End DBFolder.indexMessage()");
2154    }
2155  } // indexMessage
2156

2157  // ---------------------------------------------------------------------------
2158

2159  private void checkAppendPreconditions()
2160    throws FolderClosedException JavaDoc, StoreClosedException JavaDoc {
2161    // *************************************************************************
2162
// If DBStore is not connected to the database then raise an exception
2163

2164    if (!((DBStore)getStore()).isConnected()) {
2165      if (DebugFile.trace) DebugFile.decIdent();
2166      throw new StoreClosedException JavaDoc(getStore(), "Store is not connected");
2167    }
2168
2169    // *************************************************************************
2170
// If Folder is not opened is read-write mode then raise an exception
2171
if (0==(iOpenMode&READ_WRITE)) {
2172      if (DebugFile.trace) DebugFile.decIdent();
2173      throw new FolderClosedException JavaDoc(this, "Folder is not open is READ_WRITE mode");
2174    }
2175
2176    if ((0==(iOpenMode&MODE_MBOX)) && (0==(iOpenMode&MODE_BLOB))) {
2177      if (DebugFile.trace) DebugFile.decIdent();
2178      throw new FolderClosedException JavaDoc(this, "Folder is not open in MBOX nor BLOB mode");
2179    }
2180  } // checkAppendPreconditions
2181

2182  // ---------------------------------------------------------------------------
2183

2184  /**
2185   * Get Message body taking into account its exact MimeMessage subclass
2186   * @param oMsg MimeMessage
2187   * @return ByteArrayOutputStream
2188   * @throws MessagingException
2189   * @throws IOException
2190   */

2191  private static ByteArrayOutputStream JavaDoc getBodyAsStream(MimeMessage JavaDoc oMsg)
2192    throws MessagingException JavaDoc,IOException JavaDoc {
2193    MimePart JavaDoc oText = null;
2194    ByteArrayOutputStream JavaDoc byStrm;
2195
2196    if (DebugFile.trace) {
2197      DebugFile.writeln("Begin DBFolder.getBodyAsStream([MimeMessage])");
2198      DebugFile.incIdent();
2199      if (null!=oMsg) DebugFile.writeln(oMsg.getClass().getName());
2200                 else DebugFile.writeln("MimeMessage is null");
2201    }
2202
2203    if (oMsg.getClass().getName().equals("com.knowgate.hipermail.DBMimeMessage"))
2204      // If appended message is a DBMimeMessage then use DBMimeMessage.getBody()
2205
// for getting HTML text part or plain text part of the MULTIPART/ALTERNATIVE
2206
oText = ((DBMimeMessage) oMsg).getBody();
2207    else {
2208      // Else if the appended message is a MimeMessage use standard Java Mail getBody() method
2209
oText = new DBMimeMessage(oMsg).getBody();
2210    } // fi
2211

2212    if (DebugFile.trace) {
2213      DebugFile.writeln("MimePart encoding is "+oText.getEncoding());
2214      DebugFile.writeln("MimePart size is "+String.valueOf(oText.getSize()));
2215    }
2216
2217    // *************************************************************************
2218
// Initialize a byte array for containing the message body
2219

2220    if (DebugFile.trace) DebugFile.writeln("ByteArrayOutputStream byOutStrm = new ByteArrayOutputStream("+String.valueOf(oText.getSize()>0 ? oText.getSize() : 8192)+")");
2221
2222    byStrm = new ByteArrayOutputStream JavaDoc(oText.getSize()>0 ? oText.getSize() : 8192);
2223    oText.writeTo(byStrm);
2224
2225    if (DebugFile.trace) {
2226      DebugFile.decIdent();
2227      DebugFile.writeln("End DBFolder.getBodyAsStream() : " + Gadgets.left(new String JavaDoc(byStrm.toByteArray()),100));
2228    }
2229
2230    return byStrm;
2231  } // getBodyAsStream
2232

2233  // ---------------------------------------------------------------------------
2234

2235  /**
2236   *
2237   * @param oMsg MimeMessage
2238   * @return String
2239   * @throws FolderClosedException
2240   * @throws StoreClosedException
2241   * @throws MessagingException
2242   * @throws ArrayIndexOutOfBoundsException
2243   * @throws NullPointerException if oMsg is <b>null</b>
2244   */

2245  public String JavaDoc appendMessage(MimeMessage JavaDoc oMsg)
2246    throws FolderClosedException JavaDoc, StoreClosedException JavaDoc, MessagingException JavaDoc,
2247    ArrayIndexOutOfBoundsException JavaDoc, NullPointerException JavaDoc {
2248
2249  if (oMsg==null) {
2250    throw new NullPointerException JavaDoc("DBFolder.appendMessage() MimeMessage parameter cannot be null");
2251  }
2252
2253    if (DebugFile.trace) {
2254      DebugFile.writeln("Begin DBFolder.appendMessage("+oMsg.getClass().getName()+")");
2255      DebugFile.incIdent();
2256    }
2257
2258    // *************************************************************************
2259
// If Message does not have a GUID then assign a new one.
2260
// Message GUID is not the same as MimeMessage Id.
2261

2262    String JavaDoc gu_mimemsg;
2263    if (oMsg.getClass().getName().equals("com.knowgate.hipermail.DBMimeMessage")) {
2264      gu_mimemsg = ((DBMimeMessage) oMsg).getMessageGuid();
2265      if (((DBMimeMessage) oMsg).getFolder()==null) ((DBMimeMessage) oMsg).setFolder(this);
2266    }
2267    else {
2268      gu_mimemsg = Gadgets.generateUUID();
2269    }
2270
2271    checkAppendPreconditions();
2272
2273    // *************************************************************************
2274
// Mails are assigned by default to the same WorkArea as their recipient user
2275

2276    String JavaDoc gu_workarea = ((DBStore)getStore()).getUser().getString(DB.gu_workarea);
2277
2278    // *************************************************************************
2279
// Gather some MimeMessage headers that will be later written at the database
2280

2281    MboxFile oMBox = null;
2282    ByteArrayOutputStream JavaDoc byOutStrm = null;
2283
2284    try {
2285      long lPosition = -1;
2286      HeadersHelper oHlpr = new HeadersHelper(oMsg);
2287      RecipientsHelper oRecps = new RecipientsHelper(oMsg);
2288      String JavaDoc sMessageID = oHlpr.decodeMessageId(gu_mimemsg);
2289      String JavaDoc sMsgCharSeq = DBMimeMessage.source(oMsg, "ISO8859_1");
2290      if (sMsgCharSeq==null) {
2291        if (DebugFile.trace) {
2292          DebugFile.writeln("DBFolder.appendMessage() : Original message source is null");
2293          DebugFile.decIdent();
2294        }
2295        throw new NullPointerException JavaDoc("DBFolder.appendMessage() : Original message source is null");
2296      } // fi (sMsgCharSeq==null)
2297
String JavaDoc sContentMD5 = oHlpr.getContentMD5();
2298      if (null==sContentMD5) sContentMD5 = HeadersHelper.computeContentMD5(sMsgCharSeq.getBytes());
2299      int iSize = ((iOpenMode&MODE_MBOX)!=0) ? sMsgCharSeq.length() : oMsg.getSize();
2300      Integer JavaDoc oSize = ((iSize>=0) ? new Integer JavaDoc(iSize) : null);
2301
2302      byOutStrm = getBodyAsStream(oMsg);
2303
2304      // *************************************************************************
2305
// Create Mbox file and adquire an exclusive lock on it before start writting on the database
2306

2307      if ((iOpenMode&MODE_MBOX)!=0) {
2308          if (DebugFile.trace) DebugFile.writeln("new File("+Gadgets.chomp(sFolderDir, File.separator)+oCatg.getStringNull(DB.nm_category,"null")+".mbox)");
2309
2310          File JavaDoc oFile = getFile();
2311          lPosition = oFile.length();
2312
2313          if (DebugFile.trace) DebugFile.writeln("message position is " + String.valueOf(lPosition));
2314
2315          oMBox = new MboxFile(oFile, MboxFile.READ_WRITE);
2316
2317          /*
2318          if (DebugFile.trace && (oMsg.getMessageID()!=null)) {
2319            if (oMsg.getMessageID().trim().length()>0) {
2320              int iMsgCount = oMBox.getMessageCount();
2321              for (int m=0; m<iMsgCount; m++) {
2322                CharSequence oCharSeq = oMBox.getMessage(m);
2323                if (oCharSeq.toString().indexOf(oMsg.getMessageID())>0) {
2324                  throw new MessagingException("File " + oFile.getName() + " already contains message " + oMsg.getMessageID() + " at index " + String.valueOf(m));
2325                }
2326              }
2327            }
2328          } // fi (DebugFile.trace)
2329          */

2330      } // fi (MODE_MBOX)
2331

2332      indexMessage(gu_mimemsg, gu_workarea, oMsg, oSize,
2333                   ((iOpenMode&MODE_MBOX)!=0) ? new BigDecimal JavaDoc(lPosition) : null,
2334                   oHlpr.getContentType(),
2335                   oHlpr.getContentID(), sMessageID,
2336                   oHlpr.getDisposition(), sContentMD5,
2337                   oHlpr.getDescription(), oHlpr.getFileName(),
2338                   oHlpr.getEncoding(), oHlpr.getSubject(),
2339                   oHlpr.getPriority(), oHlpr.getFlags(),
2340                   oHlpr.getSentTimestamp(), oHlpr.getReceivedTimestamp(),
2341                   RecipientsHelper.getFromAddress(oMsg),
2342                   RecipientsHelper.getReplyAddress(oMsg),
2343                   oRecps.getRecipients(Message.RecipientType.TO),
2344                   oRecps.getRecipients(Message.RecipientType.CC),
2345                   oRecps.getRecipients(Message.RecipientType.BCC),
2346                   oHlpr.isSpam(), byOutStrm, sMsgCharSeq);
2347
2348      if ((iOpenMode&MODE_MBOX)!=0) {
2349        if (DebugFile.trace) DebugFile.writeln("MboxFile.appendMessage("+(oMsg.getContentID()!= null ? oMsg.getContentID() : "")+")");
2350
2351        oMBox.appendMessage(sMsgCharSeq);
2352
2353        oMBox.close();
2354        oMBox=null;
2355
2356        if (DebugFile.trace && ((iOpenMode&MODE_MBOX)!=0)) {
2357          oMBox = new MboxFile(getFile(), MboxFile.READ_ONLY);
2358          int iMsgCount = oMBox.getMessageCount();
2359          CharSequence JavaDoc sWrittenMsg = oMBox.getMessage(iMsgCount-1);
2360          if (!sMsgCharSeq.equals(sWrittenMsg.toString())) {
2361            DebugFile.writeln ("Readed message source does not match with original message source");
2362            DebugFile.writeln ("**** Original Message ****");
2363            DebugFile.writeln (sMsgCharSeq);
2364            DebugFile.writeln ("**** Readed Message ****");
2365            DebugFile.writeln (sWrittenMsg.toString());
2366          }
2367          oMBox.close();
2368        } // fi
2369

2370      } // fi (MODE_MBOX)
2371

2372      byOutStrm.close();
2373      byOutStrm=null;
2374
2375      if (DebugFile.trace) DebugFile.writeln("Connection.commit()");
2376      oConn.commit();
2377
2378    } catch (OutOfMemoryError JavaDoc oom) {
2379      try { if (null!=byOutStrm) byOutStrm.close(); } catch (Exception JavaDoc ignore) {}
2380      try { if (null!=oMBox) oMBox.close(); } catch (Exception JavaDoc ignore) {}
2381      try { if (null!=oConn) oConn.rollback(); } catch (Exception JavaDoc ignore) {}
2382      if (DebugFile.trace) DebugFile.decIdent();
2383      throw new MessagingException JavaDoc("OutOfMemoryError " + oom.getMessage());
2384    } catch (Exception JavaDoc xcpt) {
2385      try { if (null!=byOutStrm) byOutStrm.close(); } catch (Exception JavaDoc ignore) {}
2386      try { if (oMBox!=null) oMBox.close(); } catch (Exception JavaDoc ignore) {}
2387      try { if (null!=oConn) oConn.rollback(); } catch (Exception JavaDoc ignore) {}
2388      if (DebugFile.trace) DebugFile.decIdent();
2389      throw new MessagingException JavaDoc(xcpt.getClass().getName() + " " + xcpt.getMessage(), xcpt);
2390    }
2391
2392    // End Gathering MimeMessage headers
2393
// *************************************************************************
2394

2395    if (DebugFile.trace) {
2396      DebugFile.decIdent();
2397      DebugFile.writeln("End DBFolder.appendMessage() : " + gu_mimemsg);
2398    }
2399    return gu_mimemsg;
2400  } // appendMessage
2401

2402  // ---------------------------------------------------------------------------
2403

2404  public Message JavaDoc getMessage(int msgnum) throws MessagingException JavaDoc {
2405    return getMessage(String.valueOf(msgnum), 3);
2406  }
2407
2408  // ---------------------------------------------------------------------------
2409

2410  public DBMimeMessage getMessageByGuid(String JavaDoc sMsgGuid) throws MessagingException JavaDoc {
2411    return (DBMimeMessage) getMessage(sMsgGuid, 1);
2412  }
2413
2414  // ---------------------------------------------------------------------------
2415

2416  public DBMimeMessage getMessageByID(String JavaDoc sMsgId) throws MessagingException JavaDoc {
2417    return (DBMimeMessage) getMessage(sMsgId, 2);
2418  }
2419
2420  // ---------------------------------------------------------------------------
2421

2422  public int getMessageCount()
2423    throws FolderClosedException JavaDoc, MessagingException JavaDoc {
2424
2425    PreparedStatement JavaDoc oStmt = null;
2426    ResultSet JavaDoc oRSet = null;
2427    Object JavaDoc oCount;
2428
2429    if (DebugFile.trace) {
2430      DebugFile.writeln("Begin DBFolder.getMessageCount()");
2431      DebugFile.incIdent();
2432    }
2433
2434    // *************************************************************************
2435
// If Folder is not opened then raise an exception
2436
if (!isOpen()) {
2437      if (DebugFile.trace) DebugFile.decIdent();
2438      throw new javax.mail.FolderClosedException JavaDoc(this, "Folder is closed");
2439    }
2440
2441    try {
2442      oStmt = getConnection().prepareStatement("SELECT COUNT(*) FROM "+DB.k_mime_msgs+ " WHERE "+DB.gu_category+"=?", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
2443      oStmt.setString(1, oCatg.getStringNull(DB.gu_category, null));
2444      oRSet = oStmt.executeQuery();
2445      oRSet.next();
2446      oCount = oRSet.getObject(1);
2447      oRSet.close();
2448      oRSet=null;
2449      oStmt.close();
2450      oStmt=null;
2451    } catch (SQLException JavaDoc sqle) {
2452      oCount = new Integer JavaDoc(0);
2453      try { if (null!=oRSet) oRSet.close(); } catch (Exception JavaDoc ignore) {}
2454      try { if (null!=oStmt) oStmt.close(); } catch (Exception JavaDoc ignore) {}
2455      throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
2456    }
2457
2458    if (DebugFile.trace) {
2459      DebugFile.decIdent();
2460      DebugFile.writeln("End DBFolder.getMessageCount() : " + oCount.toString());
2461    }
2462
2463    return Integer.parseInt(oCount.toString());
2464  } // getMessageCount
2465

2466  // ---------------------------------------------------------------------------
2467

2468  public Folder JavaDoc getParent() throws MessagingException JavaDoc {
2469    if (DebugFile.trace) {
2470      DebugFile.writeln("Begin DBFolder.getParent()");
2471      DebugFile.incIdent();
2472    }
2473
2474    if (DebugFile.trace) {
2475      DebugFile.decIdent();
2476      DebugFile.writeln("End DBFolder.getParent() : null");
2477    }
2478
2479    return null;
2480  } // getParent
2481

2482  // ---------------------------------------------------------------------------
2483

2484  public Flags JavaDoc getPermanentFlags() {
2485    Flags JavaDoc oFlgs = new Flags JavaDoc();
2486    oFlgs.add(Flags.Flag.DELETED);
2487    oFlgs.add(Flags.Flag.ANSWERED);
2488    oFlgs.add(Flags.Flag.DRAFT);
2489    oFlgs.add(Flags.Flag.SEEN);
2490    oFlgs.add(Flags.Flag.RECENT);
2491    oFlgs.add(Flags.Flag.FLAGGED);
2492
2493    return oFlgs;
2494  }
2495
2496  // ---------------------------------------------------------------------------
2497

2498  public char getSeparator() throws MessagingException JavaDoc {
2499    return '/';
2500  }
2501
2502  // ---------------------------------------------------------------------------
2503

2504  public Folder JavaDoc[] list(String JavaDoc pattern) throws MessagingException JavaDoc {
2505    return null;
2506  }
2507
2508  // ---------------------------------------------------------------------------
2509

2510  public int getType() throws MessagingException JavaDoc {
2511    return iOpenMode;
2512  }
2513
2514  // ---------------------------------------------------------------------------
2515

2516  public boolean isOpen() {
2517    return (iOpenMode!=0);
2518  }
2519
2520  // ---------------------------------------------------------------------------
2521

2522  /**
2523   * <p>Get message GUID, Id, Number, Subject, From and Reply-To from k_mime_msgs table</p>
2524   * This method is mainly used for testing whether or not a message is already present at current folder.
2525   * @param sMsgId String GUID or Id of message to be rerieved
2526   * @return Properties {gu_mimemsg, id_message, pg_message, tx_subject, tx_email_from, tx_email_reply, nm_from }
2527   * or <b>null</b> if no message with such sMsgId was found referenced at k_mime_msgs
2528   * for current folder
2529   * @throws FolderClosedException
2530   * @throws SQLException
2531   */

2532  public Properties JavaDoc getMessageHeaders(String JavaDoc sMsgId)
2533    throws FolderClosedException JavaDoc, SQLException JavaDoc {
2534
2535    if (DebugFile.trace) {
2536      DebugFile.writeln("Begin DBFolder.getMessageHeaders()");
2537      DebugFile.incIdent();
2538    }
2539
2540    // *************************************************************************
2541
// If Folder is not opened then raise an exception
2542
if (!isOpen()) {
2543      if (DebugFile.trace) DebugFile.decIdent();
2544      throw new javax.mail.FolderClosedException JavaDoc(this, "Folder is closed");
2545    }
2546
2547    Properties JavaDoc oRetVal;
2548    PreparedStatement JavaDoc oStmt;
2549
2550    if (sMsgId.length()==32) {
2551      if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(SELECT " + DB.gu_mimemsg + "," + DB.id_message + "," + DB.pg_message + "," + DB.tx_subject + " FROM " + DB.k_mime_msgs + " WHERE " + DB.gu_mimemsg + "='"+sMsgId+"' OR " + DB.id_message + "='"+sMsgId+"') AND " + DB.gu_category + "='"+getCategoryGuid()+"' AND " + DB.bo_deleted + "<>1)");
2552
2553      oStmt = getConnection().prepareStatement("SELECT " + DB.gu_mimemsg + "," + DB.id_message + "," + DB.pg_message + "," + DB.tx_subject + "," + DB.tx_email_from + "," + DB.tx_email_reply + "," + DB.nm_from +
2554                                               " FROM " + DB.k_mime_msgs +
2555                                               " WHERE (" + DB.gu_mimemsg + "=? OR " + DB.id_message + "=?) AND " + DB.gu_category + "=? AND " + DB.bo_deleted + "<>1",
2556                                               ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
2557      oStmt.setString(1, sMsgId);
2558      oStmt.setString(2, sMsgId);
2559      oStmt.setString(3, getCategoryGuid());
2560    }
2561    else {
2562      if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(SELECT " + DB.gu_mimemsg + "," + DB.id_message + "," + DB.pg_message + "," + DB.tx_subject + "," + DB.tx_email_from + "," + DB.tx_email_reply + "," + DB.nm_from + " FROM " + DB.k_mime_msgs + " WHERE " + DB.id_message + "='"+sMsgId+"' AND " + DB.gu_category + "='"+getCategoryGuid()+"' AND " + DB.bo_deleted + "<>1)");
2563
2564      oStmt = getConnection().prepareStatement("SELECT " + DB.gu_mimemsg + "," + DB.id_message + "," + DB.pg_message + "," + DB.tx_subject + "," + DB.tx_email_from + "," + DB.tx_email_reply + "," + DB.nm_from + " FROM " + DB.k_mime_msgs + " WHERE " + DB.id_message + "=? AND " + DB.gu_category + "=? AND " + DB.bo_deleted + "<>1",
2565                                               ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
2566      oStmt.setString(1, sMsgId);
2567      oStmt.setString(2, getCategoryGuid());
2568    } // fi (sMsgId.length()==32)
2569

2570    ResultSet JavaDoc oRSet = oStmt.executeQuery();
2571
2572    if (oRSet.next()) {
2573      oRetVal = new Properties JavaDoc();
2574      String JavaDoc s;
2575      BigDecimal JavaDoc d;
2576      s = oRSet.getString(1);
2577      if (DebugFile.trace) DebugFile.writeln("gu_mimemsg="+s);
2578      oRetVal.put(DB.gu_mimemsg, s);
2579      s = oRSet.getString(2);
2580      if (!oRSet.wasNull()) oRetVal.put(DB.id_message, s);
2581      d = oRSet.getBigDecimal(3);
2582      if (!oRSet.wasNull()) oRetVal.put(DB.pg_message, d.toString());
2583      s = oRSet.getString(4);
2584      if (!oRSet.wasNull()) oRetVal.put(DB.tx_subject, s);
2585      s = oRSet.getString(5);
2586      if (!oRSet.wasNull()) oRetVal.put(DB.tx_email_from, s);
2587      s = oRSet.getString(6);
2588      if (!oRSet.wasNull()) oRetVal.put(DB.tx_email_reply, s);
2589      s = oRSet.getString(7);
2590      if (!oRSet.wasNull()) oRetVal.put(DB.nm_from, s);
2591    }
2592    else {
2593      if (DebugFile.trace) DebugFile.writeln("message not found");
2594      oRetVal = null;
2595    }
2596
2597    oRSet.close();
2598    oStmt.close();
2599
2600    if (DebugFile.trace) {
2601      DebugFile.decIdent();
2602      if (oRetVal==null)
2603        DebugFile.writeln("End DBFolder.getMessageHeaders() : null");
2604      else
2605        DebugFile.writeln("End DBFolder.getMessageHeaders() : Properties["+String.valueOf(oRetVal.size())+"]");
2606    }
2607
2608    return oRetVal;
2609  } // getMessageHeaders
2610

2611  // ---------------------------------------------------------------------------
2612

2613  public int importMbox(String JavaDoc sMboxFilePath)
2614    throws FileNotFoundException JavaDoc, IOException JavaDoc, MessagingException JavaDoc {
2615
2616    MimeMessage JavaDoc oMsg;
2617    InputStream JavaDoc oMsgStrm;
2618    Session JavaDoc oSession = ((DBStore)getStore()).getSession();
2619    MboxFile oInputMbox = new MboxFile(sMboxFilePath, MboxFile.READ_ONLY);
2620
2621    final int iMsgCount = oInputMbox.getMessageCount();
2622
2623    for (int m=0; m<iMsgCount; m++) {
2624      oMsgStrm = oInputMbox.getMessageAsStream(m);
2625      oMsg = new MimeMessage JavaDoc(oSession, oMsgStrm);
2626      appendMessage(oMsg);
2627      oMsgStrm.close();
2628    }
2629
2630    oInputMbox.close();
2631
2632    return iMsgCount;
2633  } // importMbox
2634

2635  // ---------------------------------------------------------------------------
2636

2637  /**
2638   * Delete every message from the index and rebuild it by re-reading the specified MBOX file
2639   * @param sMboxFilePath String Full path to MBOX file
2640   * @throws FileNotFoundException
2641   * @throws IOException
2642   * @throws MessagingException
2643   * @throws SQLException
2644   */

2645  public void reindexMbox(String JavaDoc sMboxFilePath)
2646    throws FileNotFoundException JavaDoc, IOException JavaDoc, MessagingException JavaDoc, SQLException JavaDoc {
2647
2648    MimeMessage JavaDoc oMsg;
2649    InputStream JavaDoc oMsgStrm;
2650    int iMsgCount;
2651    HeadersHelper oHlpr;
2652    RecipientsHelper oRecps;
2653    BigDecimal JavaDoc dPgMessage;
2654    String JavaDoc sGuMimeMsg;
2655    String JavaDoc sMessageID;
2656    String JavaDoc sMsgCharSeq;
2657    String JavaDoc sContentMD5;
2658    int iSize;
2659    Integer JavaDoc oSize;
2660    MboxFile oInputMbox = null;
2661
2662    if (DebugFile.trace) {
2663      DebugFile.writeln("Begin DBFolder.reindexMbox("+sMboxFilePath+")");
2664      DebugFile.incIdent();
2665    }
2666
2667    try {
2668      ByteArrayOutputStream JavaDoc byOutStrm = null;
2669      Session JavaDoc oSession = ((DBStore)getStore()).getSession();
2670      String JavaDoc sGuWorkArea = ((DBStore)getStore()).getUser().getString(DB.gu_workarea);
2671      String JavaDoc sGuFolder = getCategoryGuid();
2672      oInputMbox = new MboxFile(sMboxFilePath, MboxFile.READ_ONLY);
2673      DBSubset oMsgs = new DBSubset (DB.k_mime_msgs, DB.gu_mimemsg+","+DB.gu_workarea, DB.gu_category+"=?", 1000);
2674      iMsgCount = oMsgs.load(oConn, new Object JavaDoc[]{sGuFolder});
2675
2676      if (DebugFile.trace) DebugFile.writeln(String.valueOf(iMsgCount)+" indexed messages");
2677
2678      for (int m=0; m<iMsgCount; m++)
2679        DBMimeMessage.delete(oConn, sGuFolder, oMsgs.getString(0,m));
2680
2681      iMsgCount = oInputMbox.getMessageCount();
2682
2683      if (DebugFile.trace) DebugFile.writeln(String.valueOf(iMsgCount)+" stored messages");
2684
2685      for (int m=0; m<iMsgCount; m++) {
2686        sGuMimeMsg = Gadgets.generateUUID();
2687        oMsgStrm = oInputMbox.getMessageAsStream(m);
2688        oMsg = new MimeMessage JavaDoc(oSession, oMsgStrm);
2689        oHlpr = new HeadersHelper(oMsg);
2690        oRecps = new RecipientsHelper(oMsg);
2691        dPgMessage = new BigDecimal JavaDoc(m);
2692        sMessageID = oHlpr.decodeMessageId(sGuMimeMsg);
2693        sMsgCharSeq = DBMimeMessage.source(oMsg, "ISO8859_1");
2694        sContentMD5 = oHlpr.getContentMD5();
2695        if (null==sContentMD5) sContentMD5 = HeadersHelper.computeContentMD5(sMsgCharSeq.getBytes());
2696        iSize = ((iOpenMode&MODE_MBOX)!=0) ? sMsgCharSeq.length() : oMsg.getSize();
2697        oSize = (iSize>=0 ? new Integer JavaDoc(iSize) : null);
2698        byOutStrm = getBodyAsStream(oMsg);
2699
2700        indexMessage(Gadgets.generateUUID(), sGuWorkArea, oMsg, oSize,
2701                   ((iOpenMode&MODE_MBOX)!=0) ? new BigDecimal JavaDoc(oInputMbox.getMessagePosition(m)) : null,
2702                   oHlpr.getContentType(),
2703                   oHlpr.getContentID(), sMessageID,
2704                   oHlpr.getDisposition(), sContentMD5,
2705                   oHlpr.getDescription(), oHlpr.getFileName(),
2706                   oHlpr.getEncoding(), oHlpr.getSubject(),
2707                   oHlpr.getPriority(), oHlpr.getFlags(),
2708                   oHlpr.getSentTimestamp(), oHlpr.getReceivedTimestamp(),
2709                   RecipientsHelper.getFromAddress(oMsg),
2710                   RecipientsHelper.getReplyAddress(oMsg),
2711                   oRecps.getRecipients(Message.RecipientType.TO),
2712                   oRecps.getRecipients(Message.RecipientType.CC),
2713                   oRecps.getRecipients(Message.RecipientType.BCC),
2714                   oHlpr.isSpam(), byOutStrm, sMsgCharSeq);
2715
2716        byOutStrm.close();
2717        oMsgStrm.close();
2718      } // next
2719
oInputMbox.close();
2720      oInputMbox=null;
2721      oConn.commit();
2722    } catch (FileNotFoundException JavaDoc fnfe) {
2723      try {oConn.rollback();} catch (Exception JavaDoc ignore) {}
2724      throw fnfe;
2725    } catch (IOException JavaDoc ioe) {
2726      try {oConn.rollback();} catch (Exception JavaDoc ignore) {}
2727      throw ioe;
2728    } catch (MessagingException JavaDoc me) {
2729      try {oConn.rollback();} catch (Exception JavaDoc ignore) {}
2730      throw me;
2731    } catch (SQLException JavaDoc sqle) {
2732      try {oConn.rollback();} catch (Exception JavaDoc ignore) {}
2733      throw sqle;
2734    } finally {
2735      try { if (null!=oInputMbox) oInputMbox.close(); } catch (Exception JavaDoc ignore) {}
2736    }
2737    if (DebugFile.trace) {
2738      DebugFile.decIdent();
2739      DebugFile.writeln("End DBFolder.reindexMbox()");
2740    }
2741  } // reindexMbox
2742

2743  // ---------------------------------------------------------------------------
2744

2745  /**
2746   * Delete very message from th eindex and rebuild it by reading the default MBOX file for this folder
2747   * @throws FileNotFoundException
2748   * @throws IOException
2749   * @throws MessagingException
2750   * @throws SQLException
2751   */

2752  public void reindexMbox()
2753    throws FileNotFoundException JavaDoc, IOException JavaDoc, MessagingException JavaDoc, SQLException JavaDoc {
2754    reindexMbox(getFilePath());
2755  }
2756
2757  // ===========================================================================
2758
public static final short ClassId = 800;
2759}
2760
Popular Tags