Back to index

lightning-sunbird  0.9+nobinonly
nsRDFResource.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsRDFResource.h"
00040 #include "nsCRT.h"
00041 #include "nsIServiceManager.h"
00042 #include "nsIRDFDelegateFactory.h"
00043 #include "nsIRDFService.h"
00044 #include "nsRDFCID.h"
00045 #include "nsXPIDLString.h"
00046 #include "prlog.h"
00047 
00048 static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
00049 
00050 nsIRDFService* nsRDFResource::gRDFService = nsnull;
00051 nsrefcnt nsRDFResource::gRDFServiceRefCnt = 0;
00052 
00054 
00055 nsRDFResource::nsRDFResource(void)
00056     : mDelegates(nsnull)
00057 {
00058 }
00059 
00060 nsRDFResource::~nsRDFResource(void)
00061 {
00062     // Release all of the delegate objects
00063     while (mDelegates) {
00064         DelegateEntry* doomed = mDelegates;
00065         mDelegates = mDelegates->mNext;
00066         delete doomed;
00067     }
00068 
00069     if (!gRDFService)
00070         return;
00071 
00072     gRDFService->UnregisterResource(this);
00073 
00074     if (--gRDFServiceRefCnt == 0)
00075         NS_RELEASE(gRDFService);
00076 }
00077 
00078 NS_IMPL_THREADSAFE_ISUPPORTS2(nsRDFResource, nsIRDFResource, nsIRDFNode)
00079 
00080 
00081 // nsIRDFNode methods:
00082 
00083 NS_IMETHODIMP
00084 nsRDFResource::EqualsNode(nsIRDFNode* aNode, PRBool* aResult)
00085 {
00086     NS_PRECONDITION(aNode != nsnull, "null ptr");
00087     if (! aNode)
00088         return NS_ERROR_NULL_POINTER;
00089 
00090     nsresult rv;
00091     nsIRDFResource* resource;
00092     rv = aNode->QueryInterface(NS_GET_IID(nsIRDFResource), (void**)&resource);
00093     if (NS_SUCCEEDED(rv)) {
00094         *aResult = (NS_STATIC_CAST(nsIRDFResource*, this) == resource);
00095         NS_RELEASE(resource);
00096         return NS_OK;
00097     }
00098     else if (rv == NS_NOINTERFACE) {
00099         *aResult = PR_FALSE;
00100         return NS_OK;
00101     }
00102     else {
00103         return rv;
00104     }
00105 }
00106 
00108 // nsIRDFResource methods:
00109 
00110 NS_IMETHODIMP
00111 nsRDFResource::Init(const char* aURI)
00112 {
00113     NS_PRECONDITION(aURI != nsnull, "null ptr");
00114     if (! aURI)
00115         return NS_ERROR_NULL_POINTER;
00116 
00117     mURI = aURI;
00118 
00119     if (gRDFServiceRefCnt++ == 0) {
00120         nsresult rv = CallGetService(kRDFServiceCID, &gRDFService);
00121         if (NS_FAILED(rv)) return rv;
00122     }
00123 
00124     // don't replace an existing resource with the same URI automatically
00125     return gRDFService->RegisterResource(this, PR_TRUE);
00126 }
00127 
00128 NS_IMETHODIMP
00129 nsRDFResource::GetValue(char* *aURI)
00130 {
00131     NS_ASSERTION(aURI, "Null out param.");
00132     
00133     *aURI = ToNewCString(mURI);
00134 
00135     if (!*aURI)
00136         return NS_ERROR_OUT_OF_MEMORY;
00137 
00138     return NS_OK;
00139 }
00140 
00141 NS_IMETHODIMP
00142 nsRDFResource::GetValueUTF8(nsACString& aResult)
00143 {
00144     aResult = mURI;
00145     return NS_OK;
00146 }
00147 
00148 NS_IMETHODIMP
00149 nsRDFResource::GetValueConst(const char** aURI)
00150 {
00151     *aURI = mURI.get();
00152     return NS_OK;
00153 }
00154 
00155 NS_IMETHODIMP
00156 nsRDFResource::EqualsString(const char* aURI, PRBool* aResult)
00157 {
00158     NS_PRECONDITION(aURI != nsnull, "null ptr");
00159     if (! aURI)
00160         return NS_ERROR_NULL_POINTER;
00161 
00162     NS_PRECONDITION(aResult, "null ptr");
00163 
00164     *aResult = mURI.Equals(aURI);
00165     return NS_OK;
00166 }
00167 
00168 NS_IMETHODIMP
00169 nsRDFResource::GetDelegate(const char* aKey, REFNSIID aIID, void** aResult)
00170 {
00171     NS_PRECONDITION(aKey != nsnull, "null ptr");
00172     if (! aKey)
00173         return NS_ERROR_NULL_POINTER;
00174 
00175     nsresult rv;
00176     *aResult = nsnull;
00177 
00178     DelegateEntry* entry = mDelegates;
00179     while (entry) {
00180         if (entry->mKey.Equals(aKey)) {
00181             rv = entry->mDelegate->QueryInterface(aIID, aResult);
00182             return rv;
00183         }
00184 
00185         entry = entry->mNext;
00186     }
00187 
00188     // Construct a ContractID of the form "@mozilla.org/rdf/delegate/[key]/[scheme];1
00189     nsCAutoString contractID(NS_RDF_DELEGATEFACTORY_CONTRACTID_PREFIX);
00190     contractID.Append(aKey);
00191     contractID.Append("&scheme=");
00192 
00193     PRInt32 i = mURI.FindChar(':');
00194     contractID += StringHead(mURI, i);
00195 
00196     nsCOMPtr<nsIRDFDelegateFactory> delegateFactory =
00197              do_CreateInstance(contractID.get(), &rv);
00198     if (NS_FAILED(rv)) return rv;
00199 
00200     rv = delegateFactory->CreateDelegate(this, aKey, aIID, aResult);
00201     if (NS_FAILED(rv)) return rv;
00202 
00203     // Okay, we've successfully created a delegate. Let's remember it.
00204     entry = new DelegateEntry;
00205     if (! entry) {
00206         NS_RELEASE(*NS_REINTERPRET_CAST(nsISupports**, aResult));
00207         return NS_ERROR_OUT_OF_MEMORY;
00208     }
00209     
00210     entry->mKey      = aKey;
00211     entry->mDelegate = do_QueryInterface(*NS_REINTERPRET_CAST(nsISupports**, aResult), &rv);
00212     if (NS_FAILED(rv)) {
00213         NS_ERROR("nsRDFResource::GetDelegate(): can't QI to nsISupports!");
00214 
00215         delete entry;
00216         NS_RELEASE(*NS_REINTERPRET_CAST(nsISupports**, aResult));
00217         return NS_ERROR_FAILURE;
00218     }
00219 
00220     entry->mNext     = mDelegates;
00221 
00222     mDelegates = entry;
00223 
00224     return NS_OK;
00225 }
00226 
00227 NS_IMETHODIMP
00228 nsRDFResource::ReleaseDelegate(const char* aKey)
00229 {
00230     NS_PRECONDITION(aKey != nsnull, "null ptr");
00231     if (! aKey)
00232         return NS_ERROR_NULL_POINTER;
00233 
00234     DelegateEntry* entry = mDelegates;
00235     DelegateEntry** link = &mDelegates;
00236 
00237     while (entry) {
00238         if (entry->mKey.Equals(aKey)) {
00239             *link = entry->mNext;
00240             delete entry;
00241             return NS_OK;
00242         }
00243 
00244         link = &(entry->mNext);
00245         entry = entry->mNext;
00246     }
00247 
00248     NS_WARNING("nsRDFResource::ReleaseDelegate() no delegate found");
00249     return NS_OK;
00250 }
00251 
00252 
00253