nsRDFResource.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "nsRDFResource.h"
  6. #include "nsIServiceManager.h"
  7. #include "nsIRDFDelegateFactory.h"
  8. #include "nsIRDFService.h"
  9. #include "nsRDFCID.h"
  10. #include "mozilla/Logging.h"
  11. #include "nsComponentManagerUtils.h"
  12. #include "nsServiceManagerUtils.h"
  13. static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
  14. nsIRDFService* nsRDFResource::gRDFService = nullptr;
  15. nsrefcnt nsRDFResource::gRDFServiceRefCnt = 0;
  16. ////////////////////////////////////////////////////////////////////////////////
  17. nsRDFResource::nsRDFResource(void)
  18. : mDelegates(nullptr)
  19. {
  20. }
  21. nsRDFResource::~nsRDFResource(void)
  22. {
  23. // Release all of the delegate objects
  24. while (mDelegates) {
  25. DelegateEntry* doomed = mDelegates;
  26. mDelegates = mDelegates->mNext;
  27. delete doomed;
  28. }
  29. if (!gRDFService)
  30. return;
  31. gRDFService->UnregisterResource(this);
  32. if (--gRDFServiceRefCnt == 0)
  33. NS_RELEASE(gRDFService);
  34. }
  35. NS_IMPL_ISUPPORTS(nsRDFResource, nsIRDFResource, nsIRDFNode)
  36. ////////////////////////////////////////////////////////////////////////////////
  37. // nsIRDFNode methods:
  38. NS_IMETHODIMP
  39. nsRDFResource::EqualsNode(nsIRDFNode* aNode, bool* aResult)
  40. {
  41. NS_PRECONDITION(aNode != nullptr, "null ptr");
  42. if (! aNode)
  43. return NS_ERROR_NULL_POINTER;
  44. nsresult rv;
  45. nsIRDFResource* resource;
  46. rv = aNode->QueryInterface(NS_GET_IID(nsIRDFResource), (void**)&resource);
  47. if (NS_SUCCEEDED(rv)) {
  48. *aResult = (static_cast<nsIRDFResource*>(this) == resource);
  49. NS_RELEASE(resource);
  50. return NS_OK;
  51. }
  52. else if (rv == NS_NOINTERFACE) {
  53. *aResult = false;
  54. return NS_OK;
  55. }
  56. else {
  57. return rv;
  58. }
  59. }
  60. ////////////////////////////////////////////////////////////////////////////////
  61. // nsIRDFResource methods:
  62. NS_IMETHODIMP
  63. nsRDFResource::Init(const char* aURI)
  64. {
  65. NS_PRECONDITION(aURI != nullptr, "null ptr");
  66. if (! aURI)
  67. return NS_ERROR_NULL_POINTER;
  68. mURI = aURI;
  69. if (gRDFServiceRefCnt++ == 0) {
  70. nsresult rv = CallGetService(kRDFServiceCID, &gRDFService);
  71. if (NS_FAILED(rv)) return rv;
  72. }
  73. // don't replace an existing resource with the same URI automatically
  74. return gRDFService->RegisterResource(this, true);
  75. }
  76. NS_IMETHODIMP
  77. nsRDFResource::GetValue(char* *aURI)
  78. {
  79. NS_ASSERTION(aURI, "Null out param.");
  80. *aURI = ToNewCString(mURI);
  81. if (!*aURI)
  82. return NS_ERROR_OUT_OF_MEMORY;
  83. return NS_OK;
  84. }
  85. NS_IMETHODIMP
  86. nsRDFResource::GetValueUTF8(nsACString& aResult)
  87. {
  88. aResult = mURI;
  89. return NS_OK;
  90. }
  91. NS_IMETHODIMP
  92. nsRDFResource::GetValueConst(const char** aURI)
  93. {
  94. *aURI = mURI.get();
  95. return NS_OK;
  96. }
  97. NS_IMETHODIMP
  98. nsRDFResource::EqualsString(const char* aURI, bool* aResult)
  99. {
  100. NS_PRECONDITION(aURI != nullptr, "null ptr");
  101. if (! aURI)
  102. return NS_ERROR_NULL_POINTER;
  103. NS_PRECONDITION(aResult, "null ptr");
  104. *aResult = mURI.Equals(aURI);
  105. return NS_OK;
  106. }
  107. NS_IMETHODIMP
  108. nsRDFResource::GetDelegate(const char* aKey, REFNSIID aIID, void** aResult)
  109. {
  110. NS_PRECONDITION(aKey != nullptr, "null ptr");
  111. if (! aKey)
  112. return NS_ERROR_NULL_POINTER;
  113. nsresult rv;
  114. *aResult = nullptr;
  115. DelegateEntry* entry = mDelegates;
  116. while (entry) {
  117. if (entry->mKey.Equals(aKey)) {
  118. rv = entry->mDelegate->QueryInterface(aIID, aResult);
  119. return rv;
  120. }
  121. entry = entry->mNext;
  122. }
  123. // Construct a ContractID of the form "@mozilla.org/rdf/delegate/[key]/[scheme];1
  124. nsAutoCString contractID(NS_RDF_DELEGATEFACTORY_CONTRACTID_PREFIX);
  125. contractID.Append(aKey);
  126. contractID.AppendLiteral("&scheme=");
  127. int32_t i = mURI.FindChar(':');
  128. contractID += StringHead(mURI, i);
  129. nsCOMPtr<nsIRDFDelegateFactory> delegateFactory =
  130. do_CreateInstance(contractID.get(), &rv);
  131. if (NS_FAILED(rv)) return rv;
  132. rv = delegateFactory->CreateDelegate(this, aKey, aIID, aResult);
  133. if (NS_FAILED(rv)) return rv;
  134. // Okay, we've successfully created a delegate. Let's remember it.
  135. entry = new DelegateEntry;
  136. if (! entry) {
  137. NS_RELEASE(*reinterpret_cast<nsISupports**>(aResult));
  138. return NS_ERROR_OUT_OF_MEMORY;
  139. }
  140. entry->mKey = aKey;
  141. entry->mDelegate = do_QueryInterface(*reinterpret_cast<nsISupports**>(aResult), &rv);
  142. if (NS_FAILED(rv)) {
  143. NS_ERROR("nsRDFResource::GetDelegate(): can't QI to nsISupports!");
  144. delete entry;
  145. NS_RELEASE(*reinterpret_cast<nsISupports**>(aResult));
  146. return NS_ERROR_FAILURE;
  147. }
  148. entry->mNext = mDelegates;
  149. mDelegates = entry;
  150. return NS_OK;
  151. }
  152. NS_IMETHODIMP
  153. nsRDFResource::ReleaseDelegate(const char* aKey)
  154. {
  155. NS_PRECONDITION(aKey != nullptr, "null ptr");
  156. if (! aKey)
  157. return NS_ERROR_NULL_POINTER;
  158. DelegateEntry* entry = mDelegates;
  159. DelegateEntry** link = &mDelegates;
  160. while (entry) {
  161. if (entry->mKey.Equals(aKey)) {
  162. *link = entry->mNext;
  163. delete entry;
  164. return NS_OK;
  165. }
  166. link = &(entry->mNext);
  167. entry = entry->mNext;
  168. }
  169. NS_WARNING("nsRDFResource::ReleaseDelegate() no delegate found");
  170. return NS_OK;
  171. }
  172. ////////////////////////////////////////////////////////////////////////////////