Back to index

lightning-sunbird  0.9+nobinonly
nsMailboxService.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "msgCore.h"    // precompiled header...
00040 #include "nsCOMPtr.h"
00041 
00042 #include "nsMailboxService.h"
00043 #include "nsIMsgMailSession.h"
00044 #include "nsMailboxUrl.h"
00045 #include "nsIMsgMailNewsUrl.h"
00046 #include "nsMailboxProtocol.h"
00047 #include "nsIMsgDatabase.h"
00048 #include "nsMsgDBCID.h"
00049 #include "nsMsgKeyArray.h"
00050 #include "nsLocalUtils.h"
00051 #include "nsMsgLocalCID.h"
00052 #include "nsMsgBaseCID.h"
00053 #include "nsIDocShell.h"
00054 #include "nsIPop3Service.h"
00055 #include "nsMsgUtils.h"
00056 #include "nsNetUtil.h"
00057 #include "nsIDocShellLoadInfo.h"
00058 #include "nsIWebNavigation.h"
00059 #include "prprf.h"
00060 #include "nsEscape.h"
00061 #include "nsIMsgHdr.h"
00062 #include "nsIFileURL.h"
00063 
00064 static NS_DEFINE_CID(kCMailboxUrl, NS_MAILBOXURL_CID);
00065 static NS_DEFINE_CID(kCPop3ServiceCID, NS_POP3SERVICE_CID);
00066 
00067 nsMailboxService::nsMailboxService()
00068 {
00069     mPrintingOperation = PR_FALSE;
00070 }
00071 
00072 nsMailboxService::~nsMailboxService()
00073 {}
00074 
00075 NS_IMPL_ISUPPORTS4(nsMailboxService, nsIMailboxService, nsIMsgMessageService, nsIProtocolHandler, nsIMsgMessageFetchPartService)
00076 
00077 nsresult nsMailboxService::ParseMailbox(nsIMsgWindow *aMsgWindow, nsFileSpec& aMailboxPath, nsIStreamListener *aMailboxParser, 
00078                                                                       nsIUrlListener * aUrlListener, nsIURI ** aURL)
00079 {
00080   nsresult rv;
00081   nsCOMPtr<nsIMailboxUrl> mailboxurl = do_CreateInstance(kCMailboxUrl, &rv);
00082   if (NS_SUCCEEDED(rv) && mailboxurl)
00083   {
00084     nsCOMPtr<nsIMsgMailNewsUrl> url = do_QueryInterface(mailboxurl);
00085     // okay now generate the url string
00086     nsFilePath filePath(aMailboxPath); // convert to file url representation...
00087     nsCAutoString buf;
00088     NS_EscapeURL((const char *)filePath,-1,
00089                      esc_Minimal|esc_Forced|esc_AlwaysCopy,buf);
00090     url->SetUpdatingFolder(PR_TRUE);
00091     url->SetMsgWindow(aMsgWindow);
00092     char *temp = PR_smprintf("mailbox://%s", buf.get());
00093     url->SetSpec(nsDependentCString(temp));
00094     PR_Free(temp);
00095     mailboxurl->SetMailboxParser(aMailboxParser);
00096     if (aUrlListener)
00097       url->RegisterListener(aUrlListener);
00098     
00099     RunMailboxUrl(url, nsnull);
00100     
00101     if (aURL)
00102     {
00103       *aURL = url;
00104       NS_IF_ADDREF(*aURL);
00105     }
00106   }
00107   
00108   return rv;
00109 }
00110                                            
00111 nsresult nsMailboxService::CopyMessage(const char * aSrcMailboxURI,
00112                               nsIStreamListener * aMailboxCopyHandler,
00113                               PRBool moveMessage,
00114                               nsIUrlListener * aUrlListener,
00115                               nsIMsgWindow *aMsgWindow,
00116                               nsIURI **aURL)
00117 {
00118     nsMailboxAction mailboxAction = nsIMailboxUrl::ActionMoveMessage;
00119     if (!moveMessage)
00120         mailboxAction = nsIMailboxUrl::ActionCopyMessage;
00121   return FetchMessage(aSrcMailboxURI, aMailboxCopyHandler, aMsgWindow, aUrlListener, nsnull, mailboxAction, nsnull, aURL);
00122 }
00123 
00124 nsresult nsMailboxService::CopyMessages(nsMsgKeyArray *msgKeys,
00125                               nsIMsgFolder *srcFolder,
00126                               nsIStreamListener * aMailboxCopyHandler,
00127                               PRBool moveMessage,
00128                               nsIUrlListener * aUrlListener,
00129                               nsIMsgWindow *aMsgWindow,
00130                               nsIURI **aURL)
00131 {
00132   nsresult rv = NS_OK;
00133   NS_ENSURE_ARG(srcFolder);
00134   nsCOMPtr<nsIMailboxUrl> mailboxurl;
00135 
00136   nsMailboxAction actionToUse = nsIMailboxUrl::ActionMoveMessage;
00137   if (!moveMessage)
00138      actionToUse = nsIMailboxUrl::ActionCopyMessage;
00139 
00140   nsCOMPtr <nsIMsgDBHdr> msgHdr;
00141   nsCOMPtr <nsIMsgDatabase> db;
00142   srcFolder->GetMsgDatabase(aMsgWindow, getter_AddRefs(db));
00143   if (db)
00144   {
00145     db->GetMsgHdrForKey(msgKeys->GetAt(0), getter_AddRefs(msgHdr));
00146     if (msgHdr)
00147     {
00148       nsXPIDLCString uri;
00149       srcFolder->GetUriForMsg(msgHdr, getter_Copies(uri));
00150       rv = PrepareMessageUrl(uri, aUrlListener, actionToUse , getter_AddRefs(mailboxurl), aMsgWindow);
00151 
00152       if (NS_SUCCEEDED(rv))
00153       {
00154         nsCOMPtr<nsIURI> url = do_QueryInterface(mailboxurl);
00155         nsCOMPtr<nsIMsgMailNewsUrl> msgUrl (do_QueryInterface(url));
00156         nsCOMPtr<nsIMailboxUrl> mailboxUrl (do_QueryInterface(url));
00157         msgUrl->SetMsgWindow(aMsgWindow);
00158 
00159         mailboxUrl->SetMoveCopyMsgKeys(msgKeys->GetArray(), msgKeys->GetSize());
00160         rv = RunMailboxUrl(url, aMailboxCopyHandler); 
00161       }
00162     }
00163   }
00164   if (aURL)
00165     mailboxurl->QueryInterface(NS_GET_IID(nsIURI), (void **) aURL);
00166 
00167   return rv;
00168 }
00169 
00170 nsresult nsMailboxService::FetchMessage(const char* aMessageURI,
00171                                         nsISupports * aDisplayConsumer, 
00172                                         nsIMsgWindow * aMsgWindow,
00173                                         nsIUrlListener * aUrlListener,
00174                                         const char * aFileName, /* only used by open attachment... */
00175                                         nsMailboxAction mailboxAction,
00176                                         const char * aCharsetOverride,
00177                                         nsIURI ** aURL)
00178 {
00179   nsresult rv = NS_OK;
00180   nsCOMPtr<nsIMailboxUrl> mailboxurl;
00181   
00182   nsMailboxAction actionToUse = mailboxAction;
00183   
00184   nsCOMPtr <nsIURI> url;
00185 
00186   nsCAutoString uriString(aMessageURI);
00187 
00188   if (!strncmp(aMessageURI, "file:", 5))
00189   {
00190     PRInt64 fileSize;
00191     nsCOMPtr<nsIURI> fileUri;
00192     rv = NS_NewURI(getter_AddRefs(fileUri), aMessageURI);
00193     NS_ENSURE_SUCCESS(rv, rv);
00194     nsCOMPtr <nsIFileURL> fileUrl = do_QueryInterface(fileUri, &rv);
00195     NS_ENSURE_SUCCESS(rv, rv);
00196     nsCOMPtr <nsIFile> file;
00197     rv = fileUrl->GetFile(getter_AddRefs(file));
00198     NS_ENSURE_SUCCESS(rv, rv);
00199     file->GetFileSize(&fileSize);
00200     nsCAutoString uriString(aMessageURI);
00201     uriString.ReplaceSubstring(NS_LITERAL_CSTRING("file:"), NS_LITERAL_CSTRING("mailbox:"));
00202     uriString.Append(NS_LITERAL_CSTRING("&number=0"));
00203     rv = NS_NewURI(getter_AddRefs(url), uriString);
00204     NS_ENSURE_SUCCESS(rv, rv);
00205 
00206     nsCOMPtr<nsIMsgMailNewsUrl> msgurl = do_QueryInterface(url);
00207     if (msgurl)
00208     {
00209       msgurl->SetMsgWindow(aMsgWindow);
00210       nsCOMPtr <nsIMailboxUrl> mailboxUrl = do_QueryInterface(msgurl, &rv);
00211       mailboxUrl->SetMessageSize((PRUint32) fileSize);
00212       nsCOMPtr <nsIMsgHeaderSink> headerSink;
00213        // need to tell the header sink to capture some headers to create a fake db header
00214        // so we can do reply to a .eml file or a rfc822 msg attachment.
00215       if (aMsgWindow)
00216         aMsgWindow->GetMsgHeaderSink(getter_AddRefs(headerSink));
00217       if (headerSink)
00218       {
00219         nsCOMPtr <nsIMsgDBHdr> dummyHeader;
00220         headerSink->GetDummyMsgHeader(getter_AddRefs(dummyHeader));
00221         if (dummyHeader)
00222           dummyHeader->SetMessageSize((PRUint32) fileSize);
00223       }
00224     }
00225   }
00226   else
00227   {
00228 
00229     // this happens with forward inline of message/rfc822 attachment
00230     // opened in a stand-alone msg window.
00231     PRInt32 typeIndex = typeIndex = uriString.Find("&type=application/x-message-display");
00232     if (typeIndex != kNotFound)
00233     {
00234       uriString.Cut(typeIndex, sizeof("&type=application/x-message-display") - 1);
00235       rv = NS_NewURI(getter_AddRefs(url), uriString.get());
00236       mailboxurl = do_QueryInterface(url);
00237     }
00238     else
00239       rv = PrepareMessageUrl(aMessageURI, aUrlListener, actionToUse , getter_AddRefs(mailboxurl), aMsgWindow);
00240   
00241     if (NS_SUCCEEDED(rv))
00242     {
00243       url = do_QueryInterface(mailboxurl);
00244       nsCOMPtr<nsIMsgMailNewsUrl> msgUrl (do_QueryInterface(url));
00245       msgUrl->SetMsgWindow(aMsgWindow);
00246       nsCOMPtr<nsIMsgI18NUrl> i18nurl (do_QueryInterface(msgUrl));
00247       i18nurl->SetCharsetOverRide(aCharsetOverride);
00248       if (aFileName)
00249         msgUrl->SetFileName(nsDependentCString(aFileName));
00250     }
00251   }
00252     
00253   // instead of running the mailbox url like we used to, let's try to run the url in the docshell...
00254   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aDisplayConsumer, &rv));
00255   // if we were given a docShell, run the url in the docshell..otherwise just run it normally.
00256   if (NS_SUCCEEDED(rv) && docShell)
00257   {
00258     nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
00259     // DIRTY LITTLE HACK --> if we are opening an attachment we want the docshell to
00260     // treat this load as if it were a user click event. Then the dispatching stuff will be much
00261     // happier.
00262     if (mailboxAction == nsIMailboxUrl::ActionFetchPart)
00263     {
00264       docShell->CreateLoadInfo(getter_AddRefs(loadInfo));
00265       loadInfo->SetLoadType(nsIDocShellLoadInfo::loadLink);
00266     }
00267     rv = docShell->LoadURI(url, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, PR_FALSE);
00268   }
00269   else
00270     rv = RunMailboxUrl(url, aDisplayConsumer); 
00271  
00272   if (aURL && mailboxurl)
00273     mailboxurl->QueryInterface(NS_GET_IID(nsIURI), (void **) aURL);
00274   
00275   return rv;
00276 }
00277 
00278 NS_IMETHODIMP nsMailboxService::FetchMimePart(nsIURI *aURI, const char *aMessageURI, nsISupports *aDisplayConsumer, nsIMsgWindow *aMsgWindow, nsIUrlListener *aUrlListener, nsIURI **aURL)
00279 {
00280   nsCOMPtr<nsIMsgMailNewsUrl> msgUrl (do_QueryInterface(aURI));
00281   msgUrl->SetMsgWindow(aMsgWindow);
00282   
00283   // set up the url listener
00284   if (aUrlListener)
00285     msgUrl->RegisterListener(aUrlListener);
00286   
00287   return RunMailboxUrl(msgUrl, aDisplayConsumer); 
00288 }
00289 
00290 NS_IMETHODIMP nsMailboxService::DisplayMessage(const char* aMessageURI,
00291                                                nsISupports * aDisplayConsumer,
00292                                                nsIMsgWindow * aMsgWindow,
00293                                                nsIUrlListener * aUrlListener,
00294                                                const char * aCharsetOveride,
00295                                                nsIURI ** aURL)
00296 {
00297   return FetchMessage(aMessageURI, aDisplayConsumer,
00298     aMsgWindow,aUrlListener, nsnull,
00299     nsIMailboxUrl::ActionFetchMessage, aCharsetOveride, aURL);
00300 }
00301 
00302 NS_IMETHODIMP
00303 nsMailboxService::StreamMessage(const char *aMessageURI, nsISupports *aConsumer, 
00304                                    nsIMsgWindow *aMsgWindow,
00305                                    nsIUrlListener *aUrlListener, 
00306                                         PRBool /* aConvertData */,
00307                                         const char *aAdditionalHeader,
00308                                    nsIURI **aURL)
00309 {
00310     // The mailbox protocol object will look for "header=filter" or 
00311     // "header=attach" to decide if it wants to convert the data instead of 
00312     // using aConvertData. It turns out to be way too hard to pass aConvertData 
00313     // all the way over to the mailbox protocol object.
00314     nsCAutoString aURIString(aMessageURI);
00315     if (aAdditionalHeader)
00316     {
00317       aURIString.FindChar('?') == kNotFound ? aURIString += "?" : aURIString += "&";
00318       aURIString += "header=";
00319       aURIString += aAdditionalHeader;
00320     }
00321 
00322     return FetchMessage(aURIString.get(), aConsumer, aMsgWindow, aUrlListener, nsnull, 
00323                                         nsIMailboxUrl::ActionFetchMessage, nsnull, aURL);
00324 }
00325 
00326 NS_IMETHODIMP nsMailboxService::OpenAttachment(const char *aContentType, 
00327                                                const char *aFileName,
00328                                                const char *aUrl, 
00329                                                const char *aMessageUri, 
00330                                                nsISupports *aDisplayConsumer, 
00331                                                nsIMsgWindow *aMsgWindow, 
00332                                                nsIUrlListener *aUrlListener)
00333 {
00334   nsCOMPtr <nsIURI> URL;
00335   nsCAutoString urlString(aUrl);
00336   urlString += "&type=";
00337   urlString += aContentType;
00338   urlString += "&filename=";
00339   urlString += aFileName;
00340   CreateStartupUrl(urlString.get(), getter_AddRefs(URL));
00341   nsresult rv;
00342   // try to run the url in the docshell...
00343   nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aDisplayConsumer, &rv));
00344   // if we were given a docShell, run the url in the docshell..otherwise just run it normally.
00345   if (NS_SUCCEEDED(rv) && docShell)
00346   {
00347     nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
00348     // DIRTY LITTLE HACK --> since we are opening an attachment we want the docshell to
00349     // treat this load as if it were a user click event. Then the dispatching stuff will be much
00350     // happier.
00351     docShell->CreateLoadInfo(getter_AddRefs(loadInfo));
00352     loadInfo->SetLoadType(nsIDocShellLoadInfo::loadLink);
00353     return docShell->LoadURI(URL, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, PR_FALSE);
00354   }
00355   return RunMailboxUrl(URL, aDisplayConsumer); 
00356   
00357 }
00358 
00359 
00360 NS_IMETHODIMP 
00361 nsMailboxService::SaveMessageToDisk(const char *aMessageURI, 
00362                                     nsIFileSpec *aFile, 
00363                                     PRBool aAddDummyEnvelope, 
00364                                     nsIUrlListener *aUrlListener,
00365                                     nsIURI **aURL,
00366                                     PRBool canonicalLineEnding,
00367                                     nsIMsgWindow *aMsgWindow)
00368 {
00369   nsresult rv = NS_OK;
00370   nsCOMPtr<nsIMailboxUrl> mailboxurl;
00371   
00372   rv = PrepareMessageUrl(aMessageURI, aUrlListener, nsIMailboxUrl::ActionSaveMessageToDisk, getter_AddRefs(mailboxurl), aMsgWindow);
00373   
00374   if (NS_SUCCEEDED(rv))
00375   {
00376     nsCOMPtr<nsIMsgMessageUrl> msgUrl = do_QueryInterface(mailboxurl);
00377     if (msgUrl)
00378     {
00379       msgUrl->SetMessageFile(aFile);
00380       msgUrl->SetAddDummyEnvelope(aAddDummyEnvelope);
00381       msgUrl->SetCanonicalLineEnding(canonicalLineEnding);
00382     }
00383     
00384     nsCOMPtr<nsIURI> url = do_QueryInterface(mailboxurl);
00385     rv = RunMailboxUrl(url);
00386   }
00387   
00388   if (aURL)
00389     mailboxurl->QueryInterface(NS_GET_IID(nsIURI), (void **) aURL);
00390   
00391   return rv;
00392 }
00393 
00394 NS_IMETHODIMP nsMailboxService::GetUrlForUri(const char *aMessageURI, nsIURI **aURL, nsIMsgWindow *aMsgWindow)
00395 {
00396   if (!strncmp(aMessageURI, "file:", 5) || PL_strstr(aMessageURI, "type=application/x-message-display")
00397     || !strncmp(aMessageURI, "mailbox:", 8))
00398     return NS_NewURI(aURL, aMessageURI);
00399 
00400   nsresult rv = NS_OK;
00401   nsCOMPtr<nsIMailboxUrl> mailboxurl;
00402   rv = PrepareMessageUrl(aMessageURI, nsnull, nsIMailboxUrl::ActionFetchMessage, getter_AddRefs(mailboxurl), aMsgWindow);
00403   if (NS_SUCCEEDED(rv) && mailboxurl)
00404     rv = mailboxurl->QueryInterface(NS_GET_IID(nsIURI), (void **) aURL);
00405   return rv;
00406 }
00407 
00408 // Takes a mailbox url, this method creates a protocol instance and loads the url
00409 // into the protocol instance.
00410 nsresult nsMailboxService::RunMailboxUrl(nsIURI * aMailboxUrl, nsISupports * aDisplayConsumer)
00411 {
00412   // create a protocol instance to run the url..
00413   nsresult rv = NS_OK;
00414   nsMailboxProtocol * protocol = new nsMailboxProtocol(aMailboxUrl);
00415   
00416   if (protocol)
00417   {
00418     rv = protocol->Initialize(aMailboxUrl);
00419     if (NS_FAILED(rv)) 
00420     {
00421       delete protocol;
00422       return rv;
00423     }
00424     NS_ADDREF(protocol);
00425     rv = protocol->LoadUrl(aMailboxUrl, aDisplayConsumer);
00426     NS_RELEASE(protocol); // after loading, someone else will have a ref cnt on the mailbox
00427   }
00428               
00429   return rv;
00430 }
00431 
00432 // This function takes a message uri, converts it into a file path & msgKey 
00433 // pair. It then turns that into a mailbox url object. It also registers a url
00434 // listener if appropriate. AND it can take in a mailbox action and set that field
00435 // on the returned url as well.
00436 nsresult nsMailboxService::PrepareMessageUrl(const char * aSrcMsgMailboxURI, nsIUrlListener * aUrlListener,
00437                                              nsMailboxAction aMailboxAction, nsIMailboxUrl ** aMailboxUrl,
00438                                              nsIMsgWindow *msgWindow)
00439 {
00440   nsresult rv = CallCreateInstance(kCMailboxUrl, aMailboxUrl);
00441   if (NS_SUCCEEDED(rv) && aMailboxUrl && *aMailboxUrl)
00442   {
00443     // okay now generate the url string
00444     char * urlSpec;
00445     nsCAutoString folderURI;
00446     nsFileSpec folderPath;
00447     nsMsgKey msgKey;
00448     const char *part = PL_strstr(aSrcMsgMailboxURI, "part=");
00449     const char *header = PL_strstr(aSrcMsgMailboxURI, "header=");
00450     rv = nsParseLocalMessageURI(aSrcMsgMailboxURI, folderURI, &msgKey);
00451     NS_ENSURE_SUCCESS(rv,rv);
00452     rv = nsLocalURI2Path(kMailboxRootURI, folderURI.get(), folderPath);
00453     
00454     if (NS_SUCCEEDED(rv))
00455     {
00456       // set up the url spec and initialize the url with it.
00457       nsFilePath filePath(folderPath); // convert to file url representation...
00458       nsCAutoString buf;
00459       NS_EscapeURL((const char *)filePath,-1,
00460                    esc_Directory|esc_Forced|esc_AlwaysCopy,buf);
00461       if (mPrintingOperation)
00462         urlSpec = PR_smprintf("mailbox://%s?number=%d&header=print", buf.get(), msgKey);
00463       else if (part)
00464         urlSpec = PR_smprintf("mailbox://%s?number=%d&%s", buf.get(), msgKey, part);
00465       else if (header)
00466         urlSpec = PR_smprintf("mailbox://%s?number=%d&%s", buf.get(), msgKey, header);
00467       else
00468         urlSpec = PR_smprintf("mailbox://%s?number=%d", buf.get(), msgKey);
00469       
00470       nsCOMPtr <nsIMsgMailNewsUrl> url = do_QueryInterface(*aMailboxUrl);
00471       url->SetSpec(nsDependentCString(urlSpec));
00472       PR_Free(urlSpec);
00473       
00474       (*aMailboxUrl)->SetMailboxAction(aMailboxAction);
00475       
00476       // set up the url listener
00477       if (aUrlListener)
00478         rv = url->RegisterListener(aUrlListener);
00479       
00480       url->SetMsgWindow(msgWindow);
00481       nsCOMPtr<nsIMsgMessageUrl> msgUrl = do_QueryInterface(url);
00482       if (msgUrl)
00483       {
00484         msgUrl->SetOriginalSpec(aSrcMsgMailboxURI);
00485         msgUrl->SetUri(aSrcMsgMailboxURI);
00486       }
00487       
00488     } // if we got a url
00489   } // if we got a url
00490   
00491   return rv;
00492 }
00493 
00494 NS_IMETHODIMP nsMailboxService::GetScheme(nsACString &aScheme)
00495 {
00496        aScheme = "mailbox";
00497        return NS_OK;
00498 }
00499 
00500 NS_IMETHODIMP nsMailboxService::GetDefaultPort(PRInt32 *aDefaultPort)
00501 {
00502        nsresult rv = NS_OK;
00503        if (aDefaultPort)
00504               *aDefaultPort = -1;  // mailbox doesn't use a port!!!!!
00505        else
00506               rv = NS_ERROR_NULL_POINTER;
00507        return rv;    
00508 }
00509 
00510 NS_IMETHODIMP nsMailboxService::AllowPort(PRInt32 port, const char *scheme, PRBool *_retval)
00511 {
00512     // don't override anything.  
00513     *_retval = PR_FALSE;
00514     return NS_OK;
00515 }
00516 
00517 NS_IMETHODIMP nsMailboxService::GetProtocolFlags(PRUint32 *result)
00518 {
00519     *result = URI_STD;
00520     return NS_OK;    
00521 }
00522 
00523 NS_IMETHODIMP nsMailboxService::NewURI(const nsACString &aSpec,
00524                                        const char *aOriginCharset,
00525                                        nsIURI *aBaseURI,
00526                                        nsIURI **_retval)
00527 {
00528     nsresult rv = NS_OK;
00529     nsACString::const_iterator b, e;
00530     if (FindInReadable(NS_LITERAL_CSTRING("?uidl="), aSpec.BeginReading(b), aSpec.EndReading(e)) ||
00531         FindInReadable(NS_LITERAL_CSTRING("&uidl="), aSpec.BeginReading(b), aSpec.EndReading(e)))
00532   {
00533     nsCOMPtr<nsIProtocolHandler> handler = 
00534              do_GetService(kCPop3ServiceCID, &rv);
00535     if (NS_SUCCEEDED(rv))
00536         rv = handler->NewURI(aSpec, aOriginCharset, aBaseURI, _retval);
00537   }
00538   else
00539   {
00540     nsCOMPtr<nsIURI> aMsgUri = do_CreateInstance(kCMailboxUrl, &rv);
00541         
00542     if (NS_SUCCEEDED(rv))
00543     {
00544       if (aBaseURI) 
00545       {
00546         nsCAutoString newSpec;
00547         rv = aBaseURI->Resolve(aSpec, newSpec);
00548         if (NS_FAILED(rv))
00549           return rv;
00550         aMsgUri->SetSpec(newSpec);
00551       } 
00552       else 
00553       {
00554         aMsgUri->SetSpec(aSpec);
00555       }
00556       NS_ADDREF(*_retval = aMsgUri);
00557     }
00558   }
00559 
00560   return rv;
00561 }
00562 
00563 NS_IMETHODIMP nsMailboxService::NewChannel(nsIURI *aURI, nsIChannel **_retval)
00564 {
00565   NS_ENSURE_ARG_POINTER(aURI);
00566   nsresult rv = NS_OK;
00567   nsMailboxProtocol * protocol = new nsMailboxProtocol(aURI);
00568   if (protocol)
00569   {
00570     rv = protocol->Initialize(aURI);
00571     if (NS_FAILED(rv)) 
00572     {
00573       delete protocol;
00574       return rv;
00575     }
00576     rv = protocol->QueryInterface(NS_GET_IID(nsIChannel), (void **) _retval);
00577   }
00578   else
00579     rv = NS_ERROR_NULL_POINTER;
00580   
00581   return rv;
00582 }
00583 
00584 nsresult nsMailboxService::DisplayMessageForPrinting(const char* aMessageURI,
00585                                                      nsISupports * aDisplayConsumer,
00586                                                      nsIMsgWindow * aMsgWindow,
00587                                                      nsIUrlListener * aUrlListener,
00588                                                      nsIURI ** aURL)
00589 {
00590   mPrintingOperation = PR_TRUE;
00591   nsresult rv = FetchMessage(aMessageURI, aDisplayConsumer, aMsgWindow,aUrlListener, nsnull, 
00592     nsIMailboxUrl::ActionFetchMessage, nsnull, aURL);
00593   mPrintingOperation = PR_FALSE;
00594   return rv;
00595 }
00596 
00597 NS_IMETHODIMP nsMailboxService::Search(nsIMsgSearchSession *aSearchSession, nsIMsgWindow *aMsgWindow, nsIMsgFolder *aMsgFolder, const char *aMessageUri)
00598 {
00599   return NS_ERROR_NOT_IMPLEMENTED;
00600 }
00601 
00602 nsresult 
00603 nsMailboxService::DecomposeMailboxURI(const char * aMessageURI, nsIMsgFolder ** aFolder, nsMsgKey *aMsgKey)
00604 {
00605   NS_ENSURE_ARG_POINTER(aMessageURI);
00606   NS_ENSURE_ARG_POINTER(aFolder);
00607   NS_ENSURE_ARG_POINTER(aMsgKey);
00608   
00609   nsresult rv = NS_OK;
00610   nsCAutoString folderURI;
00611   rv = nsParseLocalMessageURI(aMessageURI, folderURI, aMsgKey);
00612   NS_ENSURE_SUCCESS(rv,rv);
00613 
00614   nsCOMPtr <nsIRDFService> rdf = do_GetService("@mozilla.org/rdf/rdf-service;1",&rv);
00615   NS_ENSURE_SUCCESS(rv,rv);
00616 
00617   nsCOMPtr<nsIRDFResource> res;
00618   rv = rdf->GetResource(folderURI, getter_AddRefs(res));
00619   NS_ENSURE_SUCCESS(rv,rv);
00620 
00621   rv = res->QueryInterface(NS_GET_IID(nsIMsgFolder), (void **) aFolder);
00622   NS_ENSURE_SUCCESS(rv,rv);
00623 
00624   return NS_OK;
00625 }
00626 
00627 NS_IMETHODIMP
00628 nsMailboxService::MessageURIToMsgHdr(const char *uri, nsIMsgDBHdr **_retval)
00629 {
00630   NS_ENSURE_ARG_POINTER(uri);
00631   NS_ENSURE_ARG_POINTER(_retval);
00632 
00633   nsresult rv = NS_OK;
00634 
00635   nsCOMPtr<nsIMsgFolder> folder;
00636   nsMsgKey msgKey;
00637 
00638   rv = DecomposeMailboxURI(uri, getter_AddRefs(folder), &msgKey);
00639   NS_ENSURE_SUCCESS(rv,rv);
00640 
00641   rv = folder->GetMessageHeader(msgKey, _retval);
00642   NS_ENSURE_SUCCESS(rv,rv);
00643   return NS_OK;
00644 }