summaryrefslogtreecommitdiffstats
path: root/rdf/util/nsRDFResource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'rdf/util/nsRDFResource.cpp')
-rw-r--r--rdf/util/nsRDFResource.cpp221
1 files changed, 221 insertions, 0 deletions
diff --git a/rdf/util/nsRDFResource.cpp b/rdf/util/nsRDFResource.cpp
new file mode 100644
index 000000000..0e6f01f14
--- /dev/null
+++ b/rdf/util/nsRDFResource.cpp
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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 "nsRDFResource.h"
+#include "nsIServiceManager.h"
+#include "nsIRDFDelegateFactory.h"
+#include "nsIRDFService.h"
+#include "nsRDFCID.h"
+#include "mozilla/Logging.h"
+#include "nsComponentManagerUtils.h"
+#include "nsServiceManagerUtils.h"
+
+static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
+
+nsIRDFService* nsRDFResource::gRDFService = nullptr;
+nsrefcnt nsRDFResource::gRDFServiceRefCnt = 0;
+
+////////////////////////////////////////////////////////////////////////////////
+
+nsRDFResource::nsRDFResource(void)
+ : mDelegates(nullptr)
+{
+}
+
+nsRDFResource::~nsRDFResource(void)
+{
+ // Release all of the delegate objects
+ while (mDelegates) {
+ DelegateEntry* doomed = mDelegates;
+ mDelegates = mDelegates->mNext;
+ delete doomed;
+ }
+
+ if (!gRDFService)
+ return;
+
+ gRDFService->UnregisterResource(this);
+
+ if (--gRDFServiceRefCnt == 0)
+ NS_RELEASE(gRDFService);
+}
+
+NS_IMPL_ISUPPORTS(nsRDFResource, nsIRDFResource, nsIRDFNode)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIRDFNode methods:
+
+NS_IMETHODIMP
+nsRDFResource::EqualsNode(nsIRDFNode* aNode, bool* aResult)
+{
+ NS_PRECONDITION(aNode != nullptr, "null ptr");
+ if (! aNode)
+ return NS_ERROR_NULL_POINTER;
+
+ nsresult rv;
+ nsIRDFResource* resource;
+ rv = aNode->QueryInterface(NS_GET_IID(nsIRDFResource), (void**)&resource);
+ if (NS_SUCCEEDED(rv)) {
+ *aResult = (static_cast<nsIRDFResource*>(this) == resource);
+ NS_RELEASE(resource);
+ return NS_OK;
+ }
+ else if (rv == NS_NOINTERFACE) {
+ *aResult = false;
+ return NS_OK;
+ }
+ else {
+ return rv;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIRDFResource methods:
+
+NS_IMETHODIMP
+nsRDFResource::Init(const char* aURI)
+{
+ NS_PRECONDITION(aURI != nullptr, "null ptr");
+ if (! aURI)
+ return NS_ERROR_NULL_POINTER;
+
+ mURI = aURI;
+
+ if (gRDFServiceRefCnt++ == 0) {
+ nsresult rv = CallGetService(kRDFServiceCID, &gRDFService);
+ if (NS_FAILED(rv)) return rv;
+ }
+
+ // don't replace an existing resource with the same URI automatically
+ return gRDFService->RegisterResource(this, true);
+}
+
+NS_IMETHODIMP
+nsRDFResource::GetValue(char* *aURI)
+{
+ NS_ASSERTION(aURI, "Null out param.");
+
+ *aURI = ToNewCString(mURI);
+
+ if (!*aURI)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsRDFResource::GetValueUTF8(nsACString& aResult)
+{
+ aResult = mURI;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsRDFResource::GetValueConst(const char** aURI)
+{
+ *aURI = mURI.get();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsRDFResource::EqualsString(const char* aURI, bool* aResult)
+{
+ NS_PRECONDITION(aURI != nullptr, "null ptr");
+ if (! aURI)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_PRECONDITION(aResult, "null ptr");
+
+ *aResult = mURI.Equals(aURI);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsRDFResource::GetDelegate(const char* aKey, REFNSIID aIID, void** aResult)
+{
+ NS_PRECONDITION(aKey != nullptr, "null ptr");
+ if (! aKey)
+ return NS_ERROR_NULL_POINTER;
+
+ nsresult rv;
+ *aResult = nullptr;
+
+ DelegateEntry* entry = mDelegates;
+ while (entry) {
+ if (entry->mKey.Equals(aKey)) {
+ rv = entry->mDelegate->QueryInterface(aIID, aResult);
+ return rv;
+ }
+
+ entry = entry->mNext;
+ }
+
+ // Construct a ContractID of the form "@mozilla.org/rdf/delegate/[key]/[scheme];1
+ nsAutoCString contractID(NS_RDF_DELEGATEFACTORY_CONTRACTID_PREFIX);
+ contractID.Append(aKey);
+ contractID.AppendLiteral("&scheme=");
+
+ int32_t i = mURI.FindChar(':');
+ contractID += StringHead(mURI, i);
+
+ nsCOMPtr<nsIRDFDelegateFactory> delegateFactory =
+ do_CreateInstance(contractID.get(), &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ rv = delegateFactory->CreateDelegate(this, aKey, aIID, aResult);
+ if (NS_FAILED(rv)) return rv;
+
+ // Okay, we've successfully created a delegate. Let's remember it.
+ entry = new DelegateEntry;
+ if (! entry) {
+ NS_RELEASE(*reinterpret_cast<nsISupports**>(aResult));
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ entry->mKey = aKey;
+ entry->mDelegate = do_QueryInterface(*reinterpret_cast<nsISupports**>(aResult), &rv);
+ if (NS_FAILED(rv)) {
+ NS_ERROR("nsRDFResource::GetDelegate(): can't QI to nsISupports!");
+
+ delete entry;
+ NS_RELEASE(*reinterpret_cast<nsISupports**>(aResult));
+ return NS_ERROR_FAILURE;
+ }
+
+ entry->mNext = mDelegates;
+
+ mDelegates = entry;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsRDFResource::ReleaseDelegate(const char* aKey)
+{
+ NS_PRECONDITION(aKey != nullptr, "null ptr");
+ if (! aKey)
+ return NS_ERROR_NULL_POINTER;
+
+ DelegateEntry* entry = mDelegates;
+ DelegateEntry** link = &mDelegates;
+
+ while (entry) {
+ if (entry->mKey.Equals(aKey)) {
+ *link = entry->mNext;
+ delete entry;
+ return NS_OK;
+ }
+
+ link = &(entry->mNext);
+ entry = entry->mNext;
+ }
+
+ NS_WARNING("nsRDFResource::ReleaseDelegate() no delegate found");
+ return NS_OK;
+}
+
+
+
+////////////////////////////////////////////////////////////////////////////////