summaryrefslogtreecommitdiffstats
path: root/mailnews/base/src/nsSubscribeDataSource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mailnews/base/src/nsSubscribeDataSource.cpp')
-rw-r--r--mailnews/base/src/nsSubscribeDataSource.cpp673
1 files changed, 673 insertions, 0 deletions
diff --git a/mailnews/base/src/nsSubscribeDataSource.cpp b/mailnews/base/src/nsSubscribeDataSource.cpp
new file mode 100644
index 000000000..fe13cffca
--- /dev/null
+++ b/mailnews/base/src/nsSubscribeDataSource.cpp
@@ -0,0 +1,673 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsSubscribeDataSource.h"
+
+#include "nsIRDFService.h"
+#include "nsRDFCID.h"
+#include "nsIComponentManager.h"
+#include "rdf.h"
+#include "nsIServiceManager.h"
+#include "nsEnumeratorUtils.h"
+#include "nsStringGlue.h"
+#include "nsCOMPtr.h"
+#include "nsIMsgFolder.h"
+#include "nsIMsgIncomingServer.h"
+#include "nsCOMArray.h"
+#include "nsArrayEnumerator.h"
+#include "nsServiceManagerUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "nsMsgUtils.h"
+
+static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
+
+nsSubscribeDataSource::nsSubscribeDataSource()
+{
+}
+
+nsSubscribeDataSource::~nsSubscribeDataSource()
+{
+}
+
+NS_IMPL_ISUPPORTS(nsSubscribeDataSource, nsIRDFDataSource, nsISubscribeDataSource)
+
+nsresult
+nsSubscribeDataSource::Init()
+{
+ nsresult rv;
+
+ mRDFService = do_GetService(kRDFServiceCID, &rv);
+ NS_ASSERTION(NS_SUCCEEDED(rv) && mRDFService, "failed to get rdf service");
+ NS_ENSURE_SUCCESS(rv,rv);
+ if (!mRDFService) return NS_ERROR_FAILURE;
+
+ rv = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "child"),
+ getter_AddRefs(kNC_Child));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ rv = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Name"),
+ getter_AddRefs(kNC_Name));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ rv = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "LeafName"),
+ getter_AddRefs(kNC_LeafName));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ rv = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Subscribed"),
+ getter_AddRefs(kNC_Subscribed));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ rv = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Subscribable"),
+ getter_AddRefs(kNC_Subscribable));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ rv = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "ServerType"),
+ getter_AddRefs(kNC_ServerType));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ rv = mRDFService->GetLiteral(u"true", getter_AddRefs(kTrueLiteral));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ rv = mRDFService->GetLiteral(u"false", getter_AddRefs(kFalseLiteral));
+ NS_ENSURE_SUCCESS(rv,rv);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSubscribeDataSource::GetURI(char * *aURI)
+{
+ if ((*aURI = strdup("rdf:subscribe")) == nullptr)
+ return NS_ERROR_OUT_OF_MEMORY;
+ else
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSubscribeDataSource::GetSource(nsIRDFResource *property, nsIRDFNode *target, bool tv, nsIRDFResource **source)
+{
+ NS_PRECONDITION(property != nullptr, "null ptr");
+ if (! property)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_PRECONDITION(target != nullptr, "null ptr");
+ if (! target)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_PRECONDITION(source != nullptr, "null ptr");
+ if (! source)
+ return NS_ERROR_NULL_POINTER;
+
+ *source = nullptr;
+ return NS_RDF_NO_VALUE;
+}
+
+NS_IMETHODIMP
+nsSubscribeDataSource::GetTarget(nsIRDFResource *source,
+ nsIRDFResource *property,
+ bool tv,
+ nsIRDFNode **target /* out */)
+{
+ nsresult rv = NS_RDF_NO_VALUE;
+
+ NS_PRECONDITION(source != nullptr, "null ptr");
+ if (! source)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_PRECONDITION(property != nullptr, "null ptr");
+ if (! property)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_PRECONDITION(target != nullptr, "null ptr");
+ if (! target)
+ return NS_ERROR_NULL_POINTER;
+
+ *target = nullptr;
+
+ // we only have positive assertions in the subscribe data source.
+ if (! tv) return NS_RDF_NO_VALUE;
+
+ nsCOMPtr<nsISubscribableServer> server;
+ nsCString relativePath;
+ rv = GetServerAndRelativePathFromResource(source, getter_AddRefs(server), getter_Copies(relativePath));
+ if (NS_FAILED(rv) || !server)
+ return NS_RDF_NO_VALUE;
+
+ if (property == kNC_Name.get()) {
+ nsCOMPtr<nsIRDFLiteral> name;
+ rv = mRDFService->GetLiteral(NS_ConvertUTF8toUTF16(relativePath).get(),
+ getter_AddRefs(name));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ if (!name) rv = NS_RDF_NO_VALUE;
+ if (rv == NS_RDF_NO_VALUE) return(rv);
+ return name->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
+ }
+ else if (property == kNC_Child.get()) {
+ nsCString childUri;
+ rv = server->GetFirstChildURI(relativePath, childUri);
+ if (NS_FAILED(rv)) return NS_RDF_NO_VALUE;
+ if (childUri.IsEmpty()) return NS_RDF_NO_VALUE;
+
+ nsCOMPtr <nsIRDFResource> childResource;
+ rv = mRDFService->GetResource(childUri, getter_AddRefs(childResource));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ return childResource->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
+ }
+ else if (property == kNC_Subscribed.get()) {
+ bool isSubscribed;
+ rv = server->IsSubscribed(relativePath, &isSubscribed);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ NS_IF_ADDREF(*target = (isSubscribed ? kTrueLiteral : kFalseLiteral));
+ return NS_OK;
+ }
+ else if (property == kNC_Subscribable.get()) {
+ bool isSubscribable;
+ rv = server->IsSubscribable(relativePath, &isSubscribable);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ NS_IF_ADDREF(*target = (isSubscribable ? kTrueLiteral : kFalseLiteral));
+ return NS_OK;
+ }
+ else if (property == kNC_ServerType.get()) {
+ nsCString serverTypeStr;
+ rv = GetServerType(server, serverTypeStr);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ nsCOMPtr<nsIRDFLiteral> serverType;
+ rv = mRDFService->GetLiteral(NS_ConvertASCIItoUTF16(serverTypeStr).get(),
+ getter_AddRefs(serverType));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ if (!serverType)
+ rv = NS_RDF_NO_VALUE;
+ if (rv == NS_RDF_NO_VALUE)
+ return rv;
+ return serverType->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
+ }
+ else if (property == kNC_LeafName.get()) {
+ nsString leafNameStr;
+ rv = server->GetLeafName(relativePath, leafNameStr);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ nsCOMPtr<nsIRDFLiteral> leafName;
+ rv = mRDFService->GetLiteral(leafNameStr.get(), getter_AddRefs(leafName));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ if (!leafName)
+ rv = NS_RDF_NO_VALUE;
+ if (rv == NS_RDF_NO_VALUE)
+ return rv;
+ return leafName->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
+ }
+ else {
+ // do nothing
+ }
+
+ return(NS_RDF_NO_VALUE);
+}
+
+NS_IMETHODIMP
+nsSubscribeDataSource::GetTargets(nsIRDFResource *source,
+ nsIRDFResource *property,
+ bool tv,
+ nsISimpleEnumerator **targets /* out */)
+{
+ nsresult rv = NS_OK;
+
+ NS_PRECONDITION(source != nullptr, "null ptr");
+ if (! source)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_PRECONDITION(property != nullptr, "null ptr");
+ if (! property)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_PRECONDITION(targets != nullptr, "null ptr");
+ if (! targets)
+ return NS_ERROR_NULL_POINTER;
+
+ *targets = nullptr;
+
+ // we only have positive assertions in the subscribe data source.
+ if (!tv) return NS_RDF_NO_VALUE;
+
+ nsCOMPtr<nsISubscribableServer> server;
+ nsCString relativePath; // UTF-8
+
+ rv = GetServerAndRelativePathFromResource(source, getter_AddRefs(server), getter_Copies(relativePath));
+ if (NS_FAILED(rv) || !server) {
+ return NS_NewEmptyEnumerator(targets);
+ }
+
+ if (property == kNC_Child.get()) {
+ rv = server->GetChildren(relativePath, targets);
+ if (NS_FAILED(rv)) {
+ return NS_NewEmptyEnumerator(targets);
+ }
+ return rv;
+ }
+ else if (property == kNC_LeafName.get()) {
+ nsString leafNameStr;
+ rv = server->GetLeafName(relativePath, leafNameStr);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ nsCOMPtr<nsIRDFLiteral> leafName;
+ rv = mRDFService->GetLiteral(leafNameStr.get(), getter_AddRefs(leafName));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ return NS_NewSingletonEnumerator(targets, leafName);
+ }
+ else if (property == kNC_Subscribed.get()) {
+ bool isSubscribed;
+ rv = server->IsSubscribed(relativePath, &isSubscribed);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ return NS_NewSingletonEnumerator(targets,
+ isSubscribed ? kTrueLiteral : kFalseLiteral);
+ }
+ else if (property == kNC_Subscribable.get()) {
+ bool isSubscribable;
+ rv = server->IsSubscribable(relativePath, &isSubscribable);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ return NS_NewSingletonEnumerator(targets,
+ isSubscribable ? kTrueLiteral : kFalseLiteral);
+ }
+ else if (property == kNC_Name.get()) {
+ nsCOMPtr<nsIRDFLiteral> name;
+ rv = mRDFService->GetLiteral(NS_ConvertUTF8toUTF16(relativePath).get(),
+ getter_AddRefs(name));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ return NS_NewSingletonEnumerator(targets, name);
+ }
+ else if (property == kNC_ServerType.get()) {
+ nsCString serverTypeStr;
+ rv = GetServerType(server, serverTypeStr);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ nsCOMPtr<nsIRDFLiteral> serverType;
+ rv = mRDFService->GetLiteral(NS_ConvertASCIItoUTF16(serverTypeStr).get(),
+ getter_AddRefs(serverType));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ return NS_NewSingletonEnumerator(targets, serverType);
+ }
+ else {
+ // do nothing
+ }
+
+ return NS_NewEmptyEnumerator(targets);
+}
+
+NS_IMETHODIMP
+nsSubscribeDataSource::Assert(nsIRDFResource *source,
+ nsIRDFResource *property,
+ nsIRDFNode *target,
+ bool tv)
+{
+ return NS_RDF_ASSERTION_REJECTED;
+}
+
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::Unassert(nsIRDFResource *source,
+ nsIRDFResource *property,
+ nsIRDFNode *target)
+{
+ return NS_RDF_ASSERTION_REJECTED;
+}
+
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::Change(nsIRDFResource* aSource,
+ nsIRDFResource* aProperty,
+ nsIRDFNode* aOldTarget,
+ nsIRDFNode* aNewTarget)
+{
+ return NS_RDF_ASSERTION_REJECTED;
+}
+
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::Move(nsIRDFResource* aOldSource,
+ nsIRDFResource* aNewSource,
+ nsIRDFResource* aProperty,
+ nsIRDFNode* aTarget)
+{
+ return NS_RDF_ASSERTION_REJECTED;
+}
+
+nsresult
+nsSubscribeDataSource::GetServerType(nsISubscribableServer *server, nsACString& serverType)
+{
+ NS_ENSURE_ARG_POINTER(server);
+ nsresult rv;
+ nsCOMPtr<nsIMsgIncomingServer> incomingServer(do_QueryInterface(server, &rv));
+ NS_ENSURE_SUCCESS(rv,rv);
+ return incomingServer->GetType(serverType);
+}
+
+nsresult
+nsSubscribeDataSource::GetServerAndRelativePathFromResource(nsIRDFResource *source, nsISubscribableServer **server, char **relativePath)
+{
+ nsresult rv = NS_OK;
+
+ const char *sourceURI = nullptr;
+ rv = source->GetValueConst(&sourceURI);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(source, &rv));
+ // we expect this to fail sometimes, so don't assert
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsCOMPtr<nsIMsgIncomingServer> incomingServer;
+ rv = folder->GetServer(getter_AddRefs(incomingServer));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ rv = incomingServer->QueryInterface(NS_GET_IID(nsISubscribableServer), (void**)server);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ nsCString serverURI;
+ rv = incomingServer->GetServerURI(serverURI);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ uint32_t serverURILen = serverURI.Length();
+ if (serverURILen == strlen(sourceURI))
+ *relativePath = nullptr;
+ else {
+ // XXX : perhaps, have to unescape before returning
+ *relativePath = strdup(sourceURI + serverURILen + 1);
+ if (!*relativePath)
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSubscribeDataSource::HasAssertion(nsIRDFResource *source,
+ nsIRDFResource *property,
+ nsIRDFNode *target,
+ bool tv,
+ bool *hasAssertion /* out */)
+{
+ nsresult rv = NS_OK;
+
+ NS_PRECONDITION(source != nullptr, "null ptr");
+ if (! source)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_PRECONDITION(property != nullptr, "null ptr");
+ if (! property)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_PRECONDITION(target != nullptr, "null ptr");
+ if (! target)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_PRECONDITION(hasAssertion != nullptr, "null ptr");
+ if (! hasAssertion)
+ return NS_ERROR_NULL_POINTER;
+
+ *hasAssertion = false;
+
+ // we only have positive assertions in the subscribe data source.
+ if (!tv) return NS_OK;
+
+ if (property == kNC_Child.get()) {
+ nsCOMPtr<nsISubscribableServer> server;
+ nsCString relativePath;
+
+ rv = GetServerAndRelativePathFromResource(source, getter_AddRefs(server), getter_Copies(relativePath));
+ if (NS_FAILED(rv) || !server) {
+ *hasAssertion = false;
+ return NS_OK;
+ }
+
+ // not everything has children
+ rv = server->HasChildren(relativePath, hasAssertion);
+ NS_ENSURE_SUCCESS(rv,rv);
+ }
+ else if (property == kNC_Name.get()) {
+ // everything has a name
+ *hasAssertion = true;
+ }
+ else if (property == kNC_LeafName.get()) {
+ // everything has a leaf name
+ *hasAssertion = true;
+ }
+ else if (property == kNC_Subscribed.get()) {
+ // everything is subscribed or not
+ *hasAssertion = true;
+ }
+ else if (property == kNC_Subscribable.get()) {
+ // everything is subscribable or not
+ *hasAssertion = true;
+ }
+ else if (property == kNC_ServerType.get()) {
+ // everything has a server type
+ *hasAssertion = true;
+ }
+ else {
+ // do nothing
+ }
+
+ return NS_OK;
+}
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsSubscribeDataSource::HasArcOut(nsIRDFResource *source, nsIRDFResource *aArc, bool *result)
+{
+ nsresult rv = NS_OK;
+
+ nsCOMPtr<nsISubscribableServer> server;
+ nsCString relativePath;
+
+ if (aArc == kNC_Child.get()) {
+ rv = GetServerAndRelativePathFromResource(source, getter_AddRefs(server), getter_Copies(relativePath));
+ if (NS_FAILED(rv) || !server) {
+ *result = false;
+ return NS_OK;
+ }
+
+ bool hasChildren = false;
+ rv = server->HasChildren(relativePath, &hasChildren);
+ NS_ENSURE_SUCCESS(rv,rv);
+ *result = hasChildren;
+ return NS_OK;
+ }
+ else if ((aArc == kNC_Subscribed.get()) ||
+ (aArc == kNC_Subscribable.get()) ||
+ (aArc == kNC_LeafName.get()) ||
+ (aArc == kNC_ServerType.get()) ||
+ (aArc == kNC_Name.get())) {
+ *result = true;
+ return NS_OK;
+ }
+
+ *result = false;
+ return NS_OK;
+}
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::ArcLabelsIn(nsIRDFNode *node,
+ nsISimpleEnumerator ** labels /* out */)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::ArcLabelsOut(nsIRDFResource *source,
+ nsISimpleEnumerator **labels /* out */)
+{
+ nsresult rv = NS_OK;
+
+ NS_PRECONDITION(source != nullptr, "null ptr");
+ if (! source)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_PRECONDITION(labels != nullptr, "null ptr");
+ if (! labels)
+ return NS_ERROR_NULL_POINTER;
+
+ nsCOMPtr<nsISubscribableServer> server;
+ nsCString relativePath;
+
+ rv = GetServerAndRelativePathFromResource(source, getter_AddRefs(server), getter_Copies(relativePath));
+ if (NS_FAILED(rv) || !server) {
+ return NS_NewEmptyEnumerator(labels);
+ }
+
+ bool hasChildren = false;
+ rv = server->HasChildren(relativePath, &hasChildren);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ // Initialise with the number of items below, to save reallocating on each
+ // addition.
+ nsCOMArray<nsIRDFResource> array(hasChildren ? 6 : 5);
+
+ array.AppendObject(kNC_Subscribed);
+ array.AppendObject(kNC_Subscribable);
+ array.AppendObject(kNC_Name);
+ array.AppendObject(kNC_ServerType);
+ array.AppendObject(kNC_LeafName);
+
+ if (hasChildren) {
+ array.AppendObject(kNC_Child);
+ }
+
+ return NS_NewArrayEnumerator(labels, array);
+}
+
+NS_IMETHODIMP
+nsSubscribeDataSource::GetAllResources(nsISimpleEnumerator** aCursor)
+{
+ NS_NOTYETIMPLEMENTED("sorry!");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::AddObserver(nsIRDFObserver *n)
+{
+ NS_ENSURE_ARG_POINTER(n);
+ mObservers.AppendElement(n);
+ return NS_OK;
+}
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::RemoveObserver(nsIRDFObserver *n)
+{
+ NS_ENSURE_ARG_POINTER(n);
+ mObservers.RemoveElement(n);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSubscribeDataSource::GetHasObservers(bool *hasObservers)
+{
+ NS_ENSURE_ARG_POINTER(hasObservers);
+ *hasObservers = !mObservers.IsEmpty();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSubscribeDataSource::GetAllCmds(nsIRDFResource* source,
+ nsISimpleEnumerator/*<nsIRDFResource>*/** commands)
+{
+ return(NS_NewEmptyEnumerator(commands));
+}
+
+NS_IMETHODIMP
+nsSubscribeDataSource::IsCommandEnabled(nsISupports/*nsISupportsArray<nsIRDFResource>*/* aSources,
+ nsIRDFResource* aCommand,
+ nsISupports/*nsISupportsArray<nsIRDFResource>*/* aArguments,
+ bool* aResult)
+{
+ return(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::DoCommand(nsISupports/*nsISupportsArray<nsIRDFResource>*/* aSources,
+ nsIRDFResource* aCommand,
+ nsISupports/*nsISupportsArray<nsIRDFResource>*/* aArguments)
+{
+ return(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::BeginUpdateBatch()
+{
+ return NS_OK;
+}
+
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::EndUpdateBatch()
+{
+ return NS_OK;
+}
+
+
+
+NS_IMETHODIMP
+nsSubscribeDataSource::GetSources(nsIRDFResource *aProperty, nsIRDFNode *aTarget, bool aTruthValue, nsISimpleEnumerator **_retval)
+{
+ NS_ASSERTION(false, "Not implemented");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+#define NOTIFY_SUBSCRIBE_LISTENERS(propertyfunc_, params_) \
+ PR_BEGIN_MACRO \
+ { \
+ nsTObserverArray<nsCOMPtr<nsIRDFObserver> >::ForwardIterator iter(mObservers); \
+ while (iter.HasMore()) \
+ { \
+ iter.GetNext()->propertyfunc_ params_; \
+ } \
+ } \
+ PR_END_MACRO
+
+NS_IMETHODIMP
+nsSubscribeDataSource::NotifyObservers(nsIRDFResource *subject,
+ nsIRDFResource *property,
+ nsIRDFNode *object,
+ bool assert, bool change)
+{
+ NS_ASSERTION(!(change && assert),
+ "Can't change and assert at the same time!\n");
+
+ if (change)
+ NOTIFY_SUBSCRIBE_LISTENERS(OnChange, (this, subject, property, nullptr, object));
+ else if (assert)
+ NOTIFY_SUBSCRIBE_LISTENERS(OnAssert, (this, subject, property, object));
+ else
+ NOTIFY_SUBSCRIBE_LISTENERS(OnUnassert, (this, subject, property, object));
+ return NS_OK;
+}