KickJava   Java API By Example, From Geeks To Geeks.

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


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.lang.UnsupportedOperationException JavaDoc;
36
37 import java.io.File JavaDoc;
38 import java.io.IOException JavaDoc;
39 import java.io.InputStream JavaDoc;
40 import java.io.FileNotFoundException JavaDoc;
41
42 import java.sql.DriverManager JavaDoc;
43 import java.sql.Connection JavaDoc;
44 import java.sql.SQLException JavaDoc;
45 import java.sql.PreparedStatement JavaDoc;
46 import java.sql.ResultSet JavaDoc;
47
48 import java.net.ProtocolException JavaDoc;
49
50 import javax.mail.Store JavaDoc;
51 import javax.mail.Session JavaDoc;
52 import javax.mail.URLName JavaDoc;
53 import javax.mail.Folder JavaDoc;
54 import javax.mail.MessagingException JavaDoc;
55 import javax.mail.StoreClosedException JavaDoc;
56 import javax.mail.AuthenticationFailedException JavaDoc;
57 import javax.mail.FolderNotFoundException JavaDoc;
58 import javax.mail.internet.MimeBodyPart JavaDoc;
59 import javax.mail.internet.MimeMessage JavaDoc;
60
61 import com.knowgate.debug.DebugFile;
62 import com.knowgate.jdc.JDCConnection;
63 import com.knowgate.dataobjs.DB;
64 import com.knowgate.dataobjs.DBSubset;
65 import com.knowgate.misc.Environment;
66 import com.knowgate.misc.Gadgets;
67 import com.knowgate.hipergate.Category;
68 import com.knowgate.acl.*;
69 import com.knowgate.dfs.FileSystem;
70
71 import javax.activation.CommandInfo JavaDoc;
72 import javax.activation.CommandMap JavaDoc;
73 import javax.activation.MailcapCommandMap JavaDoc;
74
75 /**
76  * Manages local storage of mail messages at RDBMS and MBOX files
77  * @author Sergio Montoro Ten
78  * @version 2.2
79  */

80
81 public class DBStore extends javax.mail.Store JavaDoc {
82
83   private JDCConnection oConn;
84   private ACLUser oUser;
85   private URLName JavaDoc oURL;
86
87   public DBStore (javax.mail.Session JavaDoc session, URLName JavaDoc url)
88     throws MessagingException JavaDoc {
89     super(session, url);
90
91     Class JavaDoc cStore = null;
92
93     try {
94       cStore = Class.forName("javax.mail.Store");
95     } catch (ClassNotFoundException JavaDoc cnf) {}
96
97     oURL = new URLName JavaDoc(url.getProtocol(), url.getHost(), url.getPort(), url.getFile(), url.getUsername(), url.getPassword());
98
99     if (null!=url.getFile()) {
100       File JavaDoc oDir = new File JavaDoc(url.getFile());
101
102       if (!oDir.exists()) {
103         FileSystem oFS = new FileSystem();
104         try {
105           oFS.mkdirs(url.getFile());
106         } catch (Exception JavaDoc e) {
107           if (DebugFile.trace) DebugFile.writeln(e.getClass().getName() + " " + e.getMessage());
108           throw new MessagingException JavaDoc(e.getMessage(), e);
109         }
110       }
111     }
112
113     oConn = null;
114     oUser = null;
115   }
116
117   // ----------------------------------------------------------------------------------------
118

119   /**
120    * Create new DBStore instance and open connection to the database
121    * @param oMailSession Session
122    * @param sProfile String
123    * @param sMBoxDir String
124    * @param sGuUser String
125    * @param sPwd String
126    * @return DBStore
127    * @throws MessagingException
128    */

129   public static DBStore open (Session JavaDoc oMailSession, String JavaDoc sProfile,
130                               String JavaDoc sMBoxDir, String JavaDoc sGuUser, String JavaDoc sPwd)
131     throws MessagingException JavaDoc {
132     DBStore oNewInstance = new DBStore (oMailSession, new URLName JavaDoc("jdbc://", sProfile, -1, sMBoxDir, sGuUser, sPwd));
133     oNewInstance.connect(sProfile, sGuUser, sPwd);
134     return oNewInstance;
135   } // open
136

137   // ---------------------------------------------------------------------------
138

139   public JDCConnection getConnection() {
140     return oConn;
141   }
142
143   // ---------------------------------------------------------------------------
144

145   public Session JavaDoc getSession() {
146     return session;
147   }
148
149   // ---------------------------------------------------------------------------
150

151   public boolean isConnected() {
152     return (oConn!=null);
153   }
154
155   // ---------------------------------------------------------------------------
156

157   /**
158    *
159    * @param host Name of profile file without extension { hipergate, real, test, demo }
160    * @param port Not used, must be -1
161    * @param user GUID of user to be authenticated
162    * @param password User password in clear text
163    * @return <b>true</b>
164    * @throws MessagingException
165    */

166   protected boolean protocolConnect(String JavaDoc host, int port, String JavaDoc user, String JavaDoc password)
167     throws AuthenticationFailedException JavaDoc, MessagingException JavaDoc {
168
169     if (DebugFile.trace) {
170       DebugFile.writeln("Begin DBStore.protocolConnect("+host+", "+user+", ...)");
171       DebugFile.incIdent();
172     }
173
174     if (oConn!=null || isConnected()) {
175       if (DebugFile.trace) DebugFile.decIdent();
176       throw new MessagingException JavaDoc("DBStore ia already connected");
177     }
178
179     String JavaDoc dburl = Environment.getProfileVar(host, "dburl");
180     String JavaDoc dbusr = Environment.getProfileVar(host, "dbuser");
181     String JavaDoc dbpwd = Environment.getProfileVar(host, "dbpassword");
182     String JavaDoc schema = Environment.getProfileVar(host, "schema", "");
183
184     try {
185       if (DebugFile.trace)
186         DebugFile.writeln("DriverManager.getConnection("+dburl+", "+dbusr+", ...)");
187
188       if (schema.length()>0)
189         oConn = new JDCConnection(DriverManager.getConnection(dburl, dbusr, dbpwd), null, schema);
190       else
191         oConn = new JDCConnection(DriverManager.getConnection(dburl, dbusr, dbpwd), null);
192
193       oConn.setAutoCommit(false);
194
195       short iAuth = ACL.autenticate(oConn, user, password, ACL.PWD_CLEAR_TEXT);
196
197       if (iAuth<0) {
198         oConn.close();
199         oConn = null;
200         if (DebugFile.trace) DebugFile.decIdent();
201         throw new AuthenticationFailedException JavaDoc(ACL.getErrorMessage(iAuth) + " (" + user + ")");
202       }
203       else {
204         oUser = new ACLUser(oConn, user);
205         setConnected(true);
206       }
207     }
208     catch (SQLException JavaDoc sqle) {
209       if (DebugFile.trace) DebugFile.decIdent();
210       throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
211     }
212
213     if (DebugFile.trace) {
214       DebugFile.decIdent();
215       DebugFile.writeln("End DBStore.protocolConnect()");
216     }
217
218     return true;
219   }
220
221   // ---------------------------------------------------------------------------
222

223   public void connect (String JavaDoc host, String JavaDoc user, String JavaDoc password)
224     throws MessagingException JavaDoc {
225
226     protocolConnect (host, -1, user, password);
227   }
228
229   // ---------------------------------------------------------------------------
230

231   public void connect() throws MessagingException JavaDoc {
232     URLName JavaDoc oURLName = getURLName();
233
234     protocolConnect (oURLName.getHost(), oURLName.getPort(), oURLName.getUsername(), oURLName.getPassword());
235   }
236
237   // ---------------------------------------------------------------------------
238

239   public void close() throws MessagingException JavaDoc {
240     if (DebugFile.trace) {
241       DebugFile.writeln("Begin DBStore.close()");
242       DebugFile.incIdent();
243     }
244     if (null!=oConn && isConnected()) {
245       try {
246         oConn.close();
247         oConn=null;
248         oUser=null;
249         setConnected(false);
250       }
251       catch (SQLException JavaDoc sqle) {
252         throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
253       }
254     }
255     else {
256       throw new StoreClosedException JavaDoc(this, "Store already closed");
257     }
258     if (DebugFile.trace) {
259       DebugFile.decIdent();
260       DebugFile.writeln("End DBStore.close()");
261     }
262   }
263
264   // ---------------------------------------------------------------------------
265

266   /**
267    * Calls getFolder(oURL.getFile());
268    * @param oURL URLName
269    * @return DBFolder instance
270    * @throws StoreClosedException
271    * @throws FolderNotFoundException
272    * @throws MessagingException
273    */

274   public Folder JavaDoc getFolder(URLName JavaDoc oURL)
275     throws StoreClosedException JavaDoc,FolderNotFoundException JavaDoc,MessagingException JavaDoc {
276
277     return getFolder(oURL.getFile());
278   }
279
280   // ---------------------------------------------------------------------------
281

282   /**
283    * <p>Get folder by guid or name</p>
284    * @param sFolderName String This parameter may be either the folder GUID or its name
285    * valid folder names are {inbox, outbox, drafts, sent, spam, deleted, received}
286    * @return DBFolder instance
287    * @throws StoreClosedException
288    * @throws FolderNotFoundException
289    * @throws MessagingException
290    */

291   public Folder JavaDoc getFolder(String JavaDoc sFolderName)
292     throws StoreClosedException JavaDoc,FolderNotFoundException JavaDoc,MessagingException JavaDoc {
293
294     if (DebugFile.trace) {
295       DebugFile.writeln("Begin DBStore.getFolder("+sFolderName+")");
296       DebugFile.incIdent();
297     }
298
299     if (sFolderName==null) {
300       if (DebugFile.trace) DebugFile.decIdent();
301       throw new NullPointerException JavaDoc("DBStore.getFolder() folder name cannot be null");
302     }
303     if (sFolderName.length()==0) {
304       if (DebugFile.trace) DebugFile.decIdent();
305       throw new NullPointerException JavaDoc("DBStore.getFolder() folder name cannot be an empty string");
306     }
307
308     if (!isConnected()) {
309       if (DebugFile.trace) DebugFile.decIdent();
310       throw new StoreClosedException JavaDoc(this, "Store is closed");
311     }
312
313     DBFolder oRetVal = new DBFolder(this, sFolderName);
314     boolean bExistsGuid = false;
315     PreparedStatement JavaDoc oStmt = null;
316     ResultSet JavaDoc oRSet = null;
317
318     try {
319       if (sFolderName.length()==32) {
320         if (DebugFile.trace) DebugFile.writeln("Connection.prepareStatement(SELECT NULL FROM "+DB.k_categories+" WHERE "+DB.gu_category+"='"+sFolderName+"')");
321
322         oStmt = this.getConnection().prepareStatement("SELECT NULL FROM "+DB.k_categories+" WHERE "+DB.gu_category+"=?");
323         oStmt.setString(1, sFolderName);
324         oRSet = oStmt.executeQuery();
325         bExistsGuid = oRSet.next();
326         oRSet.close();
327         oStmt.close();
328       }
329       else
330         bExistsGuid = false;
331
332       if (bExistsGuid) {
333         oRetVal.getCategory().load(oConn, new Object JavaDoc[] {sFolderName});
334       }
335       else {
336         String JavaDoc sGuid = oUser.getMailFolder(oConn, sFolderName);
337
338         if (null==sGuid) {
339           if (DebugFile.trace) DebugFile.decIdent();
340           throw new FolderNotFoundException JavaDoc(oRetVal, sFolderName);
341         }
342         oRetVal.getCategory().load(oConn, new Object JavaDoc[] {sGuid});
343       }
344     }
345     catch (SQLException JavaDoc sqle) {
346       if (DebugFile.trace) DebugFile.decIdent();
347       throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
348     }
349
350     if (DebugFile.trace) {
351       DebugFile.decIdent();
352       DebugFile.writeln("End DBStore.getFolder("+sFolderName+")");
353     }
354
355     return oRetVal;
356   } // getFolder
357

358   // ---------------------------------------------------------------------------
359

360   /**
361    * Same as getFolder() but casting result to DBFolder
362    * @param sFolderName String
363    * @return DBFolder
364    * @throws StoreClosedException
365    * @throws FolderNotFoundException
366    * @throws MessagingException
367    */

368   public DBFolder getDBFolder(String JavaDoc sFolderName)
369     throws StoreClosedException JavaDoc,FolderNotFoundException JavaDoc,MessagingException JavaDoc {
370     return (DBFolder) getFolder(sFolderName);
371   }
372
373   // ---------------------------------------------------------------------------
374

375   /**
376    * Get DBFolder and open it in the specified mode
377    * @param sFolderName String
378    * @param iMode int {DBFolder.READ_ONLY | DBFolder.READ_WRITE}
379    * @return DBFolder
380    * @throws StoreClosedException
381    * @throws FolderNotFoundException
382    * @throws MessagingException
383    */

384   public DBFolder openDBFolder(String JavaDoc sFolderName, int iMode)
385     throws StoreClosedException JavaDoc,FolderNotFoundException JavaDoc,MessagingException JavaDoc {
386     DBFolder oFldr = (DBFolder) getFolder(sFolderName);
387     oFldr.open(iMode);
388     return oFldr;
389   }
390
391   // ---------------------------------------------------------------------------
392

393   /**
394    * Get inbox Folder
395    * @return DBFolder
396    * @throws StoreClosedException
397    * @throws FolderNotFoundException
398    * @throws MessagingException
399    */

400   public Folder JavaDoc getDefaultFolder()
401     throws StoreClosedException JavaDoc,FolderNotFoundException JavaDoc,MessagingException JavaDoc {
402
403     return getFolder("inbox");
404   } // getDefaultFolder
405

406   // ---------------------------------------------------------------------------
407

408   public Folder JavaDoc[] getPersonalNamespaces()
409     throws StoreClosedException JavaDoc,FolderNotFoundException JavaDoc,MessagingException JavaDoc {
410
411     DBFolder[] aRetVal;
412
413     if (!isConnected())
414       throw new StoreClosedException JavaDoc(this, "Store is closed");
415
416     try {
417
418       String JavaDoc sGuid = oUser.getMailRoot(oConn);
419
420       if (null == sGuid)
421         throw new FolderNotFoundException JavaDoc(new DBFolder(this, "mailroot"), "mailroot");
422
423       Category oMailRoot = new Category(sGuid);
424       DBSubset oChilds = oMailRoot.getChilds(oConn);
425       int iFolders = oChilds.getRowCount();
426
427       if (0==iFolders)
428         aRetVal = null;
429       else {
430         Object JavaDoc[] oPK = new Object JavaDoc[]{null};
431         DBFolder oFR;
432         aRetVal = new DBFolder[iFolders];
433         for (int f=0; f<iFolders; f++) {
434           oPK[0] = oChilds.get(0,f);
435           oFR = new DBFolder(this, null);
436           oFR.getCategory().load(oConn, oPK);
437           aRetVal[f] = oFR;
438         } // next
439
} // fi
440
}
441     catch (SQLException JavaDoc sqle) {
442       throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
443     }
444     return aRetVal;
445   }
446
447   // ---------------------------------------------------------------------------
448

449   public Folder JavaDoc[] getSharedNamespaces() {
450     return null;
451   }
452
453   // ---------------------------------------------------------------------------
454

455   public Folder JavaDoc[] getUserNamespaces(String JavaDoc sUserId)
456       throws StoreClosedException JavaDoc,FolderNotFoundException JavaDoc,MessagingException JavaDoc {
457     DBFolder[] aRetVal;
458
459     if (!isConnected())
460       throw new StoreClosedException JavaDoc(this, "Store is closed");
461
462     try {
463
464       ACLUser oUsr = new ACLUser(sUserId);
465
466       String JavaDoc sGuid = oUsr.getMailRoot(oConn);
467
468       if (null == sGuid)
469         throw new FolderNotFoundException JavaDoc(new DBFolder(this, "mailroot"), "mailroot");
470
471       Category oMailRoot = new Category(sGuid);
472       DBSubset oChilds = oMailRoot.getChilds(oConn);
473       int iFolders = oChilds.getRowCount();
474
475       if (0==iFolders)
476         aRetVal = null;
477       else {
478         Object JavaDoc[] oPK = new Object JavaDoc[]{null};
479         DBFolder oFR;
480         aRetVal = new DBFolder[iFolders];
481         for (int f=0; f<iFolders; f++) {
482           oPK[0] = oChilds.get(0,f);
483           oFR = new DBFolder(this, null);
484           oFR.getCategory().load(oConn, oPK);
485           aRetVal[f] = oFR;
486         } // next
487
} // fi
488
}
489     catch (SQLException JavaDoc sqle) {
490       throw new MessagingException JavaDoc(sqle.getMessage(), sqle);
491     }
492     return aRetVal;
493   } // getUserNamespaces
494

495   // ---------------------------------------------------------------------------
496

497   public URLName JavaDoc getURLName() {
498     return oURL;
499   }
500
501   // ---------------------------------------------------------------------------
502

503   public ACLUser getUser() {
504     return oUser;
505   }
506
507   // ----------------------------------------------------------------------------------------
508

509   /**
510    * Fetch a message from a POP3 or other remote folder into de local cache
511    * @param oIncomingFldr Incoming Folder (POP3, IMAP, or other)
512    * @param iMsgNum int Message number
513    * @return DBMimeMessage
514    * @throws MessagingException
515    */

516   public DBMimeMessage preFetchMessage(Folder JavaDoc oIncomingFldr, int iMsgNum)
517     throws MessagingException JavaDoc {
518
519     if (DebugFile.trace) {
520       DebugFile.writeln("Begin DBStore.preFetchMessage([Folder],"+String.valueOf(iMsgNum)+")");
521       DebugFile.incIdent();
522     }
523
524     if (null==oIncomingFldr)
525       throw new MessagingException JavaDoc("Unable to open inbox folder",
526                                    new NullPointerException JavaDoc("DBStore.preFetchMessage() Folder is null"));
527
528     boolean bWasConnected = isConnected();
529     if (!bWasConnected) connect();
530     DBFolder oInboxFldr = (DBFolder) getDefaultFolder();
531     oInboxFldr.open(Folder.READ_WRITE);
532     boolean bWasOpen = oIncomingFldr.isOpen();
533     if (!bWasOpen) oIncomingFldr.open(Folder.READ_ONLY);
534     DBMimeMessage oMimeMsg = new DBMimeMessage ((MimeMessage JavaDoc) oIncomingFldr.getMessage(iMsgNum));
535     oInboxFldr.appendMessage(oMimeMsg);
536     if (!bWasOpen) oIncomingFldr.close(false);
537     if (!bWasConnected) close();
538
539     if (DebugFile.trace) {
540       DebugFile.decIdent();
541       DebugFile.writeln("End DBStore.preFetchMessage() : " + oMimeMsg.getMessageGuid());
542     }
543
544     return oMimeMsg;
545   } // prefetchMessage
546

547   // ----------------------------------------------------------------------------------------
548

549   public static String JavaDoc MBoxDirectory(String JavaDoc sProfile, int iDomainId, String JavaDoc sWorkAreaGu)
550     throws ProtocolException JavaDoc {
551     String JavaDoc sSep = System.getProperty("file.separator");
552     String JavaDoc sFileProtocol = Environment.getProfileVar(sProfile, "fileprotocol", "file://");
553     String JavaDoc sMBoxDir;
554     if (sFileProtocol.equals("file://"))
555       sMBoxDir = sFileProtocol + Environment.getProfilePath(sProfile, "storage") + "domains" + sSep + String.valueOf(iDomainId) + sSep + "workareas" + sSep + sWorkAreaGu;
556     else
557       throw new java.net.ProtocolException JavaDoc(sFileProtocol);
558     return sMBoxDir;
559     } // MBoxDirectory
560
}
561
Popular Tags