changes for autosubscribe. bug #11075. handle the case where they have a news server

already, and the case where they don't.  still more work to be done here, but the basics
work.

also, turn nsMessengerMigrator::CopyIdentity() into nsMsgIdentity::Copy() and
use that in migration and news account creation during autosubscribe.  r=alecf
This commit is contained in:
sspitzer%netscape.com 2000-04-21 00:03:02 +00:00
parent 4816e3c914
commit 9bc8a565f4
11 changed files with 223 additions and 108 deletions

View File

@ -39,7 +39,7 @@ interface nsIMsgAccountManager : nsISupports {
void removeAccount(in nsIMsgAccount account);
void removeIdentity(in nsIMsgIdentity identity);
void duplicateAccount(in nsIMsgAccount account);
/*
* creates a new identity and assigns it a new, unique "key"
*/

View File

@ -109,5 +109,8 @@ interface nsIMsgIdentity : nsISupports {
*/
attribute nsISmtpServer smtpServer;
/* copy the attributes of the identity we pass in */
void copy(in nsIMsgIdentity identity);
wstring toString();
};

View File

@ -193,62 +193,6 @@ static NS_DEFINE_CID(kAddressBookCID, NS_ADDRESSBOOK_CID);
} \
}
#define COPY_IDENTITY_FILE_VALUE(SRC_ID,DEST_ID,MACRO_GETTER,MACRO_SETTER) \
{ \
nsresult macro_rv; \
nsCOMPtr <nsIFileSpec>macro_spec; \
macro_rv = SRC_ID->MACRO_GETTER(getter_AddRefs(macro_spec)); \
if (NS_FAILED(macro_rv)) return macro_rv; \
DEST_ID->MACRO_SETTER(macro_spec); \
}
#define COPY_IDENTITY_INT_VALUE(SRC_ID,DEST_ID,MACRO_GETTER,MACRO_SETTER) \
{ \
nsresult macro_rv; \
PRInt32 macro_oldInt; \
macro_rv = SRC_ID->MACRO_GETTER(&macro_oldInt); \
if (NS_FAILED(macro_rv)) return macro_rv; \
DEST_ID->MACRO_SETTER(macro_oldInt); \
}
#define COPY_IDENTITY_BOOL_VALUE(SRC_ID,DEST_ID,MACRO_GETTER,MACRO_SETTER) \
{ \
nsresult macro_rv; \
PRBool macro_oldBool; \
macro_rv = SRC_ID->MACRO_GETTER(&macro_oldBool); \
if (NS_FAILED(macro_rv)) return macro_rv; \
DEST_ID->MACRO_SETTER(macro_oldBool); \
}
#define COPY_IDENTITY_STR_VALUE(SRC_ID,DEST_ID,MACRO_GETTER,MACRO_SETTER) \
{ \
nsXPIDLCString macro_oldStr; \
nsresult macro_rv; \
macro_rv = SRC_ID->MACRO_GETTER(getter_Copies(macro_oldStr)); \
if (NS_FAILED(macro_rv)) return macro_rv; \
if (!macro_oldStr) { \
DEST_ID->MACRO_SETTER(""); \
} \
else { \
DEST_ID->MACRO_SETTER(macro_oldStr); \
} \
}
static const PRUnichar unicharEmptyString[] = { (PRUnichar)'\0' };
#define COPY_IDENTITY_WSTR_VALUE(SRC_ID,DEST_ID,MACRO_GETTER,MACRO_SETTER) \
{ \
nsXPIDLString macro_oldStr; \
nsresult macro_rv; \
macro_rv = SRC_ID->MACRO_GETTER(getter_Copies(macro_oldStr)); \
if (NS_FAILED(macro_rv)) return macro_rv; \
if (!macro_oldStr) { \
DEST_ID->MACRO_SETTER(unicharEmptyString); \
} \
else { \
DEST_ID->MACRO_SETTER(macro_oldStr); \
} \
}
#define MIGRATE_SIMPLE_FILE_PREF_TO_BOOL_PREF(PREFNAME,MACRO_OBJECT,MACRO_METHOD) \
{ \
@ -739,7 +683,7 @@ nsMessengerMigrator::MigrateIdentity(nsIMsgIdentity *identity)
/* SetUsernameIfNecessary() can fail. */
//if (NS_FAILED(rv)) return rv;
/* NOTE: if you add prefs here, make sure you update CopyIdentity() */
/* NOTE: if you add prefs here, make sure you update nsMsgIdentity::Copy() */
MIGRATE_SIMPLE_STR_PREF(PREF_4X_MAIL_IDENTITY_USEREMAIL,identity,SetEmail)
MIGRATE_SIMPLE_WSTR_PREF(PREF_4X_MAIL_IDENTITY_USERNAME,identity,SetFullName)
MIGRATE_SIMPLE_STR_PREF(PREF_4X_MAIL_IDENTITY_REPLY_TO,identity,SetReplyTo)
@ -748,7 +692,7 @@ nsMessengerMigrator::MigrateIdentity(nsIMsgIdentity *identity)
MIGRATE_SIMPLE_FILE_PREF_TO_FILE_PREF(PREF_4X_MAIL_SIGNATURE_FILE,identity,SetSignature);
MIGRATE_SIMPLE_FILE_PREF_TO_BOOL_PREF(PREF_4X_MAIL_SIGNATURE_FILE,identity,SetAttachSignature);
MIGRATE_SIMPLE_INT_PREF(PREF_4X_MAIL_SIGNATURE_DATE,identity,SetSignatureDate);
/* NOTE: if you add prefs here, make sure you update CopyIdentity() */
/* NOTE: if you add prefs here, make sure you update nsMsgIdentity::Copy() */
return NS_OK;
}
@ -1198,9 +1142,9 @@ nsMessengerMigrator::MigrateMovemailAccount(nsIMsgIdentity *identity)
account->SetIncomingServer(server);
account->AddIdentity(copied_identity);
// make this new identity to copy of the identity
// make this new identity a copy of the identity
// that we created out of the 4.x prefs
rv = CopyIdentity(identity,copied_identity);
rv = copied_identity->Copy(identity);
if (NS_FAILED(rv)) return rv;
// XXX: this probably won't work yet...
@ -1325,9 +1269,9 @@ nsMessengerMigrator::MigratePopAccount(nsIMsgIdentity *identity)
account->SetIncomingServer(server);
account->AddIdentity(copied_identity);
// make this new identity to copy of the identity
// make this new identity a copy of the identity
// that we created out of the 4.x prefs
rv = CopyIdentity(identity,copied_identity);
rv = copied_identity->Copy(identity);
if (NS_FAILED(rv)) return rv;
rv = SetMailCopiesAndFolders(copied_identity, (const char *)username, (const char *)hostname);
@ -1494,23 +1438,6 @@ nsMessengerMigrator::MigrateImapAccounts(nsIMsgIdentity *identity)
return NS_OK;
}
nsresult
nsMessengerMigrator::CopyIdentity(nsIMsgIdentity *srcIdentity, nsIMsgIdentity *destIdentity)
{
COPY_IDENTITY_BOOL_VALUE(srcIdentity,destIdentity,GetComposeHtml,SetComposeHtml)
COPY_IDENTITY_STR_VALUE(srcIdentity,destIdentity,GetEmail,SetEmail)
COPY_IDENTITY_STR_VALUE(srcIdentity,destIdentity,GetReplyTo,SetReplyTo)
COPY_IDENTITY_WSTR_VALUE(srcIdentity,destIdentity,GetFullName,SetFullName)
COPY_IDENTITY_WSTR_VALUE(srcIdentity,destIdentity,GetOrganization,SetOrganization)
COPY_IDENTITY_STR_VALUE(srcIdentity,destIdentity,GetDraftFolder,SetDraftFolder)
COPY_IDENTITY_STR_VALUE(srcIdentity,destIdentity,GetStationeryFolder,SetStationeryFolder)
COPY_IDENTITY_BOOL_VALUE(srcIdentity,destIdentity,GetAttachSignature,SetAttachSignature)
COPY_IDENTITY_FILE_VALUE(srcIdentity,destIdentity,GetSignature,SetSignature)
COPY_IDENTITY_INT_VALUE(srcIdentity,destIdentity,GetSignatureDate,SetSignatureDate)
return NS_OK;
}
nsresult
nsMessengerMigrator::MigrateImapAccount(nsIMsgIdentity *identity, const char *hostAndPort, PRBool isDefaultAccount)
{
@ -1578,10 +1505,9 @@ nsMessengerMigrator::MigrateImapAccount(nsIMsgIdentity *identity, const char *ho
account->SetIncomingServer(server);
account->AddIdentity(copied_identity);
// make this new identity to copy of the identity
// make this new identity a copy of the identity
// that we created out of the 4.x prefs
rv = CopyIdentity(identity,copied_identity);
rv = copied_identity->Copy(identity);
if (NS_FAILED(rv)) return rv;
rv = SetMailCopiesAndFolders(copied_identity, (const char *)username, (const char *)hostname);
@ -2132,10 +2058,10 @@ nsMessengerMigrator::MigrateNewsAccount(nsIMsgIdentity *identity, const char *ho
account->SetIncomingServer(server);
account->AddIdentity(copied_identity);
// make this new identity to copy of the identity
// that we created out of the 4.x prefs
rv = CopyIdentity(identity,copied_identity);
if (NS_FAILED(rv)) return rv;
// make this new identity a copy of the identity
// that we created out of the 4.x prefs
rv = copied_identity->Copy(identity);
if (NS_FAILED(rv)) return rv;
rv = SetNewsCopiesAndFolders(copied_identity);
if (NS_FAILED(rv)) return rv;

View File

@ -88,7 +88,6 @@ private:
nsresult MigrateIdentity(nsIMsgIdentity *identity);
nsresult MigrateSmtpServer(nsISmtpServer *server);
nsresult CopyIdentity(nsIMsgIdentity *srcIdentity, nsIMsgIdentity *destIdentity);
nsresult SetMailCopiesAndFolders(nsIMsgIdentity *identity, const char *username, const char *hostname);
nsresult SetNewsCopiesAndFolders(nsIMsgIdentity *identity);
nsresult SetUsernameIfNecessary();

View File

@ -532,4 +532,76 @@ nsMsgIdentity::setFolderPref(const char *prefname, const char *value)
return rv;
}
#define COPY_IDENTITY_FILE_VALUE(SRC_ID,MACRO_GETTER,MACRO_SETTER) \
{ \
nsresult macro_rv; \
nsCOMPtr <nsIFileSpec>macro_spec; \
macro_rv = SRC_ID->MACRO_GETTER(getter_AddRefs(macro_spec)); \
if (NS_FAILED(macro_rv)) return macro_rv; \
this->MACRO_SETTER(macro_spec); \
}
#define COPY_IDENTITY_INT_VALUE(SRC_ID,MACRO_GETTER,MACRO_SETTER) \
{ \
nsresult macro_rv; \
PRInt32 macro_oldInt; \
macro_rv = SRC_ID->MACRO_GETTER(&macro_oldInt); \
if (NS_FAILED(macro_rv)) return macro_rv; \
this->MACRO_SETTER(macro_oldInt); \
}
#define COPY_IDENTITY_BOOL_VALUE(SRC_ID,MACRO_GETTER,MACRO_SETTER) \
{ \
nsresult macro_rv; \
PRBool macro_oldBool; \
macro_rv = SRC_ID->MACRO_GETTER(&macro_oldBool); \
if (NS_FAILED(macro_rv)) return macro_rv; \
this->MACRO_SETTER(macro_oldBool); \
}
#define COPY_IDENTITY_STR_VALUE(SRC_ID,MACRO_GETTER,MACRO_SETTER) \
{ \
nsXPIDLCString macro_oldStr; \
nsresult macro_rv; \
macro_rv = SRC_ID->MACRO_GETTER(getter_Copies(macro_oldStr)); \
if (NS_FAILED(macro_rv)) return macro_rv; \
if (!macro_oldStr) { \
this->MACRO_SETTER(""); \
} \
else { \
this->MACRO_SETTER(macro_oldStr); \
} \
}
static const PRUnichar unicharEmptyString[] = { (PRUnichar)'\0' };
#define COPY_IDENTITY_WSTR_VALUE(SRC_ID,MACRO_GETTER,MACRO_SETTER) \
{ \
nsXPIDLString macro_oldStr; \
nsresult macro_rv; \
macro_rv = SRC_ID->MACRO_GETTER(getter_Copies(macro_oldStr)); \
if (NS_FAILED(macro_rv)) return macro_rv; \
if (!macro_oldStr) { \
this->MACRO_SETTER(unicharEmptyString); \
} \
else { \
this->MACRO_SETTER(macro_oldStr); \
} \
}
NS_IMETHODIMP
nsMsgIdentity::Copy(nsIMsgIdentity *identity)
{
COPY_IDENTITY_BOOL_VALUE(identity,GetComposeHtml,SetComposeHtml)
COPY_IDENTITY_STR_VALUE(identity,GetEmail,SetEmail)
COPY_IDENTITY_STR_VALUE(identity,GetReplyTo,SetReplyTo)
COPY_IDENTITY_WSTR_VALUE(identity,GetFullName,SetFullName)
COPY_IDENTITY_WSTR_VALUE(identity,GetOrganization,SetOrganization)
COPY_IDENTITY_STR_VALUE(identity,GetDraftFolder,SetDraftFolder)
COPY_IDENTITY_STR_VALUE(identity,GetStationeryFolder,SetStationeryFolder)
COPY_IDENTITY_BOOL_VALUE(identity,GetAttachSignature,SetAttachSignature)
COPY_IDENTITY_FILE_VALUE(identity,GetSignature,SetSignature)
COPY_IDENTITY_INT_VALUE(identity,GetSignatureDate,SetSignatureDate)
return NS_OK;
}

View File

@ -68,4 +68,8 @@ interface nsINntpIncomingServer : nsISupports {
out nsINNTPProtocol aNntpConnection);
void RemoveConnection(in nsINNTPProtocol aNntpConnection);
/* use for auto subscribing */
boolean containsNewsgroup(in string name);
void subscribeToNewsgroup(in string name);
};

View File

@ -706,6 +706,8 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
PR_FREEIF(m_messageID);
m_messageID = nsnull;
rv = ParseURL(aURL,&bVal, getter_Copies(group), &m_messageID, &commandSpecificData);
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to parse news url");
//if (NS_FAILED(rv)) return rv;
// if we don't have a news host already, go get one...
if (!m_newsHost)
@ -847,8 +849,9 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
news:/GROUP
news://HOST/GROUP
*/
m_currentGroup = group;
if (PL_strchr (group, '*')) {
if (PL_strchr ((const char *)m_currentGroup, '*')) {
m_typeWanted = LIST_WANTED;
}
else {
@ -856,8 +859,20 @@ nsresult nsNNTPProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
rv = aURL->GetSpec(getter_Copies(newsgroupURI));
if (NS_FAILED(rv)) return(rv);
PRBool containsGroup = PR_TRUE;
NS_ASSERTION(m_nntpServer,"no nntp server");
if (m_nntpServer) {
rv = m_nntpServer->ContainsNewsgroup((const char *)m_currentGroup,&containsGroup);
if (NS_FAILED(rv)) return rv;
if (!containsGroup) {
rv = m_nntpServer->SubscribeToNewsgroup((const char *)m_currentGroup);
if (NS_FAILED(rv)) return rv;
}
}
rv = InitializeNewsFolderFromUri((const char *)newsgroupURI);
if (NS_FAILED(rv)) return(rv);
if (NS_FAILED(rv)) return rv;
m_typeWanted = GROUP_WANTED;
}

View File

@ -104,6 +104,8 @@ nsMsgNewsFolder::nsMsgNewsFolder(void) : nsMsgLineBuffer(nsnull, PR_FALSE),
if (PL_strcmp(MSG_LINEBREAK, CRLF)) {
SetLookingForCRLF(PR_FALSE);
}
mMessages = nsnull;
// NS_INIT_REFCNT(); done by superclass
}

View File

@ -778,3 +778,52 @@ nsNntpIncomingServer::OnStopRunningUrl(nsIURI *url, nsresult exitCode)
rv = AddSubscribedNewsgroups();
return rv;
}
NS_IMETHODIMP
nsNntpIncomingServer::ContainsNewsgroup(const char *name, PRBool *containsGroup)
{
nsresult rv;
NS_ASSERTION(name && PL_strlen(name),"no name");
if (!name || !containsGroup) return NS_ERROR_NULL_POINTER;
if (!nsCRT::strlen(name)) return NS_ERROR_FAILURE;
nsCOMPtr<nsIFolder> folder;
rv = GetRootFolder(getter_AddRefs(folder));
if (NS_FAILED(rv)) return rv;
if (!folder) return NS_ERROR_FAILURE;
nsCOMPtr<nsIMsgFolder> msgfolder = do_QueryInterface(folder, &rv);
if (NS_FAILED(rv)) return rv;
if (!msgfolder) return NS_ERROR_FAILURE;
rv = msgfolder->ContainsChildNamed(name, containsGroup);
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
return NS_OK;
}
NS_IMETHODIMP
nsNntpIncomingServer::SubscribeToNewsgroup(const char *name)
{
nsresult rv;
NS_ASSERTION(name && PL_strlen(name),"no name");
if (!name) return NS_ERROR_NULL_POINTER;
if (!nsCRT::strlen(name)) return NS_ERROR_FAILURE;
nsCOMPtr<nsIFolder> folder;
rv = GetRootFolder(getter_AddRefs(folder));
if (NS_FAILED(rv)) return rv;
if (!folder) return NS_ERROR_FAILURE;
nsCOMPtr<nsIMsgFolder> msgfolder = do_QueryInterface(folder, &rv);
if (NS_FAILED(rv)) return rv;
if (!msgfolder) return NS_ERROR_FAILURE;
nsAutoString newsgroupName(name);
rv = msgfolder->CreateSubfolder(newsgroupName.GetUnicode());
if (NS_FAILED(rv)) return rv;
return NS_OK;
}

View File

@ -372,20 +372,11 @@ nsNntpService::findNewsServerWithGroup(nsISupports *aElement, void *data)
nsCOMPtr<nsINntpIncomingServer> newsserver = do_QueryInterface(aElement, &rv);
if (NS_FAILED(rv) || ! newsserver) return PR_TRUE;
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(aElement, &rv);
if (NS_FAILED(rv) || ! server) return PR_TRUE;
findNewsServerEntry *entry = (findNewsServerEntry*) data;
nsCOMPtr<nsIFolder> folder;
rv = server->GetRootFolder(getter_AddRefs(folder));
if (NS_FAILED(rv) || !folder ) return PR_TRUE;
nsCOMPtr<nsIMsgFolder> msgfolder = do_QueryInterface(folder, &rv);
if (NS_FAILED(rv) || !msgfolder) return PR_TRUE;
PRBool containsGroup = PR_FALSE;
rv = msgfolder->ContainsChildNamed((const char *)(entry->newsgroup), &containsGroup);
rv = newsserver->ContainsNewsgroup((const char *)(entry->newsgroup), &containsGroup);
if (NS_FAILED(rv)) return PR_TRUE;
if (containsGroup) {
@ -843,6 +834,52 @@ nsresult nsNntpService::ConstructNntpUrl(const char * urlString, const char * ne
}
nsresult
nsNntpService::CreateNewsAccount(const char *username, const char *hostname, nsIMsgIncomingServer **server)
{
nsresult rv;
// username can be null.
if (!hostname || !server) return NS_ERROR_NULL_POINTER;
nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_PROGID, &rv);
if (NS_FAILED(rv)) return rv;
if (!accountManager) return NS_ERROR_FAILURE;
nsCOMPtr <nsIMsgAccount> account;
rv = accountManager->CreateAccount(getter_AddRefs(account));
if (NS_FAILED(rv)) return rv;
rv = accountManager->CreateIncomingServer(username, hostname, "nntp", server);
if (NS_FAILED(rv)) return rv;
nsCOMPtr <nsIMsgIdentity> identity;
rv = accountManager->CreateIdentity(getter_AddRefs(identity));
if (NS_FAILED(rv)) return rv;
if (!identity) return NS_ERROR_FAILURE;
// todo: eventually, copy the identity from the default news account
nsCOMPtr <nsIMsgAccount> defaultAccount;
rv = accountManager->GetDefaultAccount(getter_AddRefs(defaultAccount));
if (NS_FAILED(rv)) return rv;
if (!defaultAccount) return NS_ERROR_FAILURE;
nsCOMPtr <nsIMsgIdentity> defaultIdentity;
rv = defaultAccount->GetDefaultIdentity(getter_AddRefs(defaultIdentity));
if (NS_FAILED(rv)) return rv;
if (!defaultIdentity) return NS_ERROR_FAILURE;
rv = identity->Copy(defaultIdentity);
if (NS_FAILED(rv)) return rv;
// hook them together
rv = account->SetIncomingServer(*server);
if (NS_FAILED(rv)) return rv;
rv = account->AddIdentity(identity);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
nsresult
nsNntpService::GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTPProtocol **aProtocol)
{
@ -852,20 +889,25 @@ nsNntpService::GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTP
nsresult rv = aUri->GetHost(getter_Copies(hostName));
rv = aUri->GetPreHost(getter_Copies(userName));
NS_WITH_SERVICE(nsIMsgAccountManager, accountManager, NS_MSGACCOUNTMANAGER_PROGID, &rv);
nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_PROGID, &rv);
if (NS_FAILED(rv)) return rv;
if (!accountManager) return NS_ERROR_FAILURE;
// find the incoming server
nsCOMPtr<nsIMsgIncomingServer> server;
nsCOMPtr<nsINntpIncomingServer> nntpServer;
rv = accountManager->FindServer(userName,
hostName,
rv = accountManager->FindServer((const char *)userName,
(const char *)hostName,
"nntp",
getter_AddRefs(server));
if (NS_FAILED(rv) || !server)
return rv;
if (NS_FAILED(rv) || !server) {
rv = CreateNewsAccount((const char *)userName,(const char *)hostName,getter_AddRefs(server));
}
if (NS_FAILED(rv)) return rv;
if (!server) return NS_ERROR_FAILURE;
nntpServer = do_QueryInterface(server, &rv);
if (!nntpServer || NS_FAILED(rv))

View File

@ -27,6 +27,7 @@
#include "nsIProtocolHandler.h"
#include "nsIMsgMessageService.h"
#include "nsINntpIncomingServer.h"
#include "nsIMsgIncomingServer.h"
#include "nsIFileSpec.h"
#include "MailNewsTypes.h"
#include "nsIMsgProtocolInfo.h"
@ -71,10 +72,12 @@ protected:
// a convience routine used to put together news urls.
nsresult ConstructNntpUrl(const char * urlString, const char * newsgroupName, nsMsgKey key, nsIUrlListener *aUrlListener, nsIURI ** aUrl);
nsresult GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTPProtocol **aProtocol);
nsresult CreateNewsAccount(const char *username, const char *hostname, nsIMsgIncomingServer **server);
nsresult GetProtocolForUri(nsIURI *aUri, nsIMsgWindow *aMsgWindow, nsINNTPProtocol **aProtocol);
// a convience routine to run news urls
nsresult RunNewsUrl (nsIURI * aUrl, nsIMsgWindow *aMsgWindow, nsISupports * aConsumer);
static PRBool findNewsServerWithGroup(nsISupports *aElement, void *data);
PRBool mPrintingOperation; // Flag for printing operations
};