From 323df73f79e3abbb525905013a69f0afab628286 Mon Sep 17 00:00:00 2001 From: "putterman%netscape.com" Date: Thu, 28 Jan 1999 01:18:36 +0000 Subject: [PATCH] Adding folder data source to tree. git-svn-id: svn://10.0.0.236/trunk@18865 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/mailnews/local/src/Makefile.in | 35 + mozilla/mailnews/local/src/makefile.win | 58 ++ .../local/src/nsMSGFolderDataSource.cpp | 752 ++++++++++++++++++ .../local/src/nsMSGFolderDataSource.h | 179 +++++ 4 files changed, 1024 insertions(+) create mode 100644 mozilla/mailnews/local/src/Makefile.in create mode 100644 mozilla/mailnews/local/src/makefile.win create mode 100644 mozilla/mailnews/local/src/nsMSGFolderDataSource.cpp create mode 100644 mozilla/mailnews/local/src/nsMSGFolderDataSource.h diff --git a/mozilla/mailnews/local/src/Makefile.in b/mozilla/mailnews/local/src/Makefile.in new file mode 100644 index 00000000000..00f91db7c90 --- /dev/null +++ b/mozilla/mailnews/local/src/Makefile.in @@ -0,0 +1,35 @@ +#!gmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +VPATH = @srcdir@ +srcdir = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +MODULE=localmail +LIBRARY_NAME=localmail + +CPPSRCS = \ + nsMSGFolderDataSource.cpp \ + $(NULL) + +include $(topsrcdir)/config/config.mk + +include $(topsrcdir)/config/rules.mk + diff --git a/mozilla/mailnews/local/src/makefile.win b/mozilla/mailnews/local/src/makefile.win new file mode 100644 index 00000000000..f959eeaf9bd --- /dev/null +++ b/mozilla/mailnews/local/src/makefile.win @@ -0,0 +1,58 @@ +#!nmake +# +# The contents of this file are subject to the Netscape Public License +# Version 1.0 (the "NPL"); you may not use this file except in +# compliance with the NPL. You may obtain a copy of the NPL at +# http://www.mozilla.org/NPL/ +# +# Software distributed under the NPL is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL +# for the specific language governing rights and limitations under the +# NPL. +# +# The Initial Developer of this code under the NPL is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All Rights +# Reserved. + +DEPTH=..\..\.. +IGNORE_MANIFEST=1 + +include <$(DEPTH)\config\config.mak> + +LIBRARY_NAME=msglocal_s +MODULE= mailnews +REQUIRES=xpcom nspr rdf + +DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN + +CPPSRCS= nsMSGFolderDataSource.cpp \ + $(NULL) + +CPP_OBJS= .\$(OBJDIR)\nsMSGFolderDataSource.obj \ + $(NULL) + + +EXPORTS= \ + $(NULL) + +LINCS= -I$(PUBLIC)\xpcom \ + -I$(PUBLIC)\mailnews \ + -I$(PUBLIC)\raptor \ + -I$(PUBLIC)\rdf \ + $(NULL) + +MYLIBS = $(DIST)\lib\msgcore_s.lib + +LCFLAGS = \ + $(LCFLAGS) \ + $(DEFINES) \ + $(NULL) + +include <$(DEPTH)\config\rules.mak> + +libs:: $(LIBRARY) + $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib + +clobber:: + rm -f $(DIST)\lib\$(LIBRARY_NAME).lib diff --git a/mozilla/mailnews/local/src/nsMSGFolderDataSource.cpp b/mozilla/mailnews/local/src/nsMSGFolderDataSource.cpp new file mode 100644 index 00000000000..7e456191c7c --- /dev/null +++ b/mozilla/mailnews/local/src/nsMSGFolderDataSource.cpp @@ -0,0 +1,752 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nsMSGFolderDataSource.h" +#include "prlog.h" +#include "nsIRDFService.h" +#include "nsIServiceManager.h" +#include "nsRDFCID.h" +#include "rdf.h" +#include "nsIRDFResourceFactory.h" +#include "nsIRDFObserver.h" +#include "nsIRDFNode.h" +#include "plstr.h" +#include "prmem.h" +#include "prio.h" +#include "prprf.h" +#include "nsString.h" +#include "nsIMsgFolder.h" +#include "nsISupportsArray.h" +#include "nsFileSpec.h" + +static NS_DEFINE_IID(kIRDFMSGFolderDataSourceIID, NS_IRDFMSGFOLDERDATASOURCE_IID); +static NS_DEFINE_IID(kIRDFDataSourceIID, NS_IRDFDATASOURCE_IID); +static NS_DEFINE_IID(kIRDFServiceIID, NS_IRDFSERVICE_IID); +static NS_DEFINE_IID(kIRDFResourceFactoryIID, NS_IRDFRESOURCEFACTORY_IID); +static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); +static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID); +static NS_DEFINE_IID(kIRDFMsgFolderIID, NS_IMSGFOLDER_IID); +static NS_DEFINE_IID(kIRDFArcsOutCursorIID, NS_IRDFARCSOUTCURSOR_IID); +static NS_DEFINE_IID(kIRDFAssertionCursorIID, NS_IRDFASSERTIONCURSOR_IID); +static NS_DEFINE_IID(kIRDFCursorIID, NS_IRDFCURSOR_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + + +nsIRDFResource* nsMSGFolderDataSource::kNC_Child; +nsIRDFResource* nsMSGFolderDataSource::kNC_Folder; +nsIRDFResource* nsMSGFolderDataSource::kNC_Name; +nsIRDFResource* nsMSGFolderDataSource::kNC_MSGFolderRoot; + +static const char kURINC_MSGFolderRoot[] = "mailnewsfolder:MSGFolderRoot"; + +#define NC_NAMESPACE_URI "http://home.netscape.com/NC-rdf#" +DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, child); +DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Name); +DEFINE_RDF_VOCAB(NC_NAMESPACE_URI, NC, Folder); + +extern nsresult NS_NewRDFMsgFolderResourceFactory(nsIRDFResourceFactory** aInstancePtrResult); + +//////////////////////////////////////////////////////////////////////// +// The RDF service manager. Cached in the address book data source's +// constructor + +static nsIRDFService* gRDFService = nsnull; + +//////////////////////////////////////////////////////////////////////// +// THE address book source. + +static nsMSGFolderDataSource* gMsgFolderDataSource = nsnull; +//////////////////////////////////////////////////////////////////////// +// Utilities + +static PRBool +peq(nsIRDFResource* r1, nsIRDFResource* r2) +{ + PRBool result; + if (NS_SUCCEEDED(r1->EqualsResource(r2, &result)) && result) { + return PR_TRUE; + } else { + return PR_FALSE; + } +} + +static void createNode(const char *str, nsIRDFNode **node) +{ + nsIRDFLiteral * value; + nsString nsStr(str); + + *node = nsnull; + + if(NS_SUCCEEDED(gRDFService->GetLiteral((const PRUnichar*)nsStr, &value))) + { + *node = value; + } + + +} + + +//Helper function to find the name of a folder from the given pathname. +static const char* NameFromPathname(const char* pathname) +{ + char* ptr = PL_strrchr(pathname, '/'); + if (ptr) + return ptr + 1; + return pathname; +} + +static PRBool ShouldIgnoreFile (const char *name) +{ + if (name[0] == '.' || name[0] == '#' || name[PL_strlen(name) - 1] == '~') + return PR_TRUE; + + if (!PL_strcasecmp (name, "rules.dat")) + return PR_TRUE; + +#if defined (XP_PC) || defined (XP_MAC) + // don't add summary files to the list of folders; + //don't add popstate files to the list either, or rules (sort.dat). + if ((PL_strlen(name) > 4 && + !PL_strcasecmp(name + PL_strlen(name) - 4, ".snm")) || + !PL_strcasecmp(name, "popstate.dat") || + !PL_strcasecmp(name, "sort.dat") || + !PL_strcasecmp(name, "mailfilt.log") || + !PL_strcasecmp(name, "filters.js") || + !PL_strcasecmp(name + PL_strlen(name) - 4, ".toc")) + return PR_TRUE; +#endif + + return PR_FALSE; +} +nsMSGFolderDataSource::nsMSGFolderDataSource() +{ + NS_INIT_REFCNT(); + + mURI = nsnull; + mInitialized = PR_FALSE; + mObservers = nsnull; + + nsresult rv = nsServiceManager::GetService(kRDFServiceCID, + kIRDFServiceIID, + (nsISupports**) &gRDFService); + + PR_ASSERT(NS_SUCCEEDED(rv)); + + gMsgFolderDataSource = this; +} + +nsMSGFolderDataSource::~nsMSGFolderDataSource (void) +{ + gRDFService->UnregisterDataSource(this); + + PL_strfree(mURI); + if (mObservers) { + for (PRInt32 i = mObservers->Count(); i >= 0; --i) { + nsIRDFObserver* obs = (nsIRDFObserver*) mObservers->ElementAt(i); + NS_RELEASE(obs); + } + delete mObservers; + } + nsrefcnt refcnt; + NS_RELEASE2(kNC_Child, refcnt); + NS_RELEASE2(kNC_Folder, refcnt); + NS_RELEASE2(kNC_Name, refcnt); + NS_RELEASE2(kNC_MSGFolderRoot, refcnt); + + gMsgFolderDataSource = nsnull; + + nsServiceManager::ReleaseService(kRDFServiceCID, gRDFService); + gRDFService = nsnull; +} + + +NS_IMPL_ISUPPORTS(nsMSGFolderDataSource, kIRDFMSGFolderDataSourceIID); + + // nsIRDFDataSource methods +NS_IMETHODIMP nsMSGFolderDataSource::Init(const char* uri) +{ + if (mInitialized) + return NS_ERROR_ALREADY_INITIALIZED; + + if ((mURI = PL_strdup(uri)) == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv; + + nsIRDFResourceFactory *folderFactory; + + if(NS_SUCCEEDED(NS_NewRDFMsgFolderResourceFactory(&folderFactory))) + gRDFService->RegisterResourceFactory("mailnewsfolder:", folderFactory); + + + if (! kNC_Child) { + gRDFService->GetResource(kURINC_child, &kNC_Child); + gRDFService->GetResource(kURINC_Folder, &kNC_Folder); + gRDFService->GetResource(kURINC_Name, &kNC_Name); + gRDFService->GetResource(kURINC_MSGFolderRoot, &kNC_MSGFolderRoot); + } + + nsIMsgFolder *rootFolder; + if(NS_SUCCEEDED(kNC_MSGFolderRoot->QueryInterface(kIRDFMsgFolderIID, (void**)&rootFolder))) + { + + rootFolder->SetName("Mail and News"); + rootFolder->SetDepth(0); + nsNativeFileSpec startPath("your mail folder path", PR_FALSE); + if (NS_FAILED(rv = InitLocalFolders(rootFolder, startPath, 1))) + return rv; + + NS_RELEASE(rootFolder); + } + // register this as a named data source with the service manager + if (NS_FAILED(rv = gRDFService->RegisterDataSource(this))) + return rv; + + mInitialized = PR_TRUE; + return NS_OK;} + +NS_IMETHODIMP nsMSGFolderDataSource::GetURI(const char* *uri) const +{ + *uri = mURI; + return NS_OK; +} + +NS_IMETHODIMP nsMSGFolderDataSource::GetSource(nsIRDFResource* property, + nsIRDFNode* target, + PRBool tv, + nsIRDFResource** source /* out */) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsMSGFolderDataSource::GetTarget(nsIRDFResource* source, + nsIRDFResource* property, + PRBool tv, + nsIRDFNode** target) +{ + nsIMsgFolder* folder; + + // we only have positive assertions in the mail data source. + if (! tv) + return NS_ERROR_RDF_NO_VALUE; + + if (NS_SUCCEEDED(source->QueryInterface(kIRDFMsgFolderIID, (void**) &folder))) { + nsresult rv; + + if (peq(kNC_Name, property)) { + char * name; + rv = folder->GetName(&name); + createNode(name, target); + } + else { + // XXX should this fall through to the misc mail data datasource? + rv = NS_ERROR_RDF_NO_VALUE; + } + NS_RELEASE(folder); + return rv; + } else { + return NS_ERROR_RDF_NO_VALUE; + } +} + +NS_IMETHODIMP nsMSGFolderDataSource::GetSources(nsIRDFResource* property, + nsIRDFNode* target, + PRBool tv, + nsIRDFAssertionCursor** sources) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsMSGFolderDataSource::GetTargets(nsIRDFResource* source, + nsIRDFResource* property, + PRBool tv, + nsIRDFAssertionCursor** targets) +{ + nsIMsgFolder* folder; + nsresult rv = NS_ERROR_FAILURE; + + if(NS_SUCCEEDED(source->QueryInterface(kIRDFMsgFolderIID, (void**)&folder))) + { + + if (peq(kNC_Child, property)) + { + nsISupportsArray *subFolders; + + folder->GetSubFolders (&subFolders); + + *targets = new ArrayMsgFolderCursor(source, kNC_Child, subFolders); + + NS_IF_RELEASE(subFolders); + rv = NS_OK; + } + else if(peq(kNC_Name, property)) + { + *targets = new SingletonMsgFolderCursor(source, property, PR_FALSE); + rv = NS_OK; + } + NS_IF_RELEASE(folder); + } + return rv; +} + +NS_IMETHODIMP nsMSGFolderDataSource::Assert(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target, + PRBool tv) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsMSGFolderDataSource::Unassert(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + + +NS_IMETHODIMP nsMSGFolderDataSource::HasAssertion(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target, + PRBool tv, + PRBool* hasAssertion) +{ + *hasAssertion = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP nsMSGFolderDataSource::AddObserver(nsIRDFObserver* n) +{ + if (! mObservers) { + if ((mObservers = new nsVoidArray()) == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + } + mObservers->AppendElement(n); + return NS_OK;} + +NS_IMETHODIMP nsMSGFolderDataSource::RemoveObserver(nsIRDFObserver* n) +{ + if (! mObservers) + return NS_OK; + mObservers->RemoveElement(n); + return NS_OK; +} + +NS_IMETHODIMP nsMSGFolderDataSource::ArcLabelsIn(nsIRDFNode* node, + nsIRDFArcsInCursor** labels) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsMSGFolderDataSource::ArcLabelsOut(nsIRDFResource* source, + nsIRDFArcsOutCursor** labels) +{ + nsISupportsArray *temp; + NS_NewISupportsArray(&temp); + + temp->AppendElement(kNC_Child); + temp->AppendElement(kNC_Name); + *labels = new ArrayMsgFolderCursor(source, kNC_Child, temp); + return NS_OK; +} + +NS_IMETHODIMP +nsMSGFolderDataSource::GetAllResources(nsIRDFResourceCursor** aCursor) +{ + NS_NOTYETIMPLEMENTED("sorry!"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsMSGFolderDataSource::Flush() +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsMSGFolderDataSource::IsCommandEnabled(const char* aCommand, + nsIRDFResource* aCommandTarget, + PRBool* aResult) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsMSGFolderDataSource::DoCommand(const char* aCommand, + nsIRDFResource* aCommandTarget) +{ + PR_ASSERT(0); + return NS_ERROR_NOT_IMPLEMENTED; +} + +nsresult nsMSGFolderDataSource::InitFoldersFromDirectory(nsIMsgFolder *folder, nsNativeFileSpec& aPath, PRInt32 depth) +{ + + char *currentFolderName =nsnull; + + for (nsDirectoryIterator dir(aPath); dir; dir++) + { + nsNativeFileSpec currentFolderPath = (nsNativeFileSpec&)dir; + if(currentFolderName) + delete[] currentFolderName; + + currentFolderName = currentFolderPath.GetLeafName(); + if (ShouldIgnoreFile (currentFolderName)) + continue; + + InitLocalFolders (folder, currentFolderPath, depth); + } + if(currentFolderName) + delete[] currentFolderName; + + return NS_OK; +} + +nsresult +nsMSGFolderDataSource::InitLocalFolders(nsIMsgFolder* aParentFolder, nsNativeFileSpec& aPath, PRInt32 depth) +{ + const char *kDirExt = ".sbd"; + + nsFilePath aFilePath(aPath); + char* pathStr = (char*)aFilePath; + + + PRBool addNewFolderToTree = PR_TRUE; + nsIMsgFolder *folder = nsnull; + + if(aPath.IsDirectory()) + { + // pathStr specifies a filesystem directory + char *lastFour = &pathStr[PL_strlen(pathStr) - PL_strlen(kDirExt)]; + if (PL_strcasecmp(lastFour, kDirExt)) + { + // Create a new resource for this folder and set the child and name properties + PRInt16 fileurlSize = PL_strlen("mailnewsfolder:") + PL_strlen(pathStr); + char *fileurl = (char*)PR_Malloc( fileurlSize + 1); + nsIRDFResource* resource; + + PR_snprintf(fileurl, fileurlSize, "mailnewsfolder:%s", pathStr); + gRDFService->GetResource(fileurl, (nsIRDFResource**)&resource); + + PR_Free(fileurl); + + if(NS_SUCCEEDED(resource->QueryInterface(kIRDFMsgFolderIID, (void**)&folder))) + { + char * folderName; + + folder->GetNameFromPathName(pathStr, &folderName); + folder->SetName(folderName); + folder->SetDepth(depth); + aParentFolder->AddSubFolder(folder); + } + + NS_RELEASE(resource); + + InitFoldersFromDirectory(folder, aPath, depth + 1); + + NS_RELEASE(folder); + } + } + else + { + // Create a new resource for this folder and set the child and name properties + PRInt16 fileurlSize = PL_strlen("mailnewsfolder:") + PL_strlen(pathStr); + char *fileurl = (char*)PR_Malloc( fileurlSize + 1); + nsIRDFResource* resource; + + PR_snprintf(fileurl, fileurlSize, "mailnewsfolder:%s", pathStr); + gRDFService->GetResource(fileurl, (nsIRDFResource**)&resource); + + PR_Free(fileurl); + + if(NS_SUCCEEDED(resource->QueryInterface(kIRDFMsgFolderIID, (void**)&folder))) + { + char * folderName; + folder->GetNameFromPathName(pathStr, &folderName); + folder->SetName(folderName); + folder->SetDepth(depth); + if (addNewFolderToTree) + { + aParentFolder->AddSubFolder(folder); + } + NS_RELEASE(resource); + + if (folder) + { + folder->UpdateSummaryTotals(); + // Look for a directory for this mail folder, and recurse into it. + // e.g. if the folder is "inbox", look for "inbox.sbd". + char *folderName = aPath.GetLeafName(); + char *newLeafName = (char*)malloc(PL_strlen(folderName) + PL_strlen(kDirExt) + 2); + PL_strcpy(newLeafName, folderName); + PL_strcat(newLeafName, kDirExt); + aPath.SetLeafName(newLeafName); + if(folderName) + delete[] folderName; + if(newLeafName) + delete[] newLeafName; + + if(aPath.IsDirectory()) + { + InitFoldersFromDirectory(folder, aPath, depth + 1); + } + } + } + NS_RELEASE(folder); + + } + + return NS_OK; + +} + + +nsresult +nsIRDFMSGFolderDataSource::NS_NewRDFMSGFolderDataSource(nsIRDFDataSource** result) +{ + if (! result) + return NS_ERROR_NULL_POINTER; + + // Only one mail data source + if (! gMsgFolderDataSource) { + if ((gMsgFolderDataSource = new nsMSGFolderDataSource()) == nsnull) + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(gMsgFolderDataSource); + *result = gMsgFolderDataSource; + return NS_OK; +} + +SingletonMsgFolderCursor::SingletonMsgFolderCursor(nsIRDFNode* u, + nsIRDFResource* s, + PRBool inversep) +{ + if (!inversep) { + mSource = (nsIRDFResource*)u; + mTarget = nsnull; + } else { + mSource = nsnull; + mTarget = u; + } + NS_ADDREF(u); + mProperty = s; + NS_ADDREF(mProperty); + mValueReturnedp = PR_FALSE; + mInversep = inversep; + mValue = nsnull; +} + + +SingletonMsgFolderCursor::~SingletonMsgFolderCursor(void) +{ + NS_IF_RELEASE(mSource); + NS_IF_RELEASE(mValue); + NS_IF_RELEASE(mProperty); + NS_IF_RELEASE(mTarget); +} + + + + // nsIRDFCursor interface +NS_IMETHODIMP +SingletonMsgFolderCursor::Advance(void) +{ + nsresult rv = NS_ERROR_RDF_CURSOR_EMPTY; + if (mValueReturnedp) { + NS_IF_RELEASE(mValue); + mValue = nsnull; + return NS_ERROR_RDF_CURSOR_EMPTY; + } + mValueReturnedp = PR_TRUE; + if (mInversep) { + rv = gMsgFolderDataSource->GetSource(mProperty, mTarget, 1, (nsIRDFResource**)&mValue); + mSource = (nsIRDFResource*)mValue; + } else { + rv = gMsgFolderDataSource->GetTarget(mSource, mProperty, 1, &mValue); + mTarget = mValue; + } + if (mValue) { + NS_ADDREF(mValue); + NS_ADDREF(mValue); + } + // yes, its required twice, one for the value and one for the source/target + if (rv == NS_ERROR_RDF_NO_VALUE) return NS_ERROR_RDF_CURSOR_EMPTY; + return rv; +} + +NS_IMETHODIMP +SingletonMsgFolderCursor::GetValue(nsIRDFNode** aValue) +{ + NS_ADDREF(mValue); + *aValue = mValue; + return NS_OK; +} + + // nsIRDFAssertionCursor interface +NS_IMETHODIMP +SingletonMsgFolderCursor::GetDataSource(nsIRDFDataSource** aDataSource) +{ + NS_ADDREF(gMsgFolderDataSource); + *aDataSource = gMsgFolderDataSource; + return NS_OK; +} + +NS_IMETHODIMP +SingletonMsgFolderCursor::GetSubject(nsIRDFResource** aResource) +{ + NS_ADDREF(mSource); + *aResource = mSource; + return NS_OK; +} + +NS_IMETHODIMP +SingletonMsgFolderCursor::GetPredicate(nsIRDFResource** aPredicate) +{ + NS_ADDREF(mProperty); + *aPredicate = mProperty; + return NS_OK; +} + +NS_IMETHODIMP +SingletonMsgFolderCursor::GetObject(nsIRDFNode** aObject) +{ + NS_ADDREF(mTarget); + *aObject = mTarget; + return NS_OK; +} + +NS_IMETHODIMP +SingletonMsgFolderCursor::GetTruthValue(PRBool* aTruthValue) +{ + *aTruthValue = PR_TRUE; + return NS_OK; +} + + +NS_IMPL_ISUPPORTS(SingletonMsgFolderCursor, kIRDFAssertionCursorIID); + +ArrayMsgFolderCursor::ArrayMsgFolderCursor(nsIRDFResource* u, + nsIRDFResource* s, + nsISupportsArray* array) +{ + // getsources and gettargets will call this with the array + mSource = u; + mProperty = s; + mArray = array; + NS_ADDREF(mProperty); + NS_ADDREF(u); + NS_ADDREF(mArray); + mCount = 0; + mTarget = nsnull; + mValue = nsnull; +} + +ArrayMsgFolderCursor::~ArrayMsgFolderCursor(void) +{ + NS_IF_RELEASE(mSource); + NS_IF_RELEASE(mValue); + NS_IF_RELEASE(mProperty); + NS_IF_RELEASE(mTarget); + NS_IF_RELEASE(mArray); +} + + + // nsIRDFCursor interface +NS_IMETHODIMP +ArrayMsgFolderCursor::Advance(void) +{ + if (mArray->Count() <= mCount) return NS_ERROR_RDF_CURSOR_EMPTY; + NS_IF_RELEASE(mValue); + mTarget = mValue = (nsIRDFNode*) mArray->ElementAt(mCount++); + NS_ADDREF(mValue); + return NS_OK; +} + +NS_IMETHODIMP +ArrayMsgFolderCursor::GetValue(nsIRDFNode** aValue) +{ + NS_ADDREF(mValue); + *aValue = mValue; + return NS_OK; +} + + // nsIRDFAssertionCursor interface +NS_IMETHODIMP +ArrayMsgFolderCursor::GetDataSource(nsIRDFDataSource** aDataSource) +{ + NS_ADDREF(gMsgFolderDataSource); + *aDataSource = gMsgFolderDataSource; + return NS_OK; +} + +NS_IMETHODIMP +ArrayMsgFolderCursor::GetSubject(nsIRDFResource** aResource) +{ + NS_ADDREF(mSource); + *aResource = mSource; + return NS_OK; +} + +NS_IMETHODIMP +ArrayMsgFolderCursor::GetPredicate(nsIRDFResource** aPredicate) +{ + NS_ADDREF(mProperty); + *aPredicate = mProperty; + return NS_OK; +} + +NS_IMETHODIMP +ArrayMsgFolderCursor::GetObject(nsIRDFNode** aObject) +{ + NS_ADDREF(mTarget); + *aObject = mTarget; + return NS_OK; +} + +NS_IMETHODIMP +ArrayMsgFolderCursor::GetTruthValue(PRBool* aTruthValue) +{ + *aTruthValue = 1; + return NS_OK; +} + +NS_IMPL_ADDREF(ArrayMsgFolderCursor); +NS_IMPL_RELEASE(ArrayMsgFolderCursor); + +NS_IMETHODIMP +ArrayMsgFolderCursor::QueryInterface(REFNSIID iid, void** result) +{ + if (! result) + return NS_ERROR_NULL_POINTER; + + *result = nsnull; + if (iid.Equals(kIRDFAssertionCursorIID) || + iid.Equals(kIRDFCursorIID) || + iid.Equals(kIRDFArcsOutCursorIID) || + iid.Equals(kISupportsIID)) { + *result = NS_STATIC_CAST(nsIRDFAssertionCursor*, this); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} diff --git a/mozilla/mailnews/local/src/nsMSGFolderDataSource.h b/mozilla/mailnews/local/src/nsMSGFolderDataSource.h new file mode 100644 index 00000000000..de2c34f6a95 --- /dev/null +++ b/mozilla/mailnews/local/src/nsMSGFolderDataSource.h @@ -0,0 +1,179 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nsIRDFMSGFolderDataSource.h" +#include "nsIMsgFolder.h" +#include "nsISupports.h" +#include "nsVoidArray.h" +#include "nsIRDFNode.h" +#include "nsIRDFCursor.h" +#include "nsFileSpec.h" + +/** + * The mail data source. + */ +class nsMSGFolderDataSource : public nsIRDFMSGFolderDataSource +{ +private: + char* mURI; + nsVoidArray* mObservers; + PRBool mInitialized; + // internal methods + nsresult InitLocalFolders (nsIMsgFolder *aParentFolder, nsNativeFileSpec& path, + PRInt32 depth); + nsresult InitFoldersFromDirectory(nsIMsgFolder *folder, + nsNativeFileSpec& aPath, PRInt32 depth); + + nsresult AddColumns (void); + +public: + + NS_DECL_ISUPPORTS + + nsMSGFolderDataSource(void); + virtual ~nsMSGFolderDataSource (void); + + + // nsIRDFDataSource methods + NS_IMETHOD Init(const char* uri); + + NS_IMETHOD GetURI(const char* *uri) const; + + NS_IMETHOD GetSource(nsIRDFResource* property, + nsIRDFNode* target, + PRBool tv, + nsIRDFResource** source /* out */); + + NS_IMETHOD GetTarget(nsIRDFResource* source, + nsIRDFResource* property, + PRBool tv, + nsIRDFNode** target); + + NS_IMETHOD GetSources(nsIRDFResource* property, + nsIRDFNode* target, + PRBool tv, + nsIRDFAssertionCursor** sources); + + NS_IMETHOD GetTargets(nsIRDFResource* source, + nsIRDFResource* property, + PRBool tv, + nsIRDFAssertionCursor** targets); + + NS_IMETHOD Assert(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target, + PRBool tv); + + NS_IMETHOD Unassert(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target); + + NS_IMETHOD HasAssertion(nsIRDFResource* source, + nsIRDFResource* property, + nsIRDFNode* target, + PRBool tv, + PRBool* hasAssertion); + + NS_IMETHOD AddObserver(nsIRDFObserver* n); + + NS_IMETHOD RemoveObserver(nsIRDFObserver* n); + + NS_IMETHOD ArcLabelsIn(nsIRDFNode* node, + nsIRDFArcsInCursor** labels); + + NS_IMETHOD ArcLabelsOut(nsIRDFResource* source, + nsIRDFArcsOutCursor** labels); + + NS_IMETHOD GetAllResources(nsIRDFResourceCursor** aCursor); + + NS_IMETHOD Flush(); + + NS_IMETHOD IsCommandEnabled(const char* aCommand, + nsIRDFResource* aCommandTarget, + PRBool* aResult); + + NS_IMETHOD DoCommand(const char* aCommand, + nsIRDFResource* aCommandTarget); + + // caching frequently used resources + static nsIRDFResource* kNC_Child; + static nsIRDFResource* kNC_Folder; + static nsIRDFResource* kNC_Name; + static nsIRDFResource* kNC_Columns; + static nsIRDFResource* kNC_MSGFolderRoot; + +}; + +class SingletonMsgFolderCursor : public nsIRDFAssertionCursor +{ +private: + nsIRDFNode* mValue; + nsIRDFResource* mSource; + nsIRDFResource* mProperty; + nsIRDFNode* mTarget; + PRBool mValueReturnedp; + PRBool mInversep; + +public: + SingletonMsgFolderCursor(nsIRDFNode* u, + nsIRDFResource* s, + PRBool inversep); + virtual ~SingletonMsgFolderCursor(void); + + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsIRDFCursor interface + NS_IMETHOD Advance(void); + NS_IMETHOD GetValue(nsIRDFNode** aValue); + + // nsIRDFAssertionCursor interface + NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource); + NS_IMETHOD GetSubject(nsIRDFResource** aResource); + NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate); + NS_IMETHOD GetObject(nsIRDFNode** aObject); + NS_IMETHOD GetTruthValue(PRBool* aTruthValue); +}; + +class ArrayMsgFolderCursor : public nsIRDFAssertionCursor, public nsIRDFArcsOutCursor +{ +private: + nsIRDFNode* mValue; + nsIRDFResource* mSource; + nsIRDFResource* mProperty; + nsIRDFNode* mTarget; + int mCount; + nsISupportsArray* mArray; + +public: + ArrayMsgFolderCursor(nsIRDFResource* u, nsIRDFResource* s, nsISupportsArray* array); + virtual ~ArrayMsgFolderCursor(void); + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsIRDFCursor interface + NS_IMETHOD Advance(void); + NS_IMETHOD GetValue(nsIRDFNode** aValue); + // nsIRDFAssertionCursor interface + NS_IMETHOD GetDataSource(nsIRDFDataSource** aDataSource); + NS_IMETHOD GetSubject(nsIRDFResource** aResource); + NS_IMETHOD GetPredicate(nsIRDFResource** aPredicate); + NS_IMETHOD GetObject(nsIRDFNode** aObject); + NS_IMETHOD GetTruthValue(PRBool* aTruthValue); +}; +