зеркало из 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
|
* 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.
|
* ProgIDs.
|
||||||
*
|
*
|
||||||
* The factory will be invoked to create delegate objects from
|
* The factory will be invoked to create delegate objects from
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
* Contributor(s):
|
* Contributor(s):
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "nsrootidl.idl"
|
||||||
#include "nsIRDFNode.idl"
|
#include "nsIRDFNode.idl"
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,5 +52,39 @@ interface nsIRDFResource : nsIRDFNode {
|
||||||
* Determine if the resource has the given URI.
|
* Determine if the resource has the given URI.
|
||||||
*/
|
*/
|
||||||
boolean EqualsString(in string aURI);
|
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__
|
#ifndef nsRDFResource_h__
|
||||||
#define nsRDFResource_h__
|
#define nsRDFResource_h__
|
||||||
|
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIRDFNode.h"
|
#include "nsIRDFNode.h"
|
||||||
#include "nsIRDFResource.h"
|
#include "nsIRDFResource.h"
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
|
#include "nsString.h"
|
||||||
#include "rdf.h"
|
#include "rdf.h"
|
||||||
class nsIRDFService;
|
class nsIRDFService;
|
||||||
|
|
||||||
|
@ -46,6 +48,8 @@ public:
|
||||||
NS_IMETHOD GetValue(char* *aURI);
|
NS_IMETHOD GetValue(char* *aURI);
|
||||||
NS_IMETHOD GetValueConst(const char** aURI);
|
NS_IMETHOD GetValueConst(const char** aURI);
|
||||||
NS_IMETHOD EqualsString(const char* aURI, PRBool* aResult);
|
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 methods:
|
||||||
nsRDFResource(void);
|
nsRDFResource(void);
|
||||||
|
@ -57,6 +61,14 @@ protected:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char* mURI;
|
char* mURI;
|
||||||
|
|
||||||
|
struct DelegateEntry {
|
||||||
|
nsCString mKey;
|
||||||
|
nsCOMPtr<nsISupports> mDelegate;
|
||||||
|
DelegateEntry* mNext;
|
||||||
|
};
|
||||||
|
|
||||||
|
DelegateEntry* mDelegates;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // nsRDFResource_h__
|
#endif // nsRDFResource_h__
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "nsRDFResource.h"
|
#include "nsRDFResource.h"
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
#include "nsIServiceManager.h"
|
#include "nsIServiceManager.h"
|
||||||
|
#include "nsIRDFDelegateFactory.h"
|
||||||
#include "nsIRDFService.h"
|
#include "nsIRDFService.h"
|
||||||
#include "nsRDFCID.h"
|
#include "nsRDFCID.h"
|
||||||
#include "nsXPIDLString.h"
|
#include "nsXPIDLString.h"
|
||||||
|
@ -37,13 +38,20 @@ nsrefcnt nsRDFResource::gRDFServiceRefCnt = 0;
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
nsRDFResource::nsRDFResource(void)
|
nsRDFResource::nsRDFResource(void)
|
||||||
: mURI(nsnull)
|
: mURI(nsnull), mDelegates(nsnull)
|
||||||
{
|
{
|
||||||
NS_INIT_REFCNT();
|
NS_INIT_REFCNT();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRDFResource::~nsRDFResource(void)
|
nsRDFResource::~nsRDFResource(void)
|
||||||
{
|
{
|
||||||
|
// Release all of the delegate objects
|
||||||
|
while (mDelegates) {
|
||||||
|
DelegateEntry* doomed = mDelegates;
|
||||||
|
mDelegates = mDelegates->mNext;
|
||||||
|
delete doomed;
|
||||||
|
}
|
||||||
|
|
||||||
gRDFService->UnregisterResource(this);
|
gRDFService->UnregisterResource(this);
|
||||||
|
|
||||||
// N.B. that we need to free the URI *after* we un-cache the resource,
|
// 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;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
Загрузка…
Ссылка в новой задаче