rdf/base/src/nsCompositeDataSource.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     8   A simple composite data source implementation. A composit data
     9   source is just a strategy for combining individual data sources into
    10   a collective graph.
    13   1) A composite data source holds a sequence of data sources. The set
    14      of data sources can be specified during creation of the
    15      database. Data sources can also be added/deleted from a database
    16      later.
    18   2) The aggregation mechanism is based on simple super-positioning of
    19      the graphs from the datasources. If there is a conflict (i.e., 
    20      data source A has a true arc from foo to bar while data source B
    21      has a false arc from foo to bar), the data source that it earlier
    22      in the sequence wins.
    24      The implementation below doesn't really do this and needs to be
    25      fixed.
    27 */
    29 #include "xpcom-config.h"
    30 #include "nsCOMPtr.h"
    31 #include "nsIComponentManager.h"
    32 #include "nsIRDFCompositeDataSource.h"
    33 #include "nsIRDFNode.h"
    34 #include "nsIRDFObserver.h"
    35 #include "nsIRDFRemoteDataSource.h"
    36 #include "nsTArray.h"
    37 #include "nsCOMArray.h"
    38 #include "nsArrayEnumerator.h"
    39 #include "nsXPIDLString.h"
    40 #include "rdf.h"
    41 #include "nsCycleCollectionParticipant.h"
    43 #include "nsEnumeratorUtils.h"
    45 #ifdef PR_LOGGING
    46 #include "prlog.h"
    47 #include "prprf.h"
    48 #include <stdio.h>
    49 PRLogModuleInfo* nsRDFLog = nullptr;
    50 #endif
    52 //----------------------------------------------------------------------
    53 //
    54 // CompositeDataSourceImpl
    55 //
    57 class CompositeEnumeratorImpl;
    58 class CompositeArcsInOutEnumeratorImpl;
    59 class CompositeAssertionEnumeratorImpl;
    61 class CompositeDataSourceImpl : public nsIRDFCompositeDataSource,
    62                                 public nsIRDFObserver
    63 {
    64 public:
    65     CompositeDataSourceImpl(void);
    66     CompositeDataSourceImpl(char** dataSources);
    68     // nsISupports interface
    69     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    70     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(CompositeDataSourceImpl,
    71                                              nsIRDFCompositeDataSource)
    73     // nsIRDFDataSource interface
    74     NS_DECL_NSIRDFDATASOURCE
    76     // nsIRDFCompositeDataSource interface
    77     NS_DECL_NSIRDFCOMPOSITEDATASOURCE
    79     // nsIRDFObserver interface
    80     NS_DECL_NSIRDFOBSERVER
    82     bool HasAssertionN(int n, nsIRDFResource* source,
    83                             nsIRDFResource* property,
    84                             nsIRDFNode* target,
    85                             bool tv);
    87 protected:
    88     nsCOMArray<nsIRDFObserver> mObservers;
    89     nsCOMArray<nsIRDFDataSource> mDataSources;
    91     bool        mAllowNegativeAssertions;
    92     bool        mCoalesceDuplicateArcs;
    93     int32_t     mUpdateBatchNest;
    95     virtual ~CompositeDataSourceImpl() {}
    97     friend class CompositeEnumeratorImpl;
    98     friend class CompositeArcsInOutEnumeratorImpl;
    99     friend class CompositeAssertionEnumeratorImpl;
   100 };
   102 //----------------------------------------------------------------------
   103 //
   104 // CompositeEnumeratorImpl
   105 //
   107 class CompositeEnumeratorImpl : public nsISimpleEnumerator
   108 {
   109     // nsISupports
   110     NS_DECL_ISUPPORTS
   112     // nsISimpleEnumerator interface
   113     NS_DECL_NSISIMPLEENUMERATOR
   115     // pure abstract methods to be overridden
   116     virtual nsresult
   117     GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult) = 0;
   119     virtual nsresult
   120     HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult) = 0;
   122 protected:
   123     CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
   124                             bool aAllowNegativeAssertions,
   125                             bool aCoalesceDuplicateArcs);
   127     virtual ~CompositeEnumeratorImpl();
   129     CompositeDataSourceImpl* mCompositeDataSource;
   131     nsISimpleEnumerator* mCurrent;
   132     nsIRDFNode*  mResult;
   133     int32_t      mNext;
   134     nsAutoTArray<nsCOMPtr<nsIRDFNode>, 8>  mAlreadyReturned;
   135     bool mAllowNegativeAssertions;
   136     bool mCoalesceDuplicateArcs;
   137 };
   140 CompositeEnumeratorImpl::CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
   141                                                  bool aAllowNegativeAssertions,
   142                                                  bool aCoalesceDuplicateArcs)
   143     : mCompositeDataSource(aCompositeDataSource),
   144       mCurrent(nullptr),
   145       mResult(nullptr),
   146 	  mNext(0),
   147       mAllowNegativeAssertions(aAllowNegativeAssertions),
   148       mCoalesceDuplicateArcs(aCoalesceDuplicateArcs)
   149 {
   150     NS_ADDREF(mCompositeDataSource);
   151 }
   154 CompositeEnumeratorImpl::~CompositeEnumeratorImpl(void)
   155 {
   156     NS_IF_RELEASE(mCurrent);
   157     NS_IF_RELEASE(mResult);
   158     NS_RELEASE(mCompositeDataSource);
   159 }
   161 NS_IMPL_ADDREF(CompositeEnumeratorImpl)
   162 NS_IMPL_RELEASE(CompositeEnumeratorImpl)
   163 NS_IMPL_QUERY_INTERFACE(CompositeEnumeratorImpl, nsISimpleEnumerator)
   165 NS_IMETHODIMP
   166 CompositeEnumeratorImpl::HasMoreElements(bool* aResult)
   167 {
   168     NS_PRECONDITION(aResult != nullptr, "null ptr");
   169     if (! aResult)
   170         return NS_ERROR_NULL_POINTER;
   172     nsresult rv;
   174     // If we've already queued up a next target, then yep, there are
   175     // more elements.
   176     if (mResult) {
   177         *aResult = true;
   178         return NS_OK;
   179     }
   181     // Otherwise, we'll need to find a next target, switching cursors
   182     // if necessary.
   183     for ( ; mNext < mCompositeDataSource->mDataSources.Count(); ++mNext) {
   184         if (! mCurrent) {
   185             // We don't have a current enumerator, so create a new one on
   186             // the next data source.
   187             nsIRDFDataSource* datasource =
   188                 mCompositeDataSource->mDataSources[mNext];
   190             rv = GetEnumerator(datasource, &mCurrent);
   191             if (NS_FAILED(rv)) return rv;
   192             if (rv == NS_RDF_NO_VALUE)
   193                 continue;
   195             NS_ASSERTION(mCurrent != nullptr, "you're always supposed to return an enumerator from GetEnumerator, punk.");
   196             if (! mCurrent)
   197                 continue;
   198         }
   200         do {
   201             int32_t i;
   203             bool hasMore;
   204             rv = mCurrent->HasMoreElements(&hasMore);
   205             if (NS_FAILED(rv)) return rv;
   207             // Is the current enumerator depleted?
   208             if (! hasMore) {
   209                 NS_RELEASE(mCurrent);
   210                 break;
   211             }
   213             // Even if the current enumerator has more elements, we still
   214             // need to check that the current element isn't masked by
   215             // a negation in an earlier data source.
   217             // "Peek" ahead and pull out the next target.
   218             nsCOMPtr<nsISupports> result;
   219             rv = mCurrent->GetNext(getter_AddRefs(result));
   220             if (NS_FAILED(rv)) return rv;
   222             rv = result->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) &mResult);
   223             if (NS_FAILED(rv)) return rv;
   225             if (mAllowNegativeAssertions)
   226             {
   227                 // See if any previous data source negates this
   228                 bool hasNegation = false;
   229                 for (i = mNext - 1; i >= 0; --i)
   230                 {
   231                     nsIRDFDataSource* datasource =
   232                         mCompositeDataSource->mDataSources[i];
   234                     rv = HasNegation(datasource, mResult, &hasNegation);
   235                     if (NS_FAILED(rv)) return rv;
   237                     if (hasNegation)
   238                         break;
   239                 }
   241                 // if so, we've gotta keep looking
   242                 if (hasNegation)
   243                 {
   244                     NS_RELEASE(mResult);
   245                     continue;
   246                 }
   247             }
   249             if (mCoalesceDuplicateArcs)
   250             {
   251                 // Now see if we've returned it once already.
   252                 // XXX N.B. performance here...may want to hash if things get large?
   253                 bool alreadyReturned = false;
   254                 for (i = mAlreadyReturned.Length() - 1; i >= 0; --i)
   255                 {
   256                     if (mAlreadyReturned[i] == mResult)
   257                     {
   258                         alreadyReturned = true;
   259                         break;
   260                     }
   261                 }
   262                 if (alreadyReturned)
   263                 {
   264                     NS_RELEASE(mResult);
   265                     continue;
   266                 }
   267             }
   269             // If we get here, then we've really found one. It'll
   270             // remain cached in mResult until GetNext() sucks it out.
   271             *aResult = true;
   273             // Remember that we returned it, so we don't return duplicates.
   275             // XXX I wonder if we should make unique-checking be
   276             // optional. This could get to be pretty expensive (this
   277             // implementation turns iteration into O(n^2)).
   279             if (mCoalesceDuplicateArcs)
   280             {
   281                 mAlreadyReturned.AppendElement(mResult);
   282             }
   284             return NS_OK;
   285         } while (1);
   286     }
   288     // if we get here, there aren't any elements left.
   289     *aResult = false;
   290     return NS_OK;
   291 }
   294 NS_IMETHODIMP
   295 CompositeEnumeratorImpl::GetNext(nsISupports** aResult)
   296 {
   297     nsresult rv;
   299     bool hasMore;
   300     rv = HasMoreElements(&hasMore);
   301     if (NS_FAILED(rv)) return rv;
   303     if (! hasMore)
   304         return NS_ERROR_UNEXPECTED;
   306     // Don't AddRef: we "transfer" ownership to the caller
   307     *aResult = mResult;
   308     mResult = nullptr;
   310     return NS_OK;
   311 }
   313 //----------------------------------------------------------------------
   314 //
   315 // CompositeArcsInOutEnumeratorImpl
   316 //
   317 //
   319 class CompositeArcsInOutEnumeratorImpl : public CompositeEnumeratorImpl
   320 {
   321 public:
   322     enum Type { eArcsIn, eArcsOut };
   324     virtual ~CompositeArcsInOutEnumeratorImpl();
   326     virtual nsresult
   327     GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult);
   329     virtual nsresult
   330     HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult);
   332     CompositeArcsInOutEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
   333                                      nsIRDFNode* aNode,
   334                                      Type aType,
   335                                      bool aAllowNegativeAssertions,
   336                                      bool aCoalesceDuplicateArcs);
   338 private:
   339     nsIRDFNode* mNode;
   340     Type        mType;
   341 };
   344 CompositeArcsInOutEnumeratorImpl::CompositeArcsInOutEnumeratorImpl(
   345                 CompositeDataSourceImpl* aCompositeDataSource,
   346                 nsIRDFNode* aNode,
   347                 Type aType,
   348                 bool aAllowNegativeAssertions,
   349                 bool aCoalesceDuplicateArcs)
   350     : CompositeEnumeratorImpl(aCompositeDataSource, aAllowNegativeAssertions, aCoalesceDuplicateArcs),
   351       mNode(aNode),
   352       mType(aType)
   353 {
   354     NS_ADDREF(mNode);
   355 }
   357 CompositeArcsInOutEnumeratorImpl::~CompositeArcsInOutEnumeratorImpl()
   358 {
   359     NS_RELEASE(mNode);
   360 }
   363 nsresult
   364 CompositeArcsInOutEnumeratorImpl::GetEnumerator(
   365                  nsIRDFDataSource* aDataSource,
   366                  nsISimpleEnumerator** aResult)
   367 {
   368     if (mType == eArcsIn) {
   369         return aDataSource->ArcLabelsIn(mNode, aResult);
   370     }
   371     else {
   372         nsCOMPtr<nsIRDFResource> resource( do_QueryInterface(mNode) );
   373         return aDataSource->ArcLabelsOut(resource, aResult);
   374     }
   375 }
   377 nsresult
   378 CompositeArcsInOutEnumeratorImpl::HasNegation(
   379                  nsIRDFDataSource* aDataSource,
   380                  nsIRDFNode* aNode,
   381                  bool* aResult)
   382 {
   383     *aResult = false;
   384     return NS_OK;
   385 }
   388 //----------------------------------------------------------------------
   389 //
   390 // CompositeAssertionEnumeratorImpl
   391 //
   393 class CompositeAssertionEnumeratorImpl : public CompositeEnumeratorImpl
   394 {
   395 public:
   396     virtual nsresult
   397     GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult);
   399     virtual nsresult
   400     HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult);
   402     CompositeAssertionEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
   403                                      nsIRDFResource* aSource,
   404                                      nsIRDFResource* aProperty,
   405                                      nsIRDFNode* aTarget,
   406                                      bool aTruthValue,
   407                                      bool aAllowNegativeAssertions,
   408                                      bool aCoalesceDuplicateArcs);
   410     virtual ~CompositeAssertionEnumeratorImpl();
   412 private:
   413     nsIRDFResource* mSource;
   414     nsIRDFResource* mProperty;
   415     nsIRDFNode*     mTarget;
   416     bool            mTruthValue;
   417 };
   420 CompositeAssertionEnumeratorImpl::CompositeAssertionEnumeratorImpl(
   421                   CompositeDataSourceImpl* aCompositeDataSource,
   422                   nsIRDFResource* aSource,
   423                   nsIRDFResource* aProperty,
   424                   nsIRDFNode* aTarget,
   425                   bool aTruthValue,
   426                   bool aAllowNegativeAssertions,
   427                   bool aCoalesceDuplicateArcs)
   428     : CompositeEnumeratorImpl(aCompositeDataSource, aAllowNegativeAssertions, aCoalesceDuplicateArcs),
   429       mSource(aSource),
   430       mProperty(aProperty),
   431       mTarget(aTarget),
   432       mTruthValue(aTruthValue)
   433 {
   434     NS_IF_ADDREF(mSource);
   435     NS_ADDREF(mProperty); // always must be specified
   436     NS_IF_ADDREF(mTarget);
   437 }
   439 CompositeAssertionEnumeratorImpl::~CompositeAssertionEnumeratorImpl()
   440 {
   441     NS_IF_RELEASE(mSource);
   442     NS_RELEASE(mProperty);
   443     NS_IF_RELEASE(mTarget);
   444 }
   447 nsresult
   448 CompositeAssertionEnumeratorImpl::GetEnumerator(
   449                  nsIRDFDataSource* aDataSource,
   450                  nsISimpleEnumerator** aResult)
   451 {
   452     if (mSource) {
   453         return aDataSource->GetTargets(mSource, mProperty, mTruthValue, aResult);
   454     }
   455     else {
   456         return aDataSource->GetSources(mProperty, mTarget, mTruthValue, aResult);
   457     }
   458 }
   460 nsresult
   461 CompositeAssertionEnumeratorImpl::HasNegation(
   462                  nsIRDFDataSource* aDataSource,
   463                  nsIRDFNode* aNode,
   464                  bool* aResult)
   465 {
   466     if (mSource) {
   467         return aDataSource->HasAssertion(mSource, mProperty, aNode, !mTruthValue, aResult);
   468     }
   469     else {
   470         nsCOMPtr<nsIRDFResource> source( do_QueryInterface(aNode) );
   471         return aDataSource->HasAssertion(source, mProperty, mTarget, !mTruthValue, aResult);
   472     }
   473 }
   475 ////////////////////////////////////////////////////////////////////////
   477 nsresult
   478 NS_NewRDFCompositeDataSource(nsIRDFCompositeDataSource** result)
   479 {
   480     CompositeDataSourceImpl* db = new CompositeDataSourceImpl();
   481     if (! db)
   482         return NS_ERROR_OUT_OF_MEMORY;
   484     *result = db;
   485     NS_ADDREF(*result);
   486     return NS_OK;
   487 }
   490 CompositeDataSourceImpl::CompositeDataSourceImpl(void)
   491 	: mAllowNegativeAssertions(true),
   492 	  mCoalesceDuplicateArcs(true),
   493       mUpdateBatchNest(0)
   494 {
   495 #ifdef PR_LOGGING
   496     if (nsRDFLog == nullptr) 
   497         nsRDFLog = PR_NewLogModule("RDF");
   498 #endif
   499 }
   501 //----------------------------------------------------------------------
   502 //
   503 // nsISupports interface
   504 //
   506 NS_IMPL_CYCLE_COLLECTION_CLASS(CompositeDataSourceImpl)
   508 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CompositeDataSourceImpl)
   509     uint32_t i, count = tmp->mDataSources.Count();
   510     for (i = count; i > 0; --i) {
   511         tmp->mDataSources[i - 1]->RemoveObserver(tmp);
   512         tmp->mDataSources.RemoveObjectAt(i - 1);
   513     }
   514     NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservers);
   515 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
   516 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CompositeDataSourceImpl)
   517     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservers)
   518     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDataSources)
   519 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
   522 NS_IMPL_CYCLE_COLLECTING_ADDREF(CompositeDataSourceImpl)
   523 NS_IMPL_CYCLE_COLLECTING_RELEASE(CompositeDataSourceImpl)
   525 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CompositeDataSourceImpl)
   526     NS_INTERFACE_MAP_ENTRY(nsIRDFCompositeDataSource)
   527     NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
   528     NS_INTERFACE_MAP_ENTRY(nsIRDFObserver)
   529     NS_INTERFACE_MAP_ENTRY(nsIRDFCompositeDataSource)
   530     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFCompositeDataSource)
   531 NS_INTERFACE_MAP_END
   534 //----------------------------------------------------------------------
   535 //
   536 // nsIRDFDataSource interface
   537 //
   539 NS_IMETHODIMP
   540 CompositeDataSourceImpl::GetURI(char* *uri)
   541 {
   542     *uri = nullptr;
   543     return NS_OK;
   544 }
   546 NS_IMETHODIMP
   547 CompositeDataSourceImpl::GetSource(nsIRDFResource* property,
   548                                    nsIRDFNode* target,
   549                                    bool tv,
   550                                    nsIRDFResource** source)
   551 {
   552 	if (!mAllowNegativeAssertions && !tv)
   553 		return(NS_RDF_NO_VALUE);
   555     int32_t count = mDataSources.Count();
   556     for (int32_t i = 0; i < count; ++i) {
   557         nsresult rv;
   558         rv = mDataSources[i]->GetSource(property, target, tv, source);
   559         if (NS_FAILED(rv)) return rv;
   561         if (rv == NS_RDF_NO_VALUE)
   562             continue;
   564         if (!mAllowNegativeAssertions) return(NS_OK);
   566         // okay, found it. make sure we don't have the opposite
   567         // asserted in a more local data source
   568         if (!HasAssertionN(count-1, *source, property, target, !tv)) 
   569             return NS_OK;
   571         NS_RELEASE(*source);
   572         return NS_RDF_NO_VALUE;
   573     }
   574     return NS_RDF_NO_VALUE;
   575 }
   577 NS_IMETHODIMP
   578 CompositeDataSourceImpl::GetSources(nsIRDFResource* aProperty,
   579                                     nsIRDFNode* aTarget,
   580                                     bool aTruthValue,
   581                                     nsISimpleEnumerator** aResult)
   582 {
   583     NS_PRECONDITION(aProperty != nullptr, "null ptr");
   584     if (! aProperty)
   585         return NS_ERROR_NULL_POINTER;
   587     NS_PRECONDITION(aTarget != nullptr, "null ptr");
   588     if (! aTarget)
   589         return NS_ERROR_NULL_POINTER;
   591     NS_PRECONDITION(aResult != nullptr, "null ptr");
   592     if (! aResult)
   593         return NS_ERROR_NULL_POINTER;
   595     if (! mAllowNegativeAssertions && ! aTruthValue)
   596         return(NS_RDF_NO_VALUE);
   598     *aResult = new CompositeAssertionEnumeratorImpl(this, nullptr, aProperty,
   599                                                     aTarget, aTruthValue,
   600                                                     mAllowNegativeAssertions,
   601                                                     mCoalesceDuplicateArcs);
   603     if (! *aResult)
   604         return NS_ERROR_OUT_OF_MEMORY;
   606     NS_ADDREF(*aResult);
   607     return NS_OK;
   608 }
   610 NS_IMETHODIMP
   611 CompositeDataSourceImpl::GetTarget(nsIRDFResource* aSource,
   612                                    nsIRDFResource* aProperty,
   613                                    bool aTruthValue,
   614                                    nsIRDFNode** aResult)
   615 {
   616     NS_PRECONDITION(aSource != nullptr, "null ptr");
   617     if (! aSource)
   618         return NS_ERROR_NULL_POINTER;
   620     NS_PRECONDITION(aProperty != nullptr, "null ptr");
   621     if (! aProperty)
   622         return NS_ERROR_NULL_POINTER;
   624     NS_PRECONDITION(aResult != nullptr, "null ptr");
   625     if (! aResult)
   626         return NS_ERROR_NULL_POINTER;
   628     if (! mAllowNegativeAssertions && ! aTruthValue)
   629         return(NS_RDF_NO_VALUE);
   631     int32_t count = mDataSources.Count();
   632     for (int32_t i = 0; i < count; ++i) {
   633         nsresult rv;
   634         rv = mDataSources[i]->GetTarget(aSource, aProperty, aTruthValue,
   635                                         aResult);
   636         if (NS_FAILED(rv))
   637             return rv;
   639         if (rv == NS_OK) {
   640             // okay, found it. make sure we don't have the opposite
   641             // asserted in an earlier data source
   643             if (mAllowNegativeAssertions) {
   644                 if (HasAssertionN(count-1, aSource, aProperty, *aResult, !aTruthValue)) {
   645                     // whoops, it's been negated.
   646                     NS_RELEASE(*aResult);
   647                     return NS_RDF_NO_VALUE;
   648                 }
   649             }
   650             return NS_OK;
   651         }
   652     }
   654     // Otherwise, we couldn't find it at all.
   655     return NS_RDF_NO_VALUE;
   656 }
   658 bool
   659 CompositeDataSourceImpl::HasAssertionN(int n,
   660                                        nsIRDFResource* aSource,
   661                                        nsIRDFResource* aProperty,
   662                                        nsIRDFNode* aTarget,
   663                                        bool aTruthValue)
   664 {
   665     nsresult rv;
   666     for (int32_t m = 0; m < n; ++m) {
   667         bool result;
   668         rv = mDataSources[m]->HasAssertion(aSource, aProperty, aTarget,
   669                                            aTruthValue, &result);
   670         if (NS_FAILED(rv))
   671             return false;
   673         // found it!
   674         if (result)
   675             return true;
   676     }
   677     return false;
   678 }
   682 NS_IMETHODIMP
   683 CompositeDataSourceImpl::GetTargets(nsIRDFResource* aSource,
   684                                     nsIRDFResource* aProperty,
   685                                     bool aTruthValue,
   686                                     nsISimpleEnumerator** aResult)
   687 {
   688     NS_PRECONDITION(aSource != nullptr, "null ptr");
   689     if (! aSource)
   690         return NS_ERROR_NULL_POINTER;
   692     NS_PRECONDITION(aProperty != nullptr, "null ptr");
   693     if (! aProperty)
   694         return NS_ERROR_NULL_POINTER;
   696     NS_PRECONDITION(aResult != nullptr, "null ptr");
   697     if (! aResult)
   698         return NS_ERROR_NULL_POINTER;
   700     if (! mAllowNegativeAssertions && ! aTruthValue)
   701         return(NS_RDF_NO_VALUE);
   703     *aResult =
   704         new CompositeAssertionEnumeratorImpl(this,
   705                                              aSource, aProperty, nullptr,
   706                                              aTruthValue,
   707                                              mAllowNegativeAssertions,
   708                                              mCoalesceDuplicateArcs);
   710     if (! *aResult)
   711         return NS_ERROR_OUT_OF_MEMORY;
   713     NS_ADDREF(*aResult);
   714     return NS_OK;
   715 }
   717 NS_IMETHODIMP
   718 CompositeDataSourceImpl::Assert(nsIRDFResource* aSource, 
   719                                 nsIRDFResource* aProperty, 
   720                                 nsIRDFNode* aTarget,
   721                                 bool aTruthValue)
   722 {
   723     NS_PRECONDITION(aSource != nullptr, "null ptr");
   724     if (! aSource)
   725         return NS_ERROR_NULL_POINTER;
   727     NS_PRECONDITION(aProperty != nullptr, "null ptr");
   728     if (! aProperty)
   729         return NS_ERROR_NULL_POINTER;
   731     NS_PRECONDITION(aTarget != nullptr, "null ptr");
   732     if (! aTarget)
   733         return NS_ERROR_NULL_POINTER;
   735     if (! mAllowNegativeAssertions && ! aTruthValue)
   736         return(NS_RDF_ASSERTION_REJECTED);
   738     nsresult rv;
   740     // XXX Need to add back the stuff for unblocking ...
   742     // We iterate backwards from the last data source which was added
   743     // ("the most remote") to the first ("the most local"), trying to
   744     // apply the assertion in each.
   745     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
   746         rv = mDataSources[i]->Assert(aSource, aProperty, aTarget, aTruthValue);
   747         if (NS_RDF_ASSERTION_ACCEPTED == rv)
   748             return rv;
   750         if (NS_FAILED(rv))
   751             return rv;
   752     }
   754     // nobody wanted to accept it
   755     return NS_RDF_ASSERTION_REJECTED;
   756 }
   758 NS_IMETHODIMP
   759 CompositeDataSourceImpl::Unassert(nsIRDFResource* aSource,
   760                                   nsIRDFResource* aProperty,
   761                                   nsIRDFNode* aTarget)
   762 {
   763     NS_PRECONDITION(aSource != nullptr, "null ptr");
   764     if (! aSource)
   765         return NS_ERROR_NULL_POINTER;
   767     NS_PRECONDITION(aProperty != nullptr, "null ptr");
   768     if (! aProperty)
   769         return NS_ERROR_NULL_POINTER;
   771     NS_PRECONDITION(aTarget != nullptr, "null ptr");
   772     if (! aTarget)
   773         return NS_ERROR_NULL_POINTER;
   775     nsresult rv;
   777     // Iterate through each of the datasources, starting with "the
   778     // most local" and moving to "the most remote". If _any_ of the
   779     // datasources have the assertion, attempt to unassert it.
   780     bool unasserted = true;
   781     int32_t i;
   782     int32_t count = mDataSources.Count();
   783     for (i = 0; i < count; ++i) {
   784         nsIRDFDataSource* ds = mDataSources[i];
   786         bool hasAssertion;
   787         rv = ds->HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion);
   788         if (NS_FAILED(rv)) return rv;
   790         if (hasAssertion) {
   791             rv = ds->Unassert(aSource, aProperty, aTarget);
   792             if (NS_FAILED(rv)) return rv;
   794             if (rv != NS_RDF_ASSERTION_ACCEPTED) {
   795                 unasserted = false;
   796                 break;
   797             }
   798         }
   799     }
   801     // Either none of the datasources had it, or they were all willing
   802     // to let it be unasserted.
   803     if (unasserted)
   804         return NS_RDF_ASSERTION_ACCEPTED;
   806     // If we get here, one of the datasources already had the
   807     // assertion, and was adamant about not letting us remove
   808     // it. Iterate from the "most local" to the "most remote"
   809     // attempting to assert the negation...
   810     for (i = 0; i < count; ++i) {
   811         rv = mDataSources[i]->Assert(aSource, aProperty, aTarget, false);
   812         if (NS_FAILED(rv)) return rv;
   814         // Did it take?
   815         if (rv == NS_RDF_ASSERTION_ACCEPTED)
   816             return rv;
   817     }
   819     // Couln't get anyone to accept the negation, either.
   820     return NS_RDF_ASSERTION_REJECTED;
   821 }
   823 NS_IMETHODIMP
   824 CompositeDataSourceImpl::Change(nsIRDFResource* aSource,
   825                                 nsIRDFResource* aProperty,
   826                                 nsIRDFNode* aOldTarget,
   827                                 nsIRDFNode* aNewTarget)
   828 {
   829     NS_PRECONDITION(aSource != nullptr, "null ptr");
   830     if (! aSource)
   831         return NS_ERROR_NULL_POINTER;
   833     NS_PRECONDITION(aProperty != nullptr, "null ptr");
   834     if (! aProperty)
   835         return NS_ERROR_NULL_POINTER;
   837     NS_PRECONDITION(aOldTarget != nullptr, "null ptr");
   838     if (! aOldTarget)
   839         return NS_ERROR_NULL_POINTER;
   841     NS_PRECONDITION(aNewTarget != nullptr, "null ptr");
   842     if (! aNewTarget)
   843         return NS_ERROR_NULL_POINTER;
   845     nsresult rv;
   847     // XXX So we're assuming that a datasource _must_ accept the
   848     // atomic change; i.e., we can't split it up across two
   849     // datasources. That sucks.
   851     // We iterate backwards from the last data source which was added
   852     // ("the most remote") to the first ("the most local"), trying to
   853     // apply the change in each.
   854     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
   855         rv = mDataSources[i]->Change(aSource, aProperty, aOldTarget, aNewTarget);
   856         if (NS_RDF_ASSERTION_ACCEPTED == rv)
   857             return rv;
   859         if (NS_FAILED(rv))
   860             return rv;
   861     }
   863     // nobody wanted to accept it
   864     return NS_RDF_ASSERTION_REJECTED;
   865 }
   867 NS_IMETHODIMP
   868 CompositeDataSourceImpl::Move(nsIRDFResource* aOldSource,
   869                               nsIRDFResource* aNewSource,
   870                               nsIRDFResource* aProperty,
   871                               nsIRDFNode* aTarget)
   872 {
   873     NS_PRECONDITION(aOldSource != nullptr, "null ptr");
   874     if (! aOldSource)
   875         return NS_ERROR_NULL_POINTER;
   877     NS_PRECONDITION(aNewSource != nullptr, "null ptr");
   878     if (! aNewSource)
   879         return NS_ERROR_NULL_POINTER;
   881     NS_PRECONDITION(aProperty != nullptr, "null ptr");
   882     if (! aProperty)
   883         return NS_ERROR_NULL_POINTER;
   885     NS_PRECONDITION(aTarget != nullptr, "null ptr");
   886     if (! aTarget)
   887         return NS_ERROR_NULL_POINTER;
   889     nsresult rv;
   891     // XXX So we're assuming that a datasource _must_ accept the
   892     // atomic move; i.e., we can't split it up across two
   893     // datasources. That sucks.
   895     // We iterate backwards from the last data source which was added
   896     // ("the most remote") to the first ("the most local"), trying to
   897     // apply the assertion in each.
   898     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
   899         rv = mDataSources[i]->Move(aOldSource, aNewSource, aProperty, aTarget);
   900         if (NS_RDF_ASSERTION_ACCEPTED == rv)
   901             return rv;
   903         if (NS_FAILED(rv))
   904             return rv;
   905     }
   907     // nobody wanted to accept it
   908     return NS_RDF_ASSERTION_REJECTED;
   909 }
   912 NS_IMETHODIMP
   913 CompositeDataSourceImpl::HasAssertion(nsIRDFResource* aSource,
   914                                       nsIRDFResource* aProperty,
   915                                       nsIRDFNode* aTarget,
   916                                       bool aTruthValue,
   917                                       bool* aResult)
   918 {
   919     NS_PRECONDITION(aSource != nullptr, "null ptr");
   920     if (! aSource)
   921         return NS_ERROR_NULL_POINTER;
   923     NS_PRECONDITION(aProperty != nullptr, "null ptr");
   924     if (! aProperty)
   925         return NS_ERROR_NULL_POINTER;
   927     NS_PRECONDITION(aResult != nullptr, "null ptr");
   928     if (! aResult)
   929         return NS_ERROR_NULL_POINTER;
   931     if (! mAllowNegativeAssertions && ! aTruthValue)
   932     {
   933         *aResult = false;
   934         return(NS_OK);
   935     }
   937     nsresult rv;
   939     // Otherwise, look through all the data sources to see if anyone
   940     // has the positive...
   941     int32_t count = mDataSources.Count();
   942     for (int32_t i = 0; i < count; ++i) {
   943         nsIRDFDataSource* datasource = mDataSources[i];
   944         rv = datasource->HasAssertion(aSource, aProperty, aTarget, aTruthValue, aResult);
   945         if (NS_FAILED(rv)) return rv;
   947         if (*aResult)
   948             return NS_OK;
   950         if (mAllowNegativeAssertions)
   951         {
   952             bool hasNegation;
   953             rv = datasource->HasAssertion(aSource, aProperty, aTarget, !aTruthValue, &hasNegation);
   954             if (NS_FAILED(rv)) return rv;
   956             if (hasNegation)
   957             {
   958                 *aResult = false;
   959                 return NS_OK;
   960             }
   961         }
   962     }
   964     // If we get here, nobody had the assertion at all
   965     *aResult = false;
   966     return NS_OK;
   967 }
   969 NS_IMETHODIMP
   970 CompositeDataSourceImpl::AddObserver(nsIRDFObserver* aObserver)
   971 {
   972     NS_PRECONDITION(aObserver != nullptr, "null ptr");
   973     if (! aObserver)
   974         return NS_ERROR_NULL_POINTER;
   976     // XXX ensure uniqueness?
   977     mObservers.AppendObject(aObserver);
   979     return NS_OK;
   980 }
   982 NS_IMETHODIMP
   983 CompositeDataSourceImpl::RemoveObserver(nsIRDFObserver* aObserver)
   984 {
   985     NS_PRECONDITION(aObserver != nullptr, "null ptr");
   986     if (! aObserver)
   987         return NS_ERROR_NULL_POINTER;
   989     mObservers.RemoveObject(aObserver);
   991     return NS_OK;
   992 }
   994 NS_IMETHODIMP 
   995 CompositeDataSourceImpl::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result)
   996 {
   997     nsresult rv;
   998     *result = false;
   999     int32_t count = mDataSources.Count();
  1000     for (int32_t i = 0; i < count; ++i) {
  1001         rv = mDataSources[i]->HasArcIn(aNode, aArc, result);
  1002         if (NS_FAILED(rv)) return rv;
  1003         if (*result)
  1004             return NS_OK;
  1006     return NS_OK;
  1009 NS_IMETHODIMP 
  1010 CompositeDataSourceImpl::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result)
  1012     nsresult rv;
  1013     *result = false;
  1014     int32_t count = mDataSources.Count();
  1015     for (int32_t i = 0; i < count; ++i) {
  1016         rv = mDataSources[i]->HasArcOut(aSource, aArc, result);
  1017         if (NS_FAILED(rv)) return rv;
  1018         if (*result)
  1019             return NS_OK;
  1021     return NS_OK;
  1024 NS_IMETHODIMP
  1025 CompositeDataSourceImpl::ArcLabelsIn(nsIRDFNode* aTarget, nsISimpleEnumerator** aResult)
  1027     NS_PRECONDITION(aTarget != nullptr, "null ptr");
  1028     if (! aTarget)
  1029         return NS_ERROR_NULL_POINTER;
  1031     NS_PRECONDITION(aResult != nullptr, "null ptr");
  1032     if (! aResult)
  1033         return NS_ERROR_NULL_POINTER;
  1035     nsISimpleEnumerator* result =
  1036         new CompositeArcsInOutEnumeratorImpl(this, aTarget,
  1037                                              CompositeArcsInOutEnumeratorImpl::eArcsIn,
  1038                                              mAllowNegativeAssertions,
  1039                                              mCoalesceDuplicateArcs);
  1041     if (! result)
  1042         return NS_ERROR_OUT_OF_MEMORY;
  1044     NS_ADDREF(result);
  1045     *aResult = result;
  1046     return NS_OK;
  1049 NS_IMETHODIMP
  1050 CompositeDataSourceImpl::ArcLabelsOut(nsIRDFResource* aSource,
  1051                                       nsISimpleEnumerator** aResult)
  1053     NS_PRECONDITION(aSource != nullptr, "null ptr");
  1054     if (! aSource)
  1055         return NS_ERROR_NULL_POINTER;
  1057     NS_PRECONDITION(aResult != nullptr, "null ptr");
  1058     if (! aResult)
  1059         return NS_ERROR_NULL_POINTER;
  1061     nsISimpleEnumerator* result =
  1062         new CompositeArcsInOutEnumeratorImpl(this, aSource,
  1063                                              CompositeArcsInOutEnumeratorImpl::eArcsOut,
  1064                                              mAllowNegativeAssertions,
  1065                                              mCoalesceDuplicateArcs);
  1067     if (! result)
  1068         return NS_ERROR_OUT_OF_MEMORY;
  1070     NS_ADDREF(result);
  1071     *aResult = result;
  1072     return NS_OK;
  1075 NS_IMETHODIMP
  1076 CompositeDataSourceImpl::GetAllResources(nsISimpleEnumerator** aResult)
  1078     NS_NOTYETIMPLEMENTED("CompositeDataSourceImpl::GetAllResources");
  1079     return NS_ERROR_NOT_IMPLEMENTED;
  1082 NS_IMETHODIMP
  1083 CompositeDataSourceImpl::GetAllCmds(nsIRDFResource* source,
  1084                                     nsISimpleEnumerator/*<nsIRDFResource>*/** result)
  1086     nsresult rv;
  1087     nsCOMPtr<nsISimpleEnumerator> set;
  1089     for (int32_t i = 0; i < mDataSources.Count(); i++)
  1091         nsCOMPtr<nsISimpleEnumerator> dsCmds;
  1093         rv = mDataSources[i]->GetAllCmds(source, getter_AddRefs(dsCmds));
  1094         if (NS_SUCCEEDED(rv))
  1096             nsCOMPtr<nsISimpleEnumerator> tmp;
  1097             rv = NS_NewUnionEnumerator(getter_AddRefs(tmp), set, dsCmds);
  1098             set.swap(tmp);
  1099             if (NS_FAILED(rv)) return(rv);
  1103     set.forget(result);
  1104     return NS_OK;
  1107 NS_IMETHODIMP
  1108 CompositeDataSourceImpl::IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
  1109                                           nsIRDFResource*   aCommand,
  1110                                           nsISupportsArray/*<nsIRDFResource>*/* aArguments,
  1111                                           bool* aResult)
  1113     nsresult rv;
  1114     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
  1115         bool enabled = true;
  1116         rv = mDataSources[i]->IsCommandEnabled(aSources, aCommand, aArguments, &enabled);
  1117         if (NS_FAILED(rv) && (rv != NS_ERROR_NOT_IMPLEMENTED))
  1119             return(rv);
  1122         if (! enabled) {
  1123             *aResult = false;
  1124             return(NS_OK);
  1127     *aResult = true;
  1128     return(NS_OK);
  1131 NS_IMETHODIMP
  1132 CompositeDataSourceImpl::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
  1133                                    nsIRDFResource*   aCommand,
  1134                                    nsISupportsArray/*<nsIRDFResource>*/* aArguments)
  1136     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
  1137         nsresult rv = mDataSources[i]->DoCommand(aSources, aCommand, aArguments);
  1138         if (NS_FAILED(rv) && (rv != NS_ERROR_NOT_IMPLEMENTED))
  1140             return(rv);   // all datasources must succeed
  1143     return(NS_OK);
  1146 NS_IMETHODIMP
  1147 CompositeDataSourceImpl::BeginUpdateBatch()
  1149     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
  1150         mDataSources[i]->BeginUpdateBatch();
  1152     return NS_OK;
  1155 NS_IMETHODIMP
  1156 CompositeDataSourceImpl::EndUpdateBatch()
  1158     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
  1159         mDataSources[i]->EndUpdateBatch();
  1161     return NS_OK;
  1164 ////////////////////////////////////////////////////////////////////////
  1165 // nsIRDFCompositeDataSource methods
  1166 // XXX rvg We should make this take an additional argument specifying where
  1167 // in the sequence of data sources (of the db), the new data source should
  1168 // fit in. Right now, the new datasource gets stuck at the end.
  1169 // need to add the observers of the CompositeDataSourceImpl to the new data source.
  1171 NS_IMETHODIMP
  1172 CompositeDataSourceImpl::GetAllowNegativeAssertions(bool *aAllowNegativeAssertions)
  1174 	*aAllowNegativeAssertions = mAllowNegativeAssertions;
  1175 	return(NS_OK);
  1178 NS_IMETHODIMP
  1179 CompositeDataSourceImpl::SetAllowNegativeAssertions(bool aAllowNegativeAssertions)
  1181 	mAllowNegativeAssertions = aAllowNegativeAssertions;
  1182 	return(NS_OK);
  1185 NS_IMETHODIMP
  1186 CompositeDataSourceImpl::GetCoalesceDuplicateArcs(bool *aCoalesceDuplicateArcs)
  1188 	*aCoalesceDuplicateArcs = mCoalesceDuplicateArcs;
  1189 	return(NS_OK);
  1192 NS_IMETHODIMP
  1193 CompositeDataSourceImpl::SetCoalesceDuplicateArcs(bool aCoalesceDuplicateArcs)
  1195 	mCoalesceDuplicateArcs = aCoalesceDuplicateArcs;
  1196 	return(NS_OK);
  1199 NS_IMETHODIMP
  1200 CompositeDataSourceImpl::AddDataSource(nsIRDFDataSource* aDataSource)
  1202     NS_ASSERTION(aDataSource != nullptr, "null ptr");
  1203     if (! aDataSource)
  1204         return NS_ERROR_NULL_POINTER;
  1206     mDataSources.AppendObject(aDataSource);
  1207     aDataSource->AddObserver(this);
  1208     return NS_OK;
  1213 NS_IMETHODIMP
  1214 CompositeDataSourceImpl::RemoveDataSource(nsIRDFDataSource* aDataSource)
  1216     NS_ASSERTION(aDataSource != nullptr, "null ptr");
  1217     if (! aDataSource)
  1218         return NS_ERROR_NULL_POINTER;
  1221     if (mDataSources.IndexOf(aDataSource) >= 0) {
  1222         aDataSource->RemoveObserver(this);
  1223         mDataSources.RemoveObject(aDataSource);
  1225     return NS_OK;
  1229 NS_IMETHODIMP
  1230 CompositeDataSourceImpl::GetDataSources(nsISimpleEnumerator** _result)
  1232     // NS_NewArrayEnumerator for an nsCOMArray takes a snapshot of the
  1233     // current state.
  1234     return NS_NewArrayEnumerator(_result, mDataSources);
  1237 NS_IMETHODIMP
  1238 CompositeDataSourceImpl::OnAssert(nsIRDFDataSource* aDataSource,
  1239                                   nsIRDFResource* aSource,
  1240                                   nsIRDFResource* aProperty,
  1241                                   nsIRDFNode* aTarget)
  1243     // Make sure that the assertion isn't masked by another
  1244     // datasource.
  1245     //
  1246     // XXX We could make this more efficient if we knew _which_
  1247     // datasource actually served up the OnAssert(): we could use
  1248     // HasAssertionN() to only search datasources _before_ the
  1249     // datasource that coughed up the assertion.
  1250 	nsresult	rv = NS_OK;
  1252 	if (mAllowNegativeAssertions)
  1254 		bool hasAssertion;
  1255 		rv = HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion);
  1256 		if (NS_FAILED(rv)) return rv;
  1258 		if (! hasAssertion)
  1259 			return(NS_OK);
  1262     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
  1263         mObservers[i]->OnAssert(this, aSource, aProperty, aTarget);
  1265     return NS_OK;
  1268 NS_IMETHODIMP
  1269 CompositeDataSourceImpl::OnUnassert(nsIRDFDataSource* aDataSource,
  1270                                     nsIRDFResource* aSource,
  1271                                     nsIRDFResource* aProperty,
  1272                                     nsIRDFNode* aTarget)
  1274     // Make sure that the un-assertion doesn't just unmask the
  1275     // same assertion in a different datasource.
  1276     //
  1277     // XXX We could make this more efficient if we knew _which_
  1278     // datasource actually served up the OnAssert(): we could use
  1279     // HasAssertionN() to only search datasources _before_ the
  1280     // datasource that coughed up the assertion.
  1281     nsresult rv;
  1283 	if (mAllowNegativeAssertions)
  1285 		bool hasAssertion;
  1286 		rv = HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion);
  1287 		if (NS_FAILED(rv)) return rv;
  1289 		if (hasAssertion)
  1290 			return NS_OK;
  1293     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
  1294         mObservers[i]->OnUnassert(this, aSource, aProperty, aTarget);
  1296     return NS_OK;
  1300 NS_IMETHODIMP
  1301 CompositeDataSourceImpl::OnChange(nsIRDFDataSource* aDataSource,
  1302                                   nsIRDFResource* aSource,
  1303                                   nsIRDFResource* aProperty,
  1304                                   nsIRDFNode* aOldTarget,
  1305                                   nsIRDFNode* aNewTarget)
  1307     // Make sure that the change is actually visible, and not hidden
  1308     // by an assertion in a different datasource.
  1309     //
  1310     // XXX Because of aggregation, this could actually mutate into a
  1311     // variety of OnAssert or OnChange notifications, which we'll
  1312     // ignore for now :-/.
  1313     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
  1314         mObservers[i]->OnChange(this, aSource, aProperty,
  1315                                 aOldTarget, aNewTarget);
  1317     return NS_OK;
  1321 NS_IMETHODIMP
  1322 CompositeDataSourceImpl::OnMove(nsIRDFDataSource* aDataSource,
  1323                                 nsIRDFResource* aOldSource,
  1324                                 nsIRDFResource* aNewSource,
  1325                                 nsIRDFResource* aProperty,
  1326                                 nsIRDFNode* aTarget)
  1328     // Make sure that the move is actually visible, and not hidden
  1329     // by an assertion in a different datasource.
  1330     //
  1331     // XXX Because of aggregation, this could actually mutate into a
  1332     // variety of OnAssert or OnMove notifications, which we'll
  1333     // ignore for now :-/.
  1334     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
  1335         mObservers[i]->OnMove(this, aOldSource, aNewSource,
  1336                               aProperty, aTarget);
  1338     return NS_OK;
  1342 NS_IMETHODIMP
  1343 CompositeDataSourceImpl::OnBeginUpdateBatch(nsIRDFDataSource* aDataSource)
  1345     if (mUpdateBatchNest++ == 0) {
  1346         for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
  1347             mObservers[i]->OnBeginUpdateBatch(this);
  1350     return NS_OK;
  1354 NS_IMETHODIMP
  1355 CompositeDataSourceImpl::OnEndUpdateBatch(nsIRDFDataSource* aDataSource)
  1357     NS_ASSERTION(mUpdateBatchNest > 0, "badly nested update batch");
  1358     if (--mUpdateBatchNest == 0) {
  1359         for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
  1360             mObservers[i]->OnEndUpdateBatch(this);
  1363     return NS_OK;

mercurial