Back to index

lightning-sunbird  0.9+nobinonly
nsMsgQuote.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 "nsIURL.h"
00040 #include "nsIInputStream.h"
00041 #include "nsIOutputStream.h"
00042 #include "nsIGenericFactory.h"
00043 #include "nsIServiceManager.h"
00044 #include "nsIStreamListener.h"
00045 #include "nsIStreamConverter.h"
00046 #include "nsIStreamConverterService.h"
00047 #include "nsIMimeStreamConverter.h"
00048 #include "nsMimeTypes.h"
00049 #include "nsICharsetConverterManager.h"
00050 #include "prprf.h"
00051 #include "nsMsgQuote.h" 
00052 #include "nsMsgCompUtils.h"
00053 #include "nsIMsgMessageService.h"
00054 #include "nsMsgUtils.h"
00055 #include "nsMsgDeliveryListener.h"
00056 #include "nsNetUtil.h"
00057 #include "nsMsgMimeCID.h"
00058 #include "nsMsgCompCID.h"
00059 #include "nsMsgCompose.h"
00060 #include "nsMsgMailNewsUrl.h"
00061 #include "nsXPIDLString.h"
00062 
00063 NS_IMPL_THREADSAFE_ADDREF(nsMsgQuoteListener)
00064 NS_IMPL_THREADSAFE_RELEASE(nsMsgQuoteListener)
00065 
00066 NS_INTERFACE_MAP_BEGIN(nsMsgQuoteListener)
00067    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMsgQuoteListener)
00068    NS_INTERFACE_MAP_ENTRY(nsIMimeStreamConverterListener)
00069    NS_INTERFACE_MAP_ENTRY(nsIMsgQuoteListener)
00070 NS_INTERFACE_MAP_END
00071 
00072 nsMsgQuoteListener::nsMsgQuoteListener()
00073 {
00074 }
00075 
00076 nsMsgQuoteListener::~nsMsgQuoteListener()
00077 {
00078 }
00079 
00080 NS_IMETHODIMP nsMsgQuoteListener::SetMsgQuote(nsIMsgQuote * msgQuote)
00081 {
00082        mMsgQuote = do_GetWeakReference(msgQuote);
00083   return NS_OK;
00084 }
00085 
00086 NS_IMETHODIMP nsMsgQuoteListener::GetMsgQuote(nsIMsgQuote ** aMsgQuote)
00087 {
00088   nsresult rv = NS_OK;
00089   if (aMsgQuote)
00090   {
00091     nsCOMPtr<nsIMsgQuote> msgQuote = do_QueryReferent(mMsgQuote);
00092     *aMsgQuote = msgQuote;
00093     NS_IF_ADDREF(*aMsgQuote);
00094   }
00095   else
00096     rv = NS_ERROR_NULL_POINTER;
00097 
00098   return rv;
00099 }
00100 
00101 nsresult nsMsgQuoteListener::OnHeadersReady(nsIMimeHeaders * headers)
00102 {
00103        nsCOMPtr<nsIStreamListener> aStreamListener;
00104   nsCOMPtr<nsIMsgQuote> msgQuote = do_QueryReferent(mMsgQuote);
00105 
00106   if (msgQuote)
00107     msgQuote->GetStreamListener(getter_AddRefs(aStreamListener));
00108 
00109   nsCOMPtr<nsIMsgQuotingOutputStreamListener>
00110     quotingOutputStreamListener(do_QueryInterface(aStreamListener));
00111   if (quotingOutputStreamListener)
00112     quotingOutputStreamListener->SetMimeHeaders(headers);
00113   return NS_OK;
00114 }
00115 
00116 //
00117 // Implementation...
00118 //
00119 nsMsgQuote::nsMsgQuote()
00120 {
00121   mQuoteHeaders = PR_FALSE;
00122   mQuoteListener = nsnull;
00123 }
00124 
00125 nsMsgQuote::~nsMsgQuote()
00126 {
00127 }
00128 
00129 NS_IMPL_THREADSAFE_ADDREF(nsMsgQuote)
00130 NS_IMPL_THREADSAFE_RELEASE(nsMsgQuote)
00131 
00132 NS_INTERFACE_MAP_BEGIN(nsMsgQuote)
00133    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMsgQuote)
00134    NS_INTERFACE_MAP_ENTRY(nsIMsgQuote)
00135    NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
00136 NS_INTERFACE_MAP_END
00137 
00138 NS_IMETHODIMP nsMsgQuote::GetStreamListener(nsIStreamListener ** aStreamListener)
00139 {
00140   nsresult rv = NS_OK;
00141   if (aStreamListener)
00142   {
00143     *aStreamListener = mStreamListener;
00144     NS_IF_ADDREF(*aStreamListener);
00145   }
00146   else
00147     rv = NS_ERROR_NULL_POINTER;
00148 
00149   return rv;
00150 }
00151 
00152 nsresult
00153 nsMsgQuote::QuoteMessage(const char *msgURI, PRBool quoteHeaders, nsIStreamListener * aQuoteMsgStreamListener,
00154                          const char * aMsgCharSet, PRBool headersOnly)
00155 {
00156   nsresult  rv;
00157   if (!msgURI)
00158     return NS_ERROR_INVALID_ARG;
00159 
00160   mQuoteHeaders = quoteHeaders;
00161   mStreamListener = aQuoteMsgStreamListener;
00162 
00163   nsCAutoString msgUri(msgURI);
00164   PRBool fileUrl = !strncmp(msgURI, "file:", 5);
00165   PRBool forwardedMessage = PL_strstr(msgURI, "&realtype=message/rfc822") != nsnull;
00166   nsCOMPtr<nsIURI> aURL;
00167   if (fileUrl || forwardedMessage)
00168     rv = NS_NewURI(getter_AddRefs(aURL), msgURI);
00169   else
00170   {
00171     nsCOMPtr <nsIMsgMessageService> msgService;
00172     rv = GetMessageServiceFromURI(msgURI, getter_AddRefs(msgService));
00173     if (NS_FAILED(rv)) return rv;
00174     rv = msgService->GetUrlForUri(msgURI, getter_AddRefs(aURL), nsnull);
00175   }
00176   if (NS_FAILED(rv)) return rv;
00177 
00178   nsCOMPtr <nsIURL> mailNewsUrl = do_QueryInterface(aURL, &rv);
00179   NS_ENSURE_SUCCESS(rv,rv);
00180 
00181   nsCAutoString queryPart;
00182   rv = mailNewsUrl->GetQuery(queryPart);
00183   if (!queryPart.IsEmpty())
00184     queryPart.Append('&');
00185 
00186   if (headersOnly) /* We don't need to quote the message body but we still need to extract the headers */
00187     queryPart.Append("header=only");
00188   else if (quoteHeaders)
00189     queryPart.Append("header=quote");
00190   else
00191     queryPart.Append("header=quotebody");
00192   rv = mailNewsUrl->SetQuery(queryPart);
00193   NS_ENSURE_SUCCESS(rv,rv);
00194 
00195   // if we were given a non empty charset, then use it
00196   if (aMsgCharSet && *aMsgCharSet)
00197   {
00198     nsCOMPtr<nsIMsgI18NUrl> i18nUrl (do_QueryInterface(aURL));
00199     if (i18nUrl)
00200       i18nUrl->SetCharsetOverRide(aMsgCharSet);
00201   }
00202 
00203   mQuoteListener = do_CreateInstance(NS_MSGQUOTELISTENER_CONTRACTID, &rv);
00204   if (NS_FAILED(rv)) return rv;
00205   mQuoteListener->SetMsgQuote(this);
00206 
00207   // funky magic go get the isupports for this class which inherits from multiple interfaces.
00208   nsISupports * supports;
00209   QueryInterface(NS_GET_IID(nsISupports), (void **) &supports);
00210   nsCOMPtr<nsISupports> quoteSupport = supports;
00211   NS_IF_RELEASE(supports);
00212 
00213   // now we want to create a necko channel for this url and we want to open it
00214   mQuoteChannel = nsnull;
00215   nsCOMPtr<nsIIOService> netService(do_GetService(NS_IOSERVICE_CONTRACTID, &rv));
00216   if (NS_FAILED(rv)) return rv;
00217   rv = netService->NewChannelFromURI(aURL, getter_AddRefs(mQuoteChannel));
00218   if (NS_FAILED(rv)) return rv;
00219   nsCOMPtr<nsISupports> ctxt = do_QueryInterface(aURL);
00220 
00221   nsCOMPtr<nsIStreamConverterService> streamConverterService = 
00222            do_GetService("@mozilla.org/streamConverters;1", &rv);
00223   NS_ENSURE_SUCCESS(rv,rv);
00224 
00225   nsCOMPtr<nsIStreamListener> convertedListener;
00226   rv = streamConverterService->AsyncConvertData("message/rfc822",
00227                                                 "application/vnd.mozilla.xul+xml",
00228                                                 mStreamListener,
00229                                                 quoteSupport,
00230                                                 getter_AddRefs(convertedListener));
00231   if (NS_FAILED(rv)) return rv;
00232 
00233   //  now try to open the channel passing in our display consumer as the listener 
00234   rv = mQuoteChannel->AsyncOpen(convertedListener, ctxt);
00235   return rv;
00236 }
00237 
00238 NS_IMETHODIMP
00239 nsMsgQuote::GetQuoteListener(nsIMimeStreamConverterListener** aQuoteListener)
00240 {
00241     if (!aQuoteListener || !mQuoteListener)
00242         return NS_ERROR_NULL_POINTER;
00243     *aQuoteListener = mQuoteListener;
00244     NS_ADDREF(*aQuoteListener);
00245     return NS_OK;
00246 }
00247 
00248 NS_IMETHODIMP
00249 nsMsgQuote::GetQuoteChannel(nsIChannel** aQuoteChannel)
00250 {
00251     if (!aQuoteChannel || !mQuoteChannel)
00252         return NS_ERROR_NULL_POINTER;
00253     *aQuoteChannel = mQuoteChannel;
00254     NS_ADDREF(*aQuoteChannel);
00255     return NS_OK;
00256 }