зеркало из https://github.com/mozilla/pjs.git
Add experimental support for RDF delegates.
This commit is contained in:
Родитель
25ec09fbb0
Коммит
7615b7ebff
|
@ -33,7 +33,7 @@ interface nsIRDFResource;
|
|||
|
||||
/**
|
||||
* This interface should be implemented by an XPCOM factory that
|
||||
* is registered to handle "component:/rdf/delegate/[key]/[scheme]"
|
||||
* is registered to handle "component:/rdf/delegate-factory/[key]/[scheme]"
|
||||
* ProgIDs.
|
||||
*
|
||||
* The factory will be invoked to create delegate objects from
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsrootidl.idl"
|
||||
#include "nsIRDFNode.idl"
|
||||
|
||||
|
||||
|
@ -51,5 +52,39 @@ interface nsIRDFResource : nsIRDFNode {
|
|||
* Determine if the resource has the given URI.
|
||||
*/
|
||||
boolean EqualsString(in string aURI);
|
||||
|
||||
/**
|
||||
* Retrieve the "delegate" object for this resource. A resource
|
||||
* may have several delegate objects, each of whose lifetimes is
|
||||
* bound to the life of the resource object.
|
||||
*
|
||||
* This method will return the delegate for the given key after
|
||||
* QueryInterface()-ing it to the requested IID.
|
||||
*
|
||||
* If no delegate exists for the specified key, this method will
|
||||
* attempt to create one using the component manager. Specifically,
|
||||
* it will combine aKey with the resource's URI scheme to produce
|
||||
* a ProgID as follows:
|
||||
*
|
||||
* component:/rdf/delegate-factory/[key]/[scheme]
|
||||
*
|
||||
* This ProgID will be used to locate a factory using the
|
||||
* FindFactory() method of nsIComponentManager. If the nsIFactory
|
||||
* exists, it will be used to create a "delegate factory"; that
|
||||
* is, an object that supports nsIRDFDelegateFactory. The delegate
|
||||
* factory will be used to construct the delegate object.
|
||||
*/
|
||||
void GetDelegate(in string aKey, in nsIIDRef aIID,
|
||||
[iid_is(aIID),retval] out nsQIResult aResult);
|
||||
|
||||
/**
|
||||
* Force a delegate to be "unbound" from the resource.
|
||||
*
|
||||
* Normally, a delegate object's lifetime will be identical to
|
||||
* that of the resource to which it is bound; this method allows a
|
||||
* delegate to unlink itself from an RDF resource prematurely.
|
||||
*/
|
||||
void ReleaseDelegate(in string aKey);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -23,9 +23,11 @@
|
|||
#ifndef nsRDFResource_h__
|
||||
#define nsRDFResource_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIRDFNode.h"
|
||||
#include "nsIRDFResource.h"
|
||||
#include "nscore.h"
|
||||
#include "nsString.h"
|
||||
#include "rdf.h"
|
||||
class nsIRDFService;
|
||||
|
||||
|
@ -46,6 +48,8 @@ public:
|
|||
NS_IMETHOD GetValue(char* *aURI);
|
||||
NS_IMETHOD GetValueConst(const char** aURI);
|
||||
NS_IMETHOD EqualsString(const char* aURI, PRBool* aResult);
|
||||
NS_IMETHOD GetDelegate(const char* aKey, REFNSIID aIID, void** aResult);
|
||||
NS_IMETHOD ReleaseDelegate(const char* aKey);
|
||||
|
||||
// nsRDFResource methods:
|
||||
nsRDFResource(void);
|
||||
|
@ -57,6 +61,14 @@ protected:
|
|||
|
||||
protected:
|
||||
char* mURI;
|
||||
|
||||
struct DelegateEntry {
|
||||
nsCString mKey;
|
||||
nsCOMPtr<nsISupports> mDelegate;
|
||||
DelegateEntry* mNext;
|
||||
};
|
||||
|
||||
DelegateEntry* mDelegates;
|
||||
};
|
||||
|
||||
#endif // nsRDFResource_h__
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "nsRDFResource.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIRDFDelegateFactory.h"
|
||||
#include "nsIRDFService.h"
|
||||
#include "nsRDFCID.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
@ -37,13 +38,20 @@ nsrefcnt nsRDFResource::gRDFServiceRefCnt = 0;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsRDFResource::nsRDFResource(void)
|
||||
: mURI(nsnull)
|
||||
: mURI(nsnull), mDelegates(nsnull)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
nsRDFResource::~nsRDFResource(void)
|
||||
{
|
||||
// Release all of the delegate objects
|
||||
while (mDelegates) {
|
||||
DelegateEntry* doomed = mDelegates;
|
||||
mDelegates = mDelegates->mNext;
|
||||
delete doomed;
|
||||
}
|
||||
|
||||
gRDFService->UnregisterResource(this);
|
||||
|
||||
// N.B. that we need to free the URI *after* we un-cache the resource,
|
||||
|
@ -166,4 +174,85 @@ nsRDFResource::EqualsString(const char* aURI, PRBool* aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRDFResource::GetDelegate(const char* aKey, REFNSIID aIID, void** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aKey != nsnull, "null ptr");
|
||||
if (! aKey)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult rv;
|
||||
*aResult = nsnull;
|
||||
|
||||
DelegateEntry* entry = mDelegates;
|
||||
while (entry) {
|
||||
if (entry->mKey == aKey) {
|
||||
rv = entry->mDelegate->QueryInterface(aIID, aResult);
|
||||
return rv;
|
||||
}
|
||||
|
||||
entry = entry->mNext;
|
||||
}
|
||||
|
||||
// Construct a ProgID of the form "component:/rdf/delegate/[key]/[scheme]
|
||||
nsCAutoString progID("component://rdf/delegate-factory/");
|
||||
progID.Append(aKey);
|
||||
progID.Append("/");
|
||||
|
||||
for (const char* p = mURI; *p && *p != ':'; ++p)
|
||||
progID.Append(*p);
|
||||
|
||||
nsCOMPtr<nsIRDFDelegateFactory> delegateFactory;
|
||||
rv = nsComponentManager::CreateInstance(progID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIRDFDelegateFactory),
|
||||
getter_AddRefs(delegateFactory));
|
||||
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(*NS_REINTERPRET_CAST(nsISupports**, aResult));
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
entry->mKey = aKey;
|
||||
entry->mDelegate = do_QueryInterface(*NS_REINTERPRET_CAST(nsISupports**, aResult));
|
||||
entry->mNext = mDelegates;
|
||||
|
||||
mDelegates = entry;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRDFResource::ReleaseDelegate(const char* aKey)
|
||||
{
|
||||
NS_PRECONDITION(aKey != nsnull, "null ptr");
|
||||
if (! aKey)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
DelegateEntry* entry = mDelegates;
|
||||
DelegateEntry** link = &mDelegates;
|
||||
|
||||
while (entry) {
|
||||
if (entry->mKey == 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Загрузка…
Ссылка в новой задаче