Land RDF_19990617_BRANCH. Add Change() and Move() methods to nsIRDFDataSource; add OnChange() and OnMove() methods to nsIRDFObserver. Factor nsIRDFDatasource::Init() and ::Flush() into nsIRDFRemoteDataSource. Change ownership model s.t. a datasource reference counts its observers.

This commit is contained in:
waterson@netscape.com
1999-06-24 00:22:58 +00:00
parent 76b6c5ed9a
commit e45449cd92
35 changed files with 1280 additions and 806 deletions

View File

@@ -45,6 +45,7 @@
#include "nsIRDFCompositeDataSource.h"
#include "nsIRDFNode.h"
#include "nsIRDFObserver.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsVoidArray.h"
#include "nsXPIDLString.h"
#include "rdf.h"
@@ -74,8 +75,6 @@ public:
NS_DECL_ISUPPORTS
// nsIRDFDataSource interface
NS_IMETHOD Init(const char* uri);
NS_IMETHOD GetURI(char* *uri);
NS_IMETHOD GetSource(nsIRDFResource* property,
@@ -107,15 +106,25 @@ public:
nsIRDFResource* property,
nsIRDFNode* target);
NS_IMETHOD Change(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aOldTarget,
nsIRDFNode* aNewTarget);
NS_IMETHOD Move(nsIRDFResource* aOldSource,
nsIRDFResource* aNewSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget);
NS_IMETHOD HasAssertion(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
PRBool* hasAssertion);
NS_IMETHOD AddObserver(nsIRDFObserver* n);
NS_IMETHOD AddObserver(nsIRDFObserver* aObserver);
NS_IMETHOD RemoveObserver(nsIRDFObserver* n);
NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver);
NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
nsISimpleEnumerator** labels);
@@ -152,13 +161,23 @@ public:
nsIRDFResource* predicate,
nsIRDFNode* object);
NS_IMETHOD OnChange(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aOldTarget,
nsIRDFNode* aNewTarget);
NS_IMETHOD OnMove(nsIRDFResource* aOldSource,
nsIRDFResource* aNewSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget);
// Implementation methods
PRBool HasAssertionN(int n, nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv);
protected:
nsVoidArray* mObservers;
nsCOMPtr<nsISupportsArray> mObservers;
virtual ~CompositeDataSourceImpl(void);
};
@@ -545,7 +564,6 @@ NS_NewRDFCompositeDataSource(nsIRDFCompositeDataSource** result)
CompositeDataSourceImpl::CompositeDataSourceImpl(void)
: mObservers(nsnull)
{
NS_INIT_REFCNT();
@@ -558,19 +576,42 @@ CompositeDataSourceImpl::CompositeDataSourceImpl(void)
CompositeDataSourceImpl::~CompositeDataSourceImpl(void)
{
for (PRInt32 i = mDataSources.Count() - 1; i >= 0; --i) {
nsIRDFDataSource* ds = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[i]);
ds->RemoveObserver(this);
NS_IF_RELEASE(ds);
}
delete mObservers;
}
////////////////////////////////////////////////////////////////////////
// nsISupports interface
NS_IMPL_ADDREF(CompositeDataSourceImpl);
NS_IMPL_RELEASE(CompositeDataSourceImpl);
NS_IMETHODIMP_(nsrefcnt)
CompositeDataSourceImpl::Release()
{
// We need a special implementation of Release() because the
// composite datasource holds a reference to each datasource that
// it "composes", and each database that the composite datasource
// observes holds a reference _back_ to the composite datasource.
NS_PRECONDITION(PRInt32(mRefCnt) > 0, "duplicate release");
--mRefCnt;
// When the number of references == the number of datasources,
// then we know that all that remains are the circular
// references from those datasources back to us. Release them.
if (PRInt32(mRefCnt) == mDataSources.Count()) {
for (PRInt32 i = mDataSources.Count() - 1; i >= 0; --i) {
nsIRDFDataSource* ds = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[i]);
ds->RemoveObserver(this);
NS_RELEASE(ds);
}
return 0;
}
else if (mRefCnt == 0) {
delete this;
return 0;
}
else {
return mRefCnt;
}
}
NS_IMETHODIMP
CompositeDataSourceImpl::QueryInterface(REFNSIID iid, void** result)
@@ -601,18 +642,11 @@ CompositeDataSourceImpl::QueryInterface(REFNSIID iid, void** result)
////////////////////////////////////////////////////////////////////////
// nsIRDFDataSource interface
NS_IMETHODIMP
CompositeDataSourceImpl::Init(const char* uri)
{
NS_NOTREACHED("CompositeDataSourceImpl::Init");
return NS_ERROR_UNEXPECTED; // XXX CompositeDataSourceImpl doesn't have a URI?
}
NS_IMETHODIMP
CompositeDataSourceImpl::GetURI(char* *uri)
{
NS_NOTREACHED("CompositeDataSourceImpl::GetURI");
return NS_ERROR_UNEXPECTED; // XXX CompositeDataSourceImpl doesn't have a URI?
*uri = nsnull;
return NS_OK;
}
NS_IMETHODIMP
@@ -871,6 +905,27 @@ CompositeDataSourceImpl::Unassert(nsIRDFResource* aSource,
return NS_RDF_ASSERTION_REJECTED;
}
NS_IMETHODIMP
CompositeDataSourceImpl::Change(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aOldTarget,
nsIRDFNode* aNewTarget)
{
NS_NOTYETIMPLEMENTED("write me");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
CompositeDataSourceImpl::Move(nsIRDFResource* aOldSource,
nsIRDFResource* aNewSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget)
{
NS_NOTYETIMPLEMENTED("write me");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
CompositeDataSourceImpl::HasAssertion(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
@@ -926,8 +981,9 @@ CompositeDataSourceImpl::AddObserver(nsIRDFObserver* aObserver)
return NS_ERROR_NULL_POINTER;
if (!mObservers) {
if ((mObservers = new nsVoidArray()) == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv;
rv = NS_NewISupportsArray(getter_AddRefs(mObservers));
if (NS_FAILED(rv)) return rv;
}
// XXX ensure uniqueness?
@@ -1007,7 +1063,9 @@ CompositeDataSourceImpl::Flush()
{
for (PRInt32 i = mDataSources.Count() - 1; i >= 0; --i) {
nsIRDFDataSource* ds = NS_STATIC_CAST(nsIRDFDataSource*, mDataSources[i]);
ds->Flush();
nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(ds);
if (remote)
remote->Flush();
}
return NS_OK;
}
@@ -1162,9 +1220,14 @@ CompositeDataSourceImpl::OnAssert(nsIRDFResource* aSource,
return NS_OK;
if (mObservers) {
for (PRInt32 i = mObservers->Count() - 1; i >= 0; --i) {
PRUint32 count;
rv = mObservers->Count(&count);
if (NS_FAILED(rv)) return rv;
for (PRInt32 i = PRInt32(count) - 1; i >= 0; --i) {
nsIRDFObserver* obs = (nsIRDFObserver*) mObservers->ElementAt(i);
obs->OnAssert(aSource, aProperty, aTarget);
NS_RELEASE(obs);
// XXX ignore return value?
}
}
@@ -1183,8 +1246,6 @@ CompositeDataSourceImpl::OnUnassert(nsIRDFResource* aSource,
// datasource actually served up the OnAssert(): we could use
// HasAssertionN() to only search datasources _before_ the
// datasource that coughed up the assertion.
//
// XXX What if the unassertion
nsresult rv;
PRBool hasAssertion;
rv = HasAssertion(aSource, aProperty, aTarget, PR_TRUE, &hasAssertion);
@@ -1194,9 +1255,70 @@ CompositeDataSourceImpl::OnUnassert(nsIRDFResource* aSource,
return NS_OK;
if (mObservers) {
for (PRInt32 i = mObservers->Count() - 1; i >= 0; --i) {
PRUint32 count;
rv = mObservers->Count(&count);
if (NS_FAILED(rv)) return rv;
for (PRInt32 i = PRInt32(count) - 1; i >= 0; --i) {
nsIRDFObserver* obs = (nsIRDFObserver*) mObservers->ElementAt(i);
obs->OnUnassert(aSource, aProperty, aTarget);
NS_RELEASE(obs);
// XXX ignore return value?
}
}
return NS_OK;
}
NS_IMETHODIMP
CompositeDataSourceImpl::OnChange(nsIRDFResource* aSource,
nsIRDFResource* aProperty,
nsIRDFNode* aOldTarget,
nsIRDFNode* aNewTarget)
{
// Make sure that the change is actually visible, and not hidden
// by an assertion in a different datasource.
//
// XXX Because of aggregation, this could actually mutate into a
// variety of OnAssert or OnChange notifications, which we'll
// ignore for now :-/.
if (mObservers) {
PRUint32 count;
nsresult rv = mObservers->Count(&count);
if (NS_FAILED(rv)) return rv;
for (PRInt32 i = PRInt32(count) - 1; i >= 0; --i) {
nsIRDFObserver* obs = (nsIRDFObserver*) mObservers->ElementAt(i);
obs->OnChange(aSource, aProperty, aOldTarget, aNewTarget);
NS_RELEASE(obs);
// XXX ignore return value?
}
}
return NS_OK;
}
NS_IMETHODIMP
CompositeDataSourceImpl::OnMove(nsIRDFResource* aOldSource,
nsIRDFResource* aNewSource,
nsIRDFResource* aProperty,
nsIRDFNode* aTarget)
{
// Make sure that the move is actually visible, and not hidden
// by an assertion in a different datasource.
//
// XXX Because of aggregation, this could actually mutate into a
// variety of OnAssert or OnMove notifications, which we'll
// ignore for now :-/.
if (mObservers) {
PRUint32 count;
nsresult rv = mObservers->Count(&count);
if (NS_FAILED(rv)) return rv;
for (PRInt32 i = PRInt32(count) - 1; i >= 0; --i) {
nsIRDFObserver* obs = (nsIRDFObserver*) mObservers->ElementAt(i);
obs->OnMove(aOldSource, aNewSource, aProperty, aTarget);
NS_RELEASE(obs);
// XXX ignore return value?
}
}
@@ -1205,3 +1327,6 @@ CompositeDataSourceImpl::OnUnassert(nsIRDFResource* aSource,