![]() |
rdf: aggregating the in-memory datasourceChris Waterson (waterson@netscape.com) You can use XPCOM aggregation[1] with the in-memory datasource. Why would you want to do this? Say you were writing a datasource[2], and the way you chose to implement it was to "wrap" the in-memory datasource; i.e.,
MyClass : public nsIMyInterface, public nsIRDFDataSource {
private:
nsCOMPtr<nsIRDFDataSource> mInner;
public:
// nsIRDFDataSource methods
NS_IMETHOD Init(const char* aURI) {
return mInner->Init(aURI);
}
NS_IMETHOD GetURI(char* *aURI) {
return mInner->GetURI(aURI);
}
// etc., for each method in nsIRDFDataSource!
};
Very painful, prone to errors, and fragile as the interfaces are still in flux (a wee bit). Aggregation to the rescue! Here are the gory details on how. disclaimer: when it won't work
Although this magic is terribly convenient to use, it won't
work in the case that you want to "override" some of the in-memory
datasource's methods. For example, while writing the
bookmarks datasource,
I wanted to be able to trap In short, the only case where this technique is useful is when you're implementing a datasource to get "read-only reflection". That is, you want to reflect the contents of something as an RDF graph (presumably so that it can be aggregated with other information or displayed as styled content). technical details
As before, have an
class MyClass : public nsIMyInterface {
...
private:
nsCOMPtr<nsISupports> mInner;
};
Construct the datasource delegate when your object is constructed (or, at worst, when somebody QI's for it):
rv = nsComponentManager::CreateInstance(
kRDFInMemoryDataSourceCID,
this, /* the "outer" */
nsCOMTypeInfo<nsISupports>::GetIID(),
getter_AddRefs(mInner));
Note passing
Now, if the in-memory datasource's implementation of
For us to preserve symmetry, our
NS_IMETHODIMP
MyClass::QueryInterface(REFNSIID aIID, void** aResult)
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
if (aIID.Equals(nsCOMTypeInfo<nsIMyInterface>::GetIID()) ||
aIID.Equals(nsCOMTypeInfo<nsISupports>::GetIID())) {
*aResult = NS_STATIC_CAST(nsIGlobalHistory*, this);
}
else if (aIID.Equals(nsCOMTypeInfo<nsIRDFDataSource>::GetIID())) {
return mInner->QueryInterface(aIID, aResult);
}
else {
*aResult = nsnull;
return NS_NOINTERFACE;
}
NS_ADDREF(NS_STATIC_CAST(nsISupports*, aResult));
return NS_OK;
}
The only other thing that you'll need to be aware of is that you'll
need to
NS_IMETHODIMP
MyClass::DoSomething()
{
nsCOMPtr<nsIRDFDataSopurce> ds = do_QueryInterface(mInner);
rv = ds->Assert(/* something useful here */);
// etc...
return NS_OK;
}
It may be tempting to keep a pointer to the aggregate's
notes
Last Updated: $Id: aggregate.html,v 1.2 1999/08/23 23:59:06 waterson%netscape.com Exp $ |
|
|
Copyright © 1998-2000 The Mozilla Organization.
Last modified August 24, 1999. |
|