LCOV - code coverage report
Current view: top level - rdf/base - nsCompositeDataSource.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 517 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 71 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/. */
       5             : 
       6             : /*
       7             : 
       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.
      11             : 
      12             : 
      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.
      17             : 
      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.
      23             : 
      24             :      The implementation below doesn't really do this and needs to be
      25             :      fixed.
      26             : 
      27             : */
      28             : 
      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"
      42             : 
      43             : #include "nsEnumeratorUtils.h"
      44             : 
      45             : #include "mozilla/Logging.h"
      46             : #include <stdio.h>
      47             : mozilla::LazyLogModule nsRDFLog("RDF");
      48             : 
      49             : //----------------------------------------------------------------------
      50             : //
      51             : // CompositeDataSourceImpl
      52             : //
      53             : 
      54             : class CompositeEnumeratorImpl;
      55             : class CompositeArcsInOutEnumeratorImpl;
      56             : class CompositeAssertionEnumeratorImpl;
      57             : 
      58             : class CompositeDataSourceImpl : public nsIRDFCompositeDataSource,
      59             :                                 public nsIRDFObserver
      60             : {
      61             : public:
      62             :     CompositeDataSourceImpl(void);
      63             :     explicit CompositeDataSourceImpl(char** dataSources);
      64             : 
      65             :     // nsISupports interface
      66             :     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
      67           0 :     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(CompositeDataSourceImpl,
      68             :                                              nsIRDFCompositeDataSource)
      69             : 
      70             :     // nsIRDFDataSource interface
      71             :     NS_DECL_NSIRDFDATASOURCE
      72             : 
      73             :     // nsIRDFCompositeDataSource interface
      74             :     NS_DECL_NSIRDFCOMPOSITEDATASOURCE
      75             : 
      76             :     // nsIRDFObserver interface
      77             :     NS_DECL_NSIRDFOBSERVER
      78             : 
      79             :     bool HasAssertionN(int n, nsIRDFResource* source,
      80             :                             nsIRDFResource* property,
      81             :                             nsIRDFNode* target,
      82             :                             bool tv);
      83             : 
      84             : protected:
      85             :     nsCOMArray<nsIRDFObserver> mObservers;
      86             :     nsCOMArray<nsIRDFDataSource> mDataSources;
      87             : 
      88             :     bool        mAllowNegativeAssertions;
      89             :     bool        mCoalesceDuplicateArcs;
      90             :     int32_t     mUpdateBatchNest;
      91             : 
      92           0 :     virtual ~CompositeDataSourceImpl() {}
      93             : 
      94             :     friend class CompositeEnumeratorImpl;
      95             :     friend class CompositeArcsInOutEnumeratorImpl;
      96             :     friend class CompositeAssertionEnumeratorImpl;
      97             : };
      98             : 
      99             : //----------------------------------------------------------------------
     100             : //
     101             : // CompositeEnumeratorImpl
     102             : //
     103             : 
     104             : class CompositeEnumeratorImpl : public nsISimpleEnumerator
     105             : {
     106             :     // nsISupports
     107             :     NS_DECL_ISUPPORTS
     108             : 
     109             :     // nsISimpleEnumerator interface
     110             :     NS_DECL_NSISIMPLEENUMERATOR
     111             : 
     112             :     // pure abstract methods to be overridden
     113             :     virtual nsresult
     114             :     GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult) = 0;
     115             : 
     116             :     virtual nsresult
     117             :     HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult) = 0;
     118             : 
     119             : protected:
     120             :     CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
     121             :                             bool aAllowNegativeAssertions,
     122             :                             bool aCoalesceDuplicateArcs);
     123             : 
     124             :     virtual ~CompositeEnumeratorImpl();
     125             : 
     126             :     CompositeDataSourceImpl* mCompositeDataSource;
     127             : 
     128             :     nsISimpleEnumerator* mCurrent;
     129             :     nsIRDFNode*  mResult;
     130             :     int32_t      mNext;
     131             :     AutoTArray<nsCOMPtr<nsIRDFNode>, 8>  mAlreadyReturned;
     132             :     bool mAllowNegativeAssertions;
     133             :     bool mCoalesceDuplicateArcs;
     134             : };
     135             : 
     136             : 
     137           0 : CompositeEnumeratorImpl::CompositeEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
     138             :                                                  bool aAllowNegativeAssertions,
     139           0 :                                                  bool aCoalesceDuplicateArcs)
     140             :     : mCompositeDataSource(aCompositeDataSource),
     141             :       mCurrent(nullptr),
     142             :       mResult(nullptr),
     143             :           mNext(0),
     144             :       mAllowNegativeAssertions(aAllowNegativeAssertions),
     145           0 :       mCoalesceDuplicateArcs(aCoalesceDuplicateArcs)
     146             : {
     147           0 :     NS_ADDREF(mCompositeDataSource);
     148           0 : }
     149             : 
     150             : 
     151           0 : CompositeEnumeratorImpl::~CompositeEnumeratorImpl(void)
     152             : {
     153           0 :     NS_IF_RELEASE(mCurrent);
     154           0 :     NS_IF_RELEASE(mResult);
     155           0 :     NS_RELEASE(mCompositeDataSource);
     156           0 : }
     157             : 
     158           0 : NS_IMPL_ADDREF(CompositeEnumeratorImpl)
     159           0 : NS_IMPL_RELEASE(CompositeEnumeratorImpl)
     160           0 : NS_IMPL_QUERY_INTERFACE(CompositeEnumeratorImpl, nsISimpleEnumerator)
     161             : 
     162             : NS_IMETHODIMP
     163           0 : CompositeEnumeratorImpl::HasMoreElements(bool* aResult)
     164             : {
     165           0 :     NS_PRECONDITION(aResult != nullptr, "null ptr");
     166           0 :     if (! aResult)
     167           0 :         return NS_ERROR_NULL_POINTER;
     168             : 
     169             :     nsresult rv;
     170             : 
     171             :     // If we've already queued up a next target, then yep, there are
     172             :     // more elements.
     173           0 :     if (mResult) {
     174           0 :         *aResult = true;
     175           0 :         return NS_OK;
     176             :     }
     177             : 
     178             :     // Otherwise, we'll need to find a next target, switching cursors
     179             :     // if necessary.
     180           0 :     for ( ; mNext < mCompositeDataSource->mDataSources.Count(); ++mNext) {
     181           0 :         if (! mCurrent) {
     182             :             // We don't have a current enumerator, so create a new one on
     183             :             // the next data source.
     184             :             nsIRDFDataSource* datasource =
     185           0 :                 mCompositeDataSource->mDataSources[mNext];
     186             : 
     187           0 :             rv = GetEnumerator(datasource, &mCurrent);
     188           0 :             if (NS_FAILED(rv)) return rv;
     189           0 :             if (rv == NS_RDF_NO_VALUE)
     190           0 :                 continue;
     191             : 
     192           0 :             NS_ASSERTION(mCurrent != nullptr, "you're always supposed to return an enumerator from GetEnumerator, punk.");
     193           0 :             if (! mCurrent)
     194           0 :                 continue;
     195             :         }
     196             : 
     197             :         do {
     198             :             int32_t i;
     199             : 
     200             :             bool hasMore;
     201           0 :             rv = mCurrent->HasMoreElements(&hasMore);
     202           0 :             if (NS_FAILED(rv)) return rv;
     203             : 
     204             :             // Is the current enumerator depleted?
     205           0 :             if (! hasMore) {
     206           0 :                 NS_RELEASE(mCurrent);
     207           0 :                 break;
     208             :             }
     209             : 
     210             :             // Even if the current enumerator has more elements, we still
     211             :             // need to check that the current element isn't masked by
     212             :             // a negation in an earlier data source.
     213             : 
     214             :             // "Peek" ahead and pull out the next target.
     215           0 :             nsCOMPtr<nsISupports> result;
     216           0 :             rv = mCurrent->GetNext(getter_AddRefs(result));
     217           0 :             if (NS_FAILED(rv)) return rv;
     218             : 
     219           0 :             rv = result->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) &mResult);
     220           0 :             if (NS_FAILED(rv)) return rv;
     221             : 
     222           0 :             if (mAllowNegativeAssertions)
     223             :             {
     224             :                 // See if any previous data source negates this
     225           0 :                 bool hasNegation = false;
     226           0 :                 for (i = mNext - 1; i >= 0; --i)
     227             :                 {
     228             :                     nsIRDFDataSource* datasource =
     229           0 :                         mCompositeDataSource->mDataSources[i];
     230             : 
     231           0 :                     rv = HasNegation(datasource, mResult, &hasNegation);
     232           0 :                     if (NS_FAILED(rv)) return rv;
     233             : 
     234           0 :                     if (hasNegation)
     235           0 :                         break;
     236             :                 }
     237             : 
     238             :                 // if so, we've gotta keep looking
     239           0 :                 if (hasNegation)
     240             :                 {
     241           0 :                     NS_RELEASE(mResult);
     242           0 :                     continue;
     243             :                 }
     244             :             }
     245             : 
     246           0 :             if (mCoalesceDuplicateArcs)
     247             :             {
     248             :                 // Now see if we've returned it once already.
     249             :                 // XXX N.B. performance here...may want to hash if things get large?
     250           0 :                 bool alreadyReturned = false;
     251           0 :                 for (i = mAlreadyReturned.Length() - 1; i >= 0; --i)
     252             :                 {
     253           0 :                     if (mAlreadyReturned[i] == mResult)
     254             :                     {
     255           0 :                         alreadyReturned = true;
     256           0 :                         break;
     257             :                     }
     258             :                 }
     259           0 :                 if (alreadyReturned)
     260             :                 {
     261           0 :                     NS_RELEASE(mResult);
     262           0 :                     continue;
     263             :                 }
     264             :             }
     265             : 
     266             :             // If we get here, then we've really found one. It'll
     267             :             // remain cached in mResult until GetNext() sucks it out.
     268           0 :             *aResult = true;
     269             : 
     270             :             // Remember that we returned it, so we don't return duplicates.
     271             : 
     272             :             // XXX I wonder if we should make unique-checking be
     273             :             // optional. This could get to be pretty expensive (this
     274             :             // implementation turns iteration into O(n^2)).
     275             : 
     276           0 :             if (mCoalesceDuplicateArcs)
     277             :             {
     278           0 :                 mAlreadyReturned.AppendElement(mResult);
     279             :             }
     280             : 
     281           0 :             return NS_OK;
     282             :         } while (1);
     283             :     }
     284             : 
     285             :     // if we get here, there aren't any elements left.
     286           0 :     *aResult = false;
     287           0 :     return NS_OK;
     288             : }
     289             : 
     290             : 
     291             : NS_IMETHODIMP
     292           0 : CompositeEnumeratorImpl::GetNext(nsISupports** aResult)
     293             : {
     294             :     nsresult rv;
     295             : 
     296             :     bool hasMore;
     297           0 :     rv = HasMoreElements(&hasMore);
     298           0 :     if (NS_FAILED(rv)) return rv;
     299             : 
     300           0 :     if (! hasMore)
     301           0 :         return NS_ERROR_UNEXPECTED;
     302             : 
     303             :     // Don't AddRef: we "transfer" ownership to the caller
     304           0 :     *aResult = mResult;
     305           0 :     mResult = nullptr;
     306             : 
     307           0 :     return NS_OK;
     308             : }
     309             : 
     310             : //----------------------------------------------------------------------
     311             : //
     312             : // CompositeArcsInOutEnumeratorImpl
     313             : //
     314             : //
     315             : 
     316             : class CompositeArcsInOutEnumeratorImpl : public CompositeEnumeratorImpl
     317             : {
     318             : public:
     319             :     enum Type { eArcsIn, eArcsOut };
     320             : 
     321             :     virtual ~CompositeArcsInOutEnumeratorImpl();
     322             : 
     323             :     virtual nsresult
     324             :     GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult);
     325             : 
     326             :     virtual nsresult
     327             :     HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult);
     328             : 
     329             :     CompositeArcsInOutEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
     330             :                                      nsIRDFNode* aNode,
     331             :                                      Type aType,
     332             :                                      bool aAllowNegativeAssertions,
     333             :                                      bool aCoalesceDuplicateArcs);
     334             : 
     335             : private:
     336             :     nsIRDFNode* mNode;
     337             :     Type        mType;
     338             : };
     339             : 
     340             : 
     341           0 : CompositeArcsInOutEnumeratorImpl::CompositeArcsInOutEnumeratorImpl(
     342             :                 CompositeDataSourceImpl* aCompositeDataSource,
     343             :                 nsIRDFNode* aNode,
     344             :                 Type aType,
     345             :                 bool aAllowNegativeAssertions,
     346           0 :                 bool aCoalesceDuplicateArcs)
     347             :     : CompositeEnumeratorImpl(aCompositeDataSource, aAllowNegativeAssertions, aCoalesceDuplicateArcs),
     348             :       mNode(aNode),
     349           0 :       mType(aType)
     350             : {
     351           0 :     NS_ADDREF(mNode);
     352           0 : }
     353             : 
     354           0 : CompositeArcsInOutEnumeratorImpl::~CompositeArcsInOutEnumeratorImpl()
     355             : {
     356           0 :     NS_RELEASE(mNode);
     357           0 : }
     358             : 
     359             : 
     360             : nsresult
     361           0 : CompositeArcsInOutEnumeratorImpl::GetEnumerator(
     362             :                  nsIRDFDataSource* aDataSource,
     363             :                  nsISimpleEnumerator** aResult)
     364             : {
     365           0 :     if (mType == eArcsIn) {
     366           0 :         return aDataSource->ArcLabelsIn(mNode, aResult);
     367             :     }
     368             :     else {
     369           0 :         nsCOMPtr<nsIRDFResource> resource( do_QueryInterface(mNode) );
     370           0 :         return aDataSource->ArcLabelsOut(resource, aResult);
     371             :     }
     372             : }
     373             : 
     374             : nsresult
     375           0 : CompositeArcsInOutEnumeratorImpl::HasNegation(
     376             :                  nsIRDFDataSource* aDataSource,
     377             :                  nsIRDFNode* aNode,
     378             :                  bool* aResult)
     379             : {
     380           0 :     *aResult = false;
     381           0 :     return NS_OK;
     382             : }
     383             : 
     384             : 
     385             : //----------------------------------------------------------------------
     386             : //
     387             : // CompositeAssertionEnumeratorImpl
     388             : //
     389             : 
     390             : class CompositeAssertionEnumeratorImpl : public CompositeEnumeratorImpl
     391             : {
     392             : public:
     393             :     virtual nsresult
     394             :     GetEnumerator(nsIRDFDataSource* aDataSource, nsISimpleEnumerator** aResult);
     395             : 
     396             :     virtual nsresult
     397             :     HasNegation(nsIRDFDataSource* aDataSource, nsIRDFNode* aNode, bool* aResult);
     398             : 
     399             :     CompositeAssertionEnumeratorImpl(CompositeDataSourceImpl* aCompositeDataSource,
     400             :                                      nsIRDFResource* aSource,
     401             :                                      nsIRDFResource* aProperty,
     402             :                                      nsIRDFNode* aTarget,
     403             :                                      bool aTruthValue,
     404             :                                      bool aAllowNegativeAssertions,
     405             :                                      bool aCoalesceDuplicateArcs);
     406             : 
     407             :     virtual ~CompositeAssertionEnumeratorImpl();
     408             : 
     409             : private:
     410             :     nsIRDFResource* mSource;
     411             :     nsIRDFResource* mProperty;
     412             :     nsIRDFNode*     mTarget;
     413             :     bool            mTruthValue;
     414             : };
     415             : 
     416             : 
     417           0 : CompositeAssertionEnumeratorImpl::CompositeAssertionEnumeratorImpl(
     418             :                   CompositeDataSourceImpl* aCompositeDataSource,
     419             :                   nsIRDFResource* aSource,
     420             :                   nsIRDFResource* aProperty,
     421             :                   nsIRDFNode* aTarget,
     422             :                   bool aTruthValue,
     423             :                   bool aAllowNegativeAssertions,
     424           0 :                   bool aCoalesceDuplicateArcs)
     425             :     : CompositeEnumeratorImpl(aCompositeDataSource, aAllowNegativeAssertions, aCoalesceDuplicateArcs),
     426             :       mSource(aSource),
     427             :       mProperty(aProperty),
     428             :       mTarget(aTarget),
     429           0 :       mTruthValue(aTruthValue)
     430             : {
     431           0 :     NS_IF_ADDREF(mSource);
     432           0 :     NS_ADDREF(mProperty); // always must be specified
     433           0 :     NS_IF_ADDREF(mTarget);
     434           0 : }
     435             : 
     436           0 : CompositeAssertionEnumeratorImpl::~CompositeAssertionEnumeratorImpl()
     437             : {
     438           0 :     NS_IF_RELEASE(mSource);
     439           0 :     NS_RELEASE(mProperty);
     440           0 :     NS_IF_RELEASE(mTarget);
     441           0 : }
     442             : 
     443             : 
     444             : nsresult
     445           0 : CompositeAssertionEnumeratorImpl::GetEnumerator(
     446             :                  nsIRDFDataSource* aDataSource,
     447             :                  nsISimpleEnumerator** aResult)
     448             : {
     449           0 :     if (mSource) {
     450           0 :         return aDataSource->GetTargets(mSource, mProperty, mTruthValue, aResult);
     451             :     }
     452             :     else {
     453           0 :         return aDataSource->GetSources(mProperty, mTarget, mTruthValue, aResult);
     454             :     }
     455             : }
     456             : 
     457             : nsresult
     458           0 : CompositeAssertionEnumeratorImpl::HasNegation(
     459             :                  nsIRDFDataSource* aDataSource,
     460             :                  nsIRDFNode* aNode,
     461             :                  bool* aResult)
     462             : {
     463           0 :     if (mSource) {
     464           0 :         return aDataSource->HasAssertion(mSource, mProperty, aNode, !mTruthValue, aResult);
     465             :     }
     466             :     else {
     467           0 :         nsCOMPtr<nsIRDFResource> source( do_QueryInterface(aNode) );
     468           0 :         return aDataSource->HasAssertion(source, mProperty, mTarget, !mTruthValue, aResult);
     469             :     }
     470             : }
     471             : 
     472             : ////////////////////////////////////////////////////////////////////////
     473             : 
     474             : nsresult
     475           0 : NS_NewRDFCompositeDataSource(nsIRDFCompositeDataSource** result)
     476             : {
     477           0 :     CompositeDataSourceImpl* db = new CompositeDataSourceImpl();
     478           0 :     if (! db)
     479           0 :         return NS_ERROR_OUT_OF_MEMORY;
     480             : 
     481           0 :     *result = db;
     482           0 :     NS_ADDREF(*result);
     483           0 :     return NS_OK;
     484             : }
     485             : 
     486             : 
     487           0 : CompositeDataSourceImpl::CompositeDataSourceImpl(void)
     488             :         : mAllowNegativeAssertions(true),
     489             :           mCoalesceDuplicateArcs(true),
     490           0 :       mUpdateBatchNest(0)
     491             : {
     492           0 : }
     493             : 
     494             : //----------------------------------------------------------------------
     495             : //
     496             : // nsISupports interface
     497             : //
     498             : 
     499             : NS_IMPL_CYCLE_COLLECTION_CLASS(CompositeDataSourceImpl)
     500             : 
     501           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(CompositeDataSourceImpl)
     502           0 :     uint32_t i, count = tmp->mDataSources.Count();
     503           0 :     for (i = count; i > 0; --i) {
     504           0 :         tmp->mDataSources[i - 1]->RemoveObserver(tmp);
     505           0 :         tmp->mDataSources.RemoveObjectAt(i - 1);
     506             :     }
     507           0 :     NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservers);
     508           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     509           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CompositeDataSourceImpl)
     510           0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservers)
     511           0 :     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDataSources)
     512           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     513             : 
     514             : 
     515           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(CompositeDataSourceImpl)
     516           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(CompositeDataSourceImpl)
     517             : 
     518           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CompositeDataSourceImpl)
     519           0 :     NS_INTERFACE_MAP_ENTRY(nsIRDFCompositeDataSource)
     520           0 :     NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
     521           0 :     NS_INTERFACE_MAP_ENTRY(nsIRDFObserver)
     522           0 :     NS_INTERFACE_MAP_ENTRY(nsIRDFCompositeDataSource)
     523           0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFCompositeDataSource)
     524           0 : NS_INTERFACE_MAP_END
     525             : 
     526             : 
     527             : //----------------------------------------------------------------------
     528             : //
     529             : // nsIRDFDataSource interface
     530             : //
     531             : 
     532             : NS_IMETHODIMP
     533           0 : CompositeDataSourceImpl::GetURI(char* *uri)
     534             : {
     535           0 :     *uri = nullptr;
     536           0 :     return NS_OK;
     537             : }
     538             : 
     539             : NS_IMETHODIMP
     540           0 : CompositeDataSourceImpl::GetSource(nsIRDFResource* property,
     541             :                                    nsIRDFNode* target,
     542             :                                    bool tv,
     543             :                                    nsIRDFResource** source)
     544             : {
     545           0 :         if (!mAllowNegativeAssertions && !tv)
     546           0 :                 return(NS_RDF_NO_VALUE);
     547             : 
     548           0 :     int32_t count = mDataSources.Count();
     549           0 :     for (int32_t i = 0; i < count; ++i) {
     550             :         nsresult rv;
     551           0 :         rv = mDataSources[i]->GetSource(property, target, tv, source);
     552           0 :         if (NS_FAILED(rv)) return rv;
     553             : 
     554           0 :         if (rv == NS_RDF_NO_VALUE)
     555           0 :             continue;
     556             : 
     557           0 :         if (!mAllowNegativeAssertions) return(NS_OK);
     558             : 
     559             :         // okay, found it. make sure we don't have the opposite
     560             :         // asserted in a more local data source
     561           0 :         if (!HasAssertionN(count-1, *source, property, target, !tv))
     562           0 :             return NS_OK;
     563             : 
     564           0 :         NS_RELEASE(*source);
     565           0 :         return NS_RDF_NO_VALUE;
     566             :     }
     567           0 :     return NS_RDF_NO_VALUE;
     568             : }
     569             : 
     570             : NS_IMETHODIMP
     571           0 : CompositeDataSourceImpl::GetSources(nsIRDFResource* aProperty,
     572             :                                     nsIRDFNode* aTarget,
     573             :                                     bool aTruthValue,
     574             :                                     nsISimpleEnumerator** aResult)
     575             : {
     576           0 :     NS_PRECONDITION(aProperty != nullptr, "null ptr");
     577           0 :     if (! aProperty)
     578           0 :         return NS_ERROR_NULL_POINTER;
     579             : 
     580           0 :     NS_PRECONDITION(aTarget != nullptr, "null ptr");
     581           0 :     if (! aTarget)
     582           0 :         return NS_ERROR_NULL_POINTER;
     583             : 
     584           0 :     NS_PRECONDITION(aResult != nullptr, "null ptr");
     585           0 :     if (! aResult)
     586           0 :         return NS_ERROR_NULL_POINTER;
     587             : 
     588           0 :     if (! mAllowNegativeAssertions && ! aTruthValue)
     589           0 :         return(NS_RDF_NO_VALUE);
     590             : 
     591           0 :     *aResult = new CompositeAssertionEnumeratorImpl(this, nullptr, aProperty,
     592             :                                                     aTarget, aTruthValue,
     593           0 :                                                     mAllowNegativeAssertions,
     594           0 :                                                     mCoalesceDuplicateArcs);
     595             : 
     596           0 :     if (! *aResult)
     597           0 :         return NS_ERROR_OUT_OF_MEMORY;
     598             : 
     599           0 :     NS_ADDREF(*aResult);
     600           0 :     return NS_OK;
     601             : }
     602             : 
     603             : NS_IMETHODIMP
     604           0 : CompositeDataSourceImpl::GetTarget(nsIRDFResource* aSource,
     605             :                                    nsIRDFResource* aProperty,
     606             :                                    bool aTruthValue,
     607             :                                    nsIRDFNode** aResult)
     608             : {
     609           0 :     NS_PRECONDITION(aSource != nullptr, "null ptr");
     610           0 :     if (! aSource)
     611           0 :         return NS_ERROR_NULL_POINTER;
     612             : 
     613           0 :     NS_PRECONDITION(aProperty != nullptr, "null ptr");
     614           0 :     if (! aProperty)
     615           0 :         return NS_ERROR_NULL_POINTER;
     616             : 
     617           0 :     NS_PRECONDITION(aResult != nullptr, "null ptr");
     618           0 :     if (! aResult)
     619           0 :         return NS_ERROR_NULL_POINTER;
     620             : 
     621           0 :     if (! mAllowNegativeAssertions && ! aTruthValue)
     622           0 :         return(NS_RDF_NO_VALUE);
     623             : 
     624           0 :     int32_t count = mDataSources.Count();
     625           0 :     for (int32_t i = 0; i < count; ++i) {
     626             :         nsresult rv;
     627           0 :         rv = mDataSources[i]->GetTarget(aSource, aProperty, aTruthValue,
     628           0 :                                         aResult);
     629           0 :         if (NS_FAILED(rv))
     630           0 :             return rv;
     631             : 
     632           0 :         if (rv == NS_OK) {
     633             :             // okay, found it. make sure we don't have the opposite
     634             :             // asserted in an earlier data source
     635             : 
     636           0 :             if (mAllowNegativeAssertions) {
     637           0 :                 if (HasAssertionN(count-1, aSource, aProperty, *aResult, !aTruthValue)) {
     638             :                     // whoops, it's been negated.
     639           0 :                     NS_RELEASE(*aResult);
     640           0 :                     return NS_RDF_NO_VALUE;
     641             :                 }
     642             :             }
     643           0 :             return NS_OK;
     644             :         }
     645             :     }
     646             : 
     647             :     // Otherwise, we couldn't find it at all.
     648           0 :     return NS_RDF_NO_VALUE;
     649             : }
     650             : 
     651             : bool
     652           0 : CompositeDataSourceImpl::HasAssertionN(int n,
     653             :                                        nsIRDFResource* aSource,
     654             :                                        nsIRDFResource* aProperty,
     655             :                                        nsIRDFNode* aTarget,
     656             :                                        bool aTruthValue)
     657             : {
     658             :     nsresult rv;
     659           0 :     for (int32_t m = 0; m < n; ++m) {
     660             :         bool result;
     661           0 :         rv = mDataSources[m]->HasAssertion(aSource, aProperty, aTarget,
     662           0 :                                            aTruthValue, &result);
     663           0 :         if (NS_FAILED(rv))
     664           0 :             return false;
     665             : 
     666             :         // found it!
     667           0 :         if (result)
     668           0 :             return true;
     669             :     }
     670           0 :     return false;
     671             : }
     672             : 
     673             : 
     674             : 
     675             : NS_IMETHODIMP
     676           0 : CompositeDataSourceImpl::GetTargets(nsIRDFResource* aSource,
     677             :                                     nsIRDFResource* aProperty,
     678             :                                     bool aTruthValue,
     679             :                                     nsISimpleEnumerator** aResult)
     680             : {
     681           0 :     NS_PRECONDITION(aSource != nullptr, "null ptr");
     682           0 :     if (! aSource)
     683           0 :         return NS_ERROR_NULL_POINTER;
     684             : 
     685           0 :     NS_PRECONDITION(aProperty != nullptr, "null ptr");
     686           0 :     if (! aProperty)
     687           0 :         return NS_ERROR_NULL_POINTER;
     688             : 
     689           0 :     NS_PRECONDITION(aResult != nullptr, "null ptr");
     690           0 :     if (! aResult)
     691           0 :         return NS_ERROR_NULL_POINTER;
     692             : 
     693           0 :     if (! mAllowNegativeAssertions && ! aTruthValue)
     694           0 :         return(NS_RDF_NO_VALUE);
     695             : 
     696           0 :     *aResult =
     697             :         new CompositeAssertionEnumeratorImpl(this,
     698             :                                              aSource, aProperty, nullptr,
     699             :                                              aTruthValue,
     700           0 :                                              mAllowNegativeAssertions,
     701           0 :                                              mCoalesceDuplicateArcs);
     702             : 
     703           0 :     if (! *aResult)
     704           0 :         return NS_ERROR_OUT_OF_MEMORY;
     705             : 
     706           0 :     NS_ADDREF(*aResult);
     707           0 :     return NS_OK;
     708             : }
     709             : 
     710             : NS_IMETHODIMP
     711           0 : CompositeDataSourceImpl::Assert(nsIRDFResource* aSource,
     712             :                                 nsIRDFResource* aProperty,
     713             :                                 nsIRDFNode* aTarget,
     714             :                                 bool aTruthValue)
     715             : {
     716           0 :     NS_PRECONDITION(aSource != nullptr, "null ptr");
     717           0 :     if (! aSource)
     718           0 :         return NS_ERROR_NULL_POINTER;
     719             : 
     720           0 :     NS_PRECONDITION(aProperty != nullptr, "null ptr");
     721           0 :     if (! aProperty)
     722           0 :         return NS_ERROR_NULL_POINTER;
     723             : 
     724           0 :     NS_PRECONDITION(aTarget != nullptr, "null ptr");
     725           0 :     if (! aTarget)
     726           0 :         return NS_ERROR_NULL_POINTER;
     727             : 
     728           0 :     if (! mAllowNegativeAssertions && ! aTruthValue)
     729           0 :         return(NS_RDF_ASSERTION_REJECTED);
     730             : 
     731             :     nsresult rv;
     732             : 
     733             :     // XXX Need to add back the stuff for unblocking ...
     734             : 
     735             :     // We iterate backwards from the last data source which was added
     736             :     // ("the most remote") to the first ("the most local"), trying to
     737             :     // apply the assertion in each.
     738           0 :     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
     739           0 :         rv = mDataSources[i]->Assert(aSource, aProperty, aTarget, aTruthValue);
     740           0 :         if (NS_RDF_ASSERTION_ACCEPTED == rv)
     741           0 :             return rv;
     742             : 
     743           0 :         if (NS_FAILED(rv))
     744           0 :             return rv;
     745             :     }
     746             : 
     747             :     // nobody wanted to accept it
     748           0 :     return NS_RDF_ASSERTION_REJECTED;
     749             : }
     750             : 
     751             : NS_IMETHODIMP
     752           0 : CompositeDataSourceImpl::Unassert(nsIRDFResource* aSource,
     753             :                                   nsIRDFResource* aProperty,
     754             :                                   nsIRDFNode* aTarget)
     755             : {
     756           0 :     NS_PRECONDITION(aSource != nullptr, "null ptr");
     757           0 :     if (! aSource)
     758           0 :         return NS_ERROR_NULL_POINTER;
     759             : 
     760           0 :     NS_PRECONDITION(aProperty != nullptr, "null ptr");
     761           0 :     if (! aProperty)
     762           0 :         return NS_ERROR_NULL_POINTER;
     763             : 
     764           0 :     NS_PRECONDITION(aTarget != nullptr, "null ptr");
     765           0 :     if (! aTarget)
     766           0 :         return NS_ERROR_NULL_POINTER;
     767             : 
     768             :     nsresult rv;
     769             : 
     770             :     // Iterate through each of the datasources, starting with "the
     771             :     // most local" and moving to "the most remote". If _any_ of the
     772             :     // datasources have the assertion, attempt to unassert it.
     773           0 :     bool unasserted = true;
     774             :     int32_t i;
     775           0 :     int32_t count = mDataSources.Count();
     776           0 :     for (i = 0; i < count; ++i) {
     777           0 :         nsIRDFDataSource* ds = mDataSources[i];
     778             : 
     779             :         bool hasAssertion;
     780           0 :         rv = ds->HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion);
     781           0 :         if (NS_FAILED(rv)) return rv;
     782             : 
     783           0 :         if (hasAssertion) {
     784           0 :             rv = ds->Unassert(aSource, aProperty, aTarget);
     785           0 :             if (NS_FAILED(rv)) return rv;
     786             : 
     787           0 :             if (rv != NS_RDF_ASSERTION_ACCEPTED) {
     788           0 :                 unasserted = false;
     789           0 :                 break;
     790             :             }
     791             :         }
     792             :     }
     793             : 
     794             :     // Either none of the datasources had it, or they were all willing
     795             :     // to let it be unasserted.
     796           0 :     if (unasserted)
     797           0 :         return NS_RDF_ASSERTION_ACCEPTED;
     798             : 
     799             :     // If we get here, one of the datasources already had the
     800             :     // assertion, and was adamant about not letting us remove
     801             :     // it. Iterate from the "most local" to the "most remote"
     802             :     // attempting to assert the negation...
     803           0 :     for (i = 0; i < count; ++i) {
     804           0 :         rv = mDataSources[i]->Assert(aSource, aProperty, aTarget, false);
     805           0 :         if (NS_FAILED(rv)) return rv;
     806             : 
     807             :         // Did it take?
     808           0 :         if (rv == NS_RDF_ASSERTION_ACCEPTED)
     809           0 :             return rv;
     810             :     }
     811             : 
     812             :     // Couln't get anyone to accept the negation, either.
     813           0 :     return NS_RDF_ASSERTION_REJECTED;
     814             : }
     815             : 
     816             : NS_IMETHODIMP
     817           0 : CompositeDataSourceImpl::Change(nsIRDFResource* aSource,
     818             :                                 nsIRDFResource* aProperty,
     819             :                                 nsIRDFNode* aOldTarget,
     820             :                                 nsIRDFNode* aNewTarget)
     821             : {
     822           0 :     NS_PRECONDITION(aSource != nullptr, "null ptr");
     823           0 :     if (! aSource)
     824           0 :         return NS_ERROR_NULL_POINTER;
     825             : 
     826           0 :     NS_PRECONDITION(aProperty != nullptr, "null ptr");
     827           0 :     if (! aProperty)
     828           0 :         return NS_ERROR_NULL_POINTER;
     829             : 
     830           0 :     NS_PRECONDITION(aOldTarget != nullptr, "null ptr");
     831           0 :     if (! aOldTarget)
     832           0 :         return NS_ERROR_NULL_POINTER;
     833             : 
     834           0 :     NS_PRECONDITION(aNewTarget != nullptr, "null ptr");
     835           0 :     if (! aNewTarget)
     836           0 :         return NS_ERROR_NULL_POINTER;
     837             : 
     838             :     nsresult rv;
     839             : 
     840             :     // XXX So we're assuming that a datasource _must_ accept the
     841             :     // atomic change; i.e., we can't split it up across two
     842             :     // datasources. That sucks.
     843             : 
     844             :     // We iterate backwards from the last data source which was added
     845             :     // ("the most remote") to the first ("the most local"), trying to
     846             :     // apply the change in each.
     847           0 :     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
     848           0 :         rv = mDataSources[i]->Change(aSource, aProperty, aOldTarget, aNewTarget);
     849           0 :         if (NS_RDF_ASSERTION_ACCEPTED == rv)
     850           0 :             return rv;
     851             : 
     852           0 :         if (NS_FAILED(rv))
     853           0 :             return rv;
     854             :     }
     855             : 
     856             :     // nobody wanted to accept it
     857           0 :     return NS_RDF_ASSERTION_REJECTED;
     858             : }
     859             : 
     860             : NS_IMETHODIMP
     861           0 : CompositeDataSourceImpl::Move(nsIRDFResource* aOldSource,
     862             :                               nsIRDFResource* aNewSource,
     863             :                               nsIRDFResource* aProperty,
     864             :                               nsIRDFNode* aTarget)
     865             : {
     866           0 :     NS_PRECONDITION(aOldSource != nullptr, "null ptr");
     867           0 :     if (! aOldSource)
     868           0 :         return NS_ERROR_NULL_POINTER;
     869             : 
     870           0 :     NS_PRECONDITION(aNewSource != nullptr, "null ptr");
     871           0 :     if (! aNewSource)
     872           0 :         return NS_ERROR_NULL_POINTER;
     873             : 
     874           0 :     NS_PRECONDITION(aProperty != nullptr, "null ptr");
     875           0 :     if (! aProperty)
     876           0 :         return NS_ERROR_NULL_POINTER;
     877             : 
     878           0 :     NS_PRECONDITION(aTarget != nullptr, "null ptr");
     879           0 :     if (! aTarget)
     880           0 :         return NS_ERROR_NULL_POINTER;
     881             : 
     882             :     nsresult rv;
     883             : 
     884             :     // XXX So we're assuming that a datasource _must_ accept the
     885             :     // atomic move; i.e., we can't split it up across two
     886             :     // datasources. That sucks.
     887             : 
     888             :     // We iterate backwards from the last data source which was added
     889             :     // ("the most remote") to the first ("the most local"), trying to
     890             :     // apply the assertion in each.
     891           0 :     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
     892           0 :         rv = mDataSources[i]->Move(aOldSource, aNewSource, aProperty, aTarget);
     893           0 :         if (NS_RDF_ASSERTION_ACCEPTED == rv)
     894           0 :             return rv;
     895             : 
     896           0 :         if (NS_FAILED(rv))
     897           0 :             return rv;
     898             :     }
     899             : 
     900             :     // nobody wanted to accept it
     901           0 :     return NS_RDF_ASSERTION_REJECTED;
     902             : }
     903             : 
     904             : 
     905             : NS_IMETHODIMP
     906           0 : CompositeDataSourceImpl::HasAssertion(nsIRDFResource* aSource,
     907             :                                       nsIRDFResource* aProperty,
     908             :                                       nsIRDFNode* aTarget,
     909             :                                       bool aTruthValue,
     910             :                                       bool* aResult)
     911             : {
     912           0 :     NS_PRECONDITION(aSource != nullptr, "null ptr");
     913           0 :     if (! aSource)
     914           0 :         return NS_ERROR_NULL_POINTER;
     915             : 
     916           0 :     NS_PRECONDITION(aProperty != nullptr, "null ptr");
     917           0 :     if (! aProperty)
     918           0 :         return NS_ERROR_NULL_POINTER;
     919             : 
     920           0 :     NS_PRECONDITION(aResult != nullptr, "null ptr");
     921           0 :     if (! aResult)
     922           0 :         return NS_ERROR_NULL_POINTER;
     923             : 
     924           0 :     if (! mAllowNegativeAssertions && ! aTruthValue)
     925             :     {
     926           0 :         *aResult = false;
     927           0 :         return(NS_OK);
     928             :     }
     929             : 
     930             :     nsresult rv;
     931             : 
     932             :     // Otherwise, look through all the data sources to see if anyone
     933             :     // has the positive...
     934           0 :     int32_t count = mDataSources.Count();
     935           0 :     for (int32_t i = 0; i < count; ++i) {
     936           0 :         nsIRDFDataSource* datasource = mDataSources[i];
     937           0 :         rv = datasource->HasAssertion(aSource, aProperty, aTarget, aTruthValue, aResult);
     938           0 :         if (NS_FAILED(rv)) return rv;
     939             : 
     940           0 :         if (*aResult)
     941           0 :             return NS_OK;
     942             : 
     943           0 :         if (mAllowNegativeAssertions)
     944             :         {
     945             :             bool hasNegation;
     946           0 :             rv = datasource->HasAssertion(aSource, aProperty, aTarget, !aTruthValue, &hasNegation);
     947           0 :             if (NS_FAILED(rv)) return rv;
     948             : 
     949           0 :             if (hasNegation)
     950             :             {
     951           0 :                 *aResult = false;
     952           0 :                 return NS_OK;
     953             :             }
     954             :         }
     955             :     }
     956             : 
     957             :     // If we get here, nobody had the assertion at all
     958           0 :     *aResult = false;
     959           0 :     return NS_OK;
     960             : }
     961             : 
     962             : NS_IMETHODIMP
     963           0 : CompositeDataSourceImpl::AddObserver(nsIRDFObserver* aObserver)
     964             : {
     965           0 :     NS_PRECONDITION(aObserver != nullptr, "null ptr");
     966           0 :     if (! aObserver)
     967           0 :         return NS_ERROR_NULL_POINTER;
     968             : 
     969             :     // XXX ensure uniqueness?
     970           0 :     mObservers.AppendObject(aObserver);
     971             : 
     972           0 :     return NS_OK;
     973             : }
     974             : 
     975             : NS_IMETHODIMP
     976           0 : CompositeDataSourceImpl::RemoveObserver(nsIRDFObserver* aObserver)
     977             : {
     978           0 :     NS_PRECONDITION(aObserver != nullptr, "null ptr");
     979           0 :     if (! aObserver)
     980           0 :         return NS_ERROR_NULL_POINTER;
     981             : 
     982           0 :     mObservers.RemoveObject(aObserver);
     983             : 
     984           0 :     return NS_OK;
     985             : }
     986             : 
     987             : NS_IMETHODIMP
     988           0 : CompositeDataSourceImpl::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result)
     989             : {
     990             :     nsresult rv;
     991           0 :     *result = false;
     992           0 :     int32_t count = mDataSources.Count();
     993           0 :     for (int32_t i = 0; i < count; ++i) {
     994           0 :         rv = mDataSources[i]->HasArcIn(aNode, aArc, result);
     995           0 :         if (NS_FAILED(rv)) return rv;
     996           0 :         if (*result)
     997           0 :             return NS_OK;
     998             :     }
     999           0 :     return NS_OK;
    1000             : }
    1001             : 
    1002             : NS_IMETHODIMP
    1003           0 : CompositeDataSourceImpl::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result)
    1004             : {
    1005             :     nsresult rv;
    1006           0 :     *result = false;
    1007           0 :     int32_t count = mDataSources.Count();
    1008           0 :     for (int32_t i = 0; i < count; ++i) {
    1009           0 :         rv = mDataSources[i]->HasArcOut(aSource, aArc, result);
    1010           0 :         if (NS_FAILED(rv)) return rv;
    1011           0 :         if (*result)
    1012           0 :             return NS_OK;
    1013             :     }
    1014           0 :     return NS_OK;
    1015             : }
    1016             : 
    1017             : NS_IMETHODIMP
    1018           0 : CompositeDataSourceImpl::ArcLabelsIn(nsIRDFNode* aTarget, nsISimpleEnumerator** aResult)
    1019             : {
    1020           0 :     NS_PRECONDITION(aTarget != nullptr, "null ptr");
    1021           0 :     if (! aTarget)
    1022           0 :         return NS_ERROR_NULL_POINTER;
    1023             : 
    1024           0 :     NS_PRECONDITION(aResult != nullptr, "null ptr");
    1025           0 :     if (! aResult)
    1026           0 :         return NS_ERROR_NULL_POINTER;
    1027             : 
    1028             :     nsISimpleEnumerator* result =
    1029             :         new CompositeArcsInOutEnumeratorImpl(this, aTarget,
    1030             :                                              CompositeArcsInOutEnumeratorImpl::eArcsIn,
    1031           0 :                                              mAllowNegativeAssertions,
    1032           0 :                                              mCoalesceDuplicateArcs);
    1033             : 
    1034           0 :     if (! result)
    1035           0 :         return NS_ERROR_OUT_OF_MEMORY;
    1036             : 
    1037           0 :     NS_ADDREF(result);
    1038           0 :     *aResult = result;
    1039           0 :     return NS_OK;
    1040             : }
    1041             : 
    1042             : NS_IMETHODIMP
    1043           0 : CompositeDataSourceImpl::ArcLabelsOut(nsIRDFResource* aSource,
    1044             :                                       nsISimpleEnumerator** aResult)
    1045             : {
    1046           0 :     NS_PRECONDITION(aSource != nullptr, "null ptr");
    1047           0 :     if (! aSource)
    1048           0 :         return NS_ERROR_NULL_POINTER;
    1049             : 
    1050           0 :     NS_PRECONDITION(aResult != nullptr, "null ptr");
    1051           0 :     if (! aResult)
    1052           0 :         return NS_ERROR_NULL_POINTER;
    1053             : 
    1054             :     nsISimpleEnumerator* result =
    1055             :         new CompositeArcsInOutEnumeratorImpl(this, aSource,
    1056             :                                              CompositeArcsInOutEnumeratorImpl::eArcsOut,
    1057           0 :                                              mAllowNegativeAssertions,
    1058           0 :                                              mCoalesceDuplicateArcs);
    1059             : 
    1060           0 :     if (! result)
    1061           0 :         return NS_ERROR_OUT_OF_MEMORY;
    1062             : 
    1063           0 :     NS_ADDREF(result);
    1064           0 :     *aResult = result;
    1065           0 :     return NS_OK;
    1066             : }
    1067             : 
    1068             : NS_IMETHODIMP
    1069           0 : CompositeDataSourceImpl::GetAllResources(nsISimpleEnumerator** aResult)
    1070             : {
    1071           0 :     NS_NOTYETIMPLEMENTED("CompositeDataSourceImpl::GetAllResources");
    1072           0 :     return NS_ERROR_NOT_IMPLEMENTED;
    1073             : }
    1074             : 
    1075             : NS_IMETHODIMP
    1076           0 : CompositeDataSourceImpl::GetAllCmds(nsIRDFResource* source,
    1077             :                                     nsISimpleEnumerator/*<nsIRDFResource>*/** result)
    1078             : {
    1079             :     nsresult rv;
    1080           0 :     nsCOMPtr<nsISimpleEnumerator> set;
    1081             : 
    1082           0 :     for (int32_t i = 0; i < mDataSources.Count(); i++)
    1083             :     {
    1084           0 :         nsCOMPtr<nsISimpleEnumerator> dsCmds;
    1085             : 
    1086           0 :         rv = mDataSources[i]->GetAllCmds(source, getter_AddRefs(dsCmds));
    1087           0 :         if (NS_SUCCEEDED(rv))
    1088             :         {
    1089           0 :             nsCOMPtr<nsISimpleEnumerator> tmp;
    1090           0 :             rv = NS_NewUnionEnumerator(getter_AddRefs(tmp), set, dsCmds);
    1091           0 :             set.swap(tmp);
    1092           0 :             if (NS_FAILED(rv)) return(rv);
    1093             :         }
    1094             :     }
    1095             : 
    1096           0 :     set.forget(result);
    1097           0 :     return NS_OK;
    1098             : }
    1099             : 
    1100             : NS_IMETHODIMP
    1101           0 : CompositeDataSourceImpl::IsCommandEnabled(nsISupports/* nsIRDFResource container */* aSources,
    1102             :                                           nsIRDFResource*   aCommand,
    1103             :                                           nsISupports/* nsIRDFResource container */* aArguments,
    1104             :                                           bool* aResult)
    1105             : {
    1106             :     nsresult rv;
    1107           0 :     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
    1108           0 :         bool enabled = true;
    1109           0 :         rv = mDataSources[i]->IsCommandEnabled(aSources, aCommand, aArguments, &enabled);
    1110           0 :         if (NS_FAILED(rv) && (rv != NS_ERROR_NOT_IMPLEMENTED))
    1111             :         {
    1112           0 :             return(rv);
    1113             :         }
    1114             : 
    1115           0 :         if (! enabled) {
    1116           0 :             *aResult = false;
    1117           0 :             return(NS_OK);
    1118             :         }
    1119             :     }
    1120           0 :     *aResult = true;
    1121           0 :     return(NS_OK);
    1122             : }
    1123             : 
    1124             : NS_IMETHODIMP
    1125           0 : CompositeDataSourceImpl::DoCommand(nsISupports/* nsIRDFResource container */* aSources,
    1126             :                                    nsIRDFResource*   aCommand,
    1127             :                                    nsISupports/* nsIRDFResource container */* aArguments)
    1128             : {
    1129           0 :     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
    1130           0 :         nsresult rv = mDataSources[i]->DoCommand(aSources, aCommand, aArguments);
    1131           0 :         if (NS_FAILED(rv) && (rv != NS_ERROR_NOT_IMPLEMENTED))
    1132             :         {
    1133           0 :             return(rv);   // all datasources must succeed
    1134             :         }
    1135             :     }
    1136           0 :     return(NS_OK);
    1137             : }
    1138             : 
    1139             : NS_IMETHODIMP
    1140           0 : CompositeDataSourceImpl::BeginUpdateBatch()
    1141             : {
    1142           0 :     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
    1143           0 :         mDataSources[i]->BeginUpdateBatch();
    1144             :     }
    1145           0 :     return NS_OK;
    1146             : }
    1147             : 
    1148             : NS_IMETHODIMP
    1149           0 : CompositeDataSourceImpl::EndUpdateBatch()
    1150             : {
    1151           0 :     for (int32_t i = mDataSources.Count() - 1; i >= 0; --i) {
    1152           0 :         mDataSources[i]->EndUpdateBatch();
    1153             :     }
    1154           0 :     return NS_OK;
    1155             : }
    1156             : 
    1157             : ////////////////////////////////////////////////////////////////////////
    1158             : // nsIRDFCompositeDataSource methods
    1159             : // XXX rvg We should make this take an additional argument specifying where
    1160             : // in the sequence of data sources (of the db), the new data source should
    1161             : // fit in. Right now, the new datasource gets stuck at the end.
    1162             : // need to add the observers of the CompositeDataSourceImpl to the new data source.
    1163             : 
    1164             : NS_IMETHODIMP
    1165           0 : CompositeDataSourceImpl::GetAllowNegativeAssertions(bool *aAllowNegativeAssertions)
    1166             : {
    1167           0 :         *aAllowNegativeAssertions = mAllowNegativeAssertions;
    1168           0 :         return(NS_OK);
    1169             : }
    1170             : 
    1171             : NS_IMETHODIMP
    1172           0 : CompositeDataSourceImpl::SetAllowNegativeAssertions(bool aAllowNegativeAssertions)
    1173             : {
    1174           0 :         mAllowNegativeAssertions = aAllowNegativeAssertions;
    1175           0 :         return(NS_OK);
    1176             : }
    1177             : 
    1178             : NS_IMETHODIMP
    1179           0 : CompositeDataSourceImpl::GetCoalesceDuplicateArcs(bool *aCoalesceDuplicateArcs)
    1180             : {
    1181           0 :         *aCoalesceDuplicateArcs = mCoalesceDuplicateArcs;
    1182           0 :         return(NS_OK);
    1183             : }
    1184             : 
    1185             : NS_IMETHODIMP
    1186           0 : CompositeDataSourceImpl::SetCoalesceDuplicateArcs(bool aCoalesceDuplicateArcs)
    1187             : {
    1188           0 :         mCoalesceDuplicateArcs = aCoalesceDuplicateArcs;
    1189           0 :         return(NS_OK);
    1190             : }
    1191             : 
    1192             : NS_IMETHODIMP
    1193           0 : CompositeDataSourceImpl::AddDataSource(nsIRDFDataSource* aDataSource)
    1194             : {
    1195           0 :     NS_ASSERTION(aDataSource != nullptr, "null ptr");
    1196           0 :     if (! aDataSource)
    1197           0 :         return NS_ERROR_NULL_POINTER;
    1198             : 
    1199           0 :     mDataSources.AppendObject(aDataSource);
    1200           0 :     aDataSource->AddObserver(this);
    1201           0 :     return NS_OK;
    1202             : }
    1203             : 
    1204             : 
    1205             : 
    1206             : NS_IMETHODIMP
    1207           0 : CompositeDataSourceImpl::RemoveDataSource(nsIRDFDataSource* aDataSource)
    1208             : {
    1209           0 :     NS_ASSERTION(aDataSource != nullptr, "null ptr");
    1210           0 :     if (! aDataSource)
    1211           0 :         return NS_ERROR_NULL_POINTER;
    1212             : 
    1213             : 
    1214           0 :     if (mDataSources.IndexOf(aDataSource) >= 0) {
    1215           0 :         aDataSource->RemoveObserver(this);
    1216           0 :         mDataSources.RemoveObject(aDataSource);
    1217             :     }
    1218           0 :     return NS_OK;
    1219             : }
    1220             : 
    1221             : 
    1222             : NS_IMETHODIMP
    1223           0 : CompositeDataSourceImpl::GetDataSources(nsISimpleEnumerator** _result)
    1224             : {
    1225             :     // NS_NewArrayEnumerator for an nsCOMArray takes a snapshot of the
    1226             :     // current state.
    1227           0 :     return NS_NewArrayEnumerator(_result, mDataSources);
    1228             : }
    1229             : 
    1230             : NS_IMETHODIMP
    1231           0 : CompositeDataSourceImpl::OnAssert(nsIRDFDataSource* aDataSource,
    1232             :                                   nsIRDFResource* aSource,
    1233             :                                   nsIRDFResource* aProperty,
    1234             :                                   nsIRDFNode* aTarget)
    1235             : {
    1236             :     // Make sure that the assertion isn't masked by another
    1237             :     // datasource.
    1238             :     //
    1239             :     // XXX We could make this more efficient if we knew _which_
    1240             :     // datasource actually served up the OnAssert(): we could use
    1241             :     // HasAssertionN() to only search datasources _before_ the
    1242             :     // datasource that coughed up the assertion.
    1243           0 :         nsresult        rv = NS_OK;
    1244             : 
    1245           0 :         if (mAllowNegativeAssertions)
    1246             :         {
    1247             :                 bool hasAssertion;
    1248           0 :                 rv = HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion);
    1249           0 :                 if (NS_FAILED(rv)) return rv;
    1250             : 
    1251           0 :                 if (! hasAssertion)
    1252           0 :                         return(NS_OK);
    1253             :         }
    1254             : 
    1255           0 :     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
    1256           0 :         mObservers[i]->OnAssert(this, aSource, aProperty, aTarget);
    1257             :     }
    1258           0 :     return NS_OK;
    1259             : }
    1260             : 
    1261             : NS_IMETHODIMP
    1262           0 : CompositeDataSourceImpl::OnUnassert(nsIRDFDataSource* aDataSource,
    1263             :                                     nsIRDFResource* aSource,
    1264             :                                     nsIRDFResource* aProperty,
    1265             :                                     nsIRDFNode* aTarget)
    1266             : {
    1267             :     // Make sure that the un-assertion doesn't just unmask the
    1268             :     // same assertion in a different datasource.
    1269             :     //
    1270             :     // XXX We could make this more efficient if we knew _which_
    1271             :     // datasource actually served up the OnAssert(): we could use
    1272             :     // HasAssertionN() to only search datasources _before_ the
    1273             :     // datasource that coughed up the assertion.
    1274             :     nsresult rv;
    1275             : 
    1276           0 :         if (mAllowNegativeAssertions)
    1277             :         {
    1278             :                 bool hasAssertion;
    1279           0 :                 rv = HasAssertion(aSource, aProperty, aTarget, true, &hasAssertion);
    1280           0 :                 if (NS_FAILED(rv)) return rv;
    1281             : 
    1282           0 :                 if (hasAssertion)
    1283           0 :                         return NS_OK;
    1284             :         }
    1285             : 
    1286           0 :     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
    1287           0 :         mObservers[i]->OnUnassert(this, aSource, aProperty, aTarget);
    1288             :     }
    1289           0 :     return NS_OK;
    1290             : }
    1291             : 
    1292             : 
    1293             : NS_IMETHODIMP
    1294           0 : CompositeDataSourceImpl::OnChange(nsIRDFDataSource* aDataSource,
    1295             :                                   nsIRDFResource* aSource,
    1296             :                                   nsIRDFResource* aProperty,
    1297             :                                   nsIRDFNode* aOldTarget,
    1298             :                                   nsIRDFNode* aNewTarget)
    1299             : {
    1300             :     // Make sure that the change is actually visible, and not hidden
    1301             :     // by an assertion in a different datasource.
    1302             :     //
    1303             :     // XXX Because of aggregation, this could actually mutate into a
    1304             :     // variety of OnAssert or OnChange notifications, which we'll
    1305             :     // ignore for now :-/.
    1306           0 :     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
    1307           0 :         mObservers[i]->OnChange(this, aSource, aProperty,
    1308           0 :                                 aOldTarget, aNewTarget);
    1309             :     }
    1310           0 :     return NS_OK;
    1311             : }
    1312             : 
    1313             : 
    1314             : NS_IMETHODIMP
    1315           0 : CompositeDataSourceImpl::OnMove(nsIRDFDataSource* aDataSource,
    1316             :                                 nsIRDFResource* aOldSource,
    1317             :                                 nsIRDFResource* aNewSource,
    1318             :                                 nsIRDFResource* aProperty,
    1319             :                                 nsIRDFNode* aTarget)
    1320             : {
    1321             :     // Make sure that the move is actually visible, and not hidden
    1322             :     // by an assertion in a different datasource.
    1323             :     //
    1324             :     // XXX Because of aggregation, this could actually mutate into a
    1325             :     // variety of OnAssert or OnMove notifications, which we'll
    1326             :     // ignore for now :-/.
    1327           0 :     for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
    1328           0 :         mObservers[i]->OnMove(this, aOldSource, aNewSource,
    1329           0 :                               aProperty, aTarget);
    1330             :     }
    1331           0 :     return NS_OK;
    1332             : }
    1333             : 
    1334             : 
    1335             : NS_IMETHODIMP
    1336           0 : CompositeDataSourceImpl::OnBeginUpdateBatch(nsIRDFDataSource* aDataSource)
    1337             : {
    1338           0 :     if (mUpdateBatchNest++ == 0) {
    1339           0 :         for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
    1340           0 :             mObservers[i]->OnBeginUpdateBatch(this);
    1341             :         }
    1342             :     }
    1343           0 :     return NS_OK;
    1344             : }
    1345             : 
    1346             : 
    1347             : NS_IMETHODIMP
    1348           0 : CompositeDataSourceImpl::OnEndUpdateBatch(nsIRDFDataSource* aDataSource)
    1349             : {
    1350           0 :     NS_ASSERTION(mUpdateBatchNest > 0, "badly nested update batch");
    1351           0 :     if (--mUpdateBatchNest == 0) {
    1352           0 :         for (int32_t i = mObservers.Count() - 1; i >= 0; --i) {
    1353           0 :             mObservers[i]->OnEndUpdateBatch(this);
    1354             :         }
    1355             :     }
    1356           0 :     return NS_OK;
    1357             : }

Generated by: LCOV version 1.13