LCOV - code coverage report
Current view: top level - rdf/datasource - nsLocalStore.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 172 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 48 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             : /* vim: set cindent tabstop=4 expandtab shiftwidth=4: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : /*
       8             : 
       9             :   Implementation for the local store
      10             : 
      11             :  */
      12             : 
      13             : #include "nsNetUtil.h"
      14             : #include "nsIFile.h"
      15             : #include "nsIURI.h"
      16             : #include "nsIIOService.h"
      17             : #include "nsIOutputStream.h"
      18             : #include "nsIComponentManager.h"
      19             : #include "nsILocalStore.h"
      20             : #include "nsIRDFDataSource.h"
      21             : #include "nsIRDFRemoteDataSource.h"
      22             : #include "nsIRDFService.h"
      23             : #include "nsIServiceManager.h"
      24             : #include "nsRDFCID.h"
      25             : #include "nsXPIDLString.h"
      26             : #include "plstr.h"
      27             : #include "rdf.h"
      28             : #include "nsCOMPtr.h"
      29             : #include "nsWeakPtr.h"
      30             : #include "nsAppDirectoryServiceDefs.h"
      31             : #include "nsIObserver.h"
      32             : #include "nsIObserverService.h"
      33             : #include "nsWeakReference.h"
      34             : #include "nsCRTGlue.h"
      35             : #include "nsCRT.h"
      36             : #include "nsEnumeratorUtils.h"
      37             : #include "nsCycleCollectionParticipant.h"
      38             : 
      39             : ////////////////////////////////////////////////////////////////////////
      40             : 
      41             : class LocalStoreImpl : public nsILocalStore,
      42             :                        public nsIRDFDataSource,
      43             :                        public nsIRDFRemoteDataSource,
      44             :                        public nsIObserver,
      45             :                        public nsSupportsWeakReference
      46             : {
      47             : protected:
      48             :     nsCOMPtr<nsIRDFDataSource> mInner;
      49             : 
      50             :     LocalStoreImpl();
      51             :     virtual ~LocalStoreImpl();
      52             :     nsresult Init();
      53             :     nsresult CreateLocalStore(nsIFile* aFile);
      54             :     nsresult LoadData();
      55             : 
      56             :     friend nsresult
      57             :     NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult);
      58             : 
      59             :     nsCOMPtr<nsIRDFService>    mRDFService;
      60             : 
      61             : public:
      62             :     // nsISupports interface
      63             :     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
      64           0 :     NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(LocalStoreImpl, nsILocalStore)
      65             : 
      66             :     // nsILocalStore interface
      67             : 
      68             :     // nsIRDFDataSource interface. Most of these are just delegated to
      69             :     // the inner, in-memory datasource.
      70             :     NS_IMETHOD GetURI(char* *aURI) override;
      71             : 
      72           0 :     NS_IMETHOD GetSource(nsIRDFResource* aProperty,
      73             :                          nsIRDFNode* aTarget,
      74             :                          bool aTruthValue,
      75             :                          nsIRDFResource** aSource) override {
      76           0 :         return mInner->GetSource(aProperty, aTarget, aTruthValue, aSource);
      77             :     }
      78             : 
      79           0 :     NS_IMETHOD GetSources(nsIRDFResource* aProperty,
      80             :                           nsIRDFNode* aTarget,
      81             :                           bool aTruthValue,
      82             :                           nsISimpleEnumerator** aSources) override {
      83           0 :         return mInner->GetSources(aProperty, aTarget, aTruthValue, aSources);
      84             :     }
      85             : 
      86           0 :     NS_IMETHOD GetTarget(nsIRDFResource* aSource,
      87             :                          nsIRDFResource* aProperty,
      88             :                          bool aTruthValue,
      89             :                          nsIRDFNode** aTarget) override {
      90           0 :         return mInner->GetTarget(aSource, aProperty, aTruthValue, aTarget);
      91             :     }
      92             : 
      93           0 :     NS_IMETHOD GetTargets(nsIRDFResource* aSource,
      94             :                           nsIRDFResource* aProperty,
      95             :                           bool aTruthValue,
      96             :                           nsISimpleEnumerator** aTargets) override {
      97           0 :         return mInner->GetTargets(aSource, aProperty, aTruthValue, aTargets);
      98             :     }
      99             : 
     100           0 :     NS_IMETHOD Assert(nsIRDFResource* aSource,
     101             :                       nsIRDFResource* aProperty,
     102             :                       nsIRDFNode* aTarget,
     103             :                       bool aTruthValue) override {
     104           0 :         return mInner->Assert(aSource, aProperty, aTarget, aTruthValue);
     105             :     }
     106             : 
     107           0 :     NS_IMETHOD Unassert(nsIRDFResource* aSource,
     108             :                         nsIRDFResource* aProperty,
     109             :                         nsIRDFNode* aTarget) override {
     110           0 :         return mInner->Unassert(aSource, aProperty, aTarget);
     111             :     }
     112             : 
     113           0 :     NS_IMETHOD Change(nsIRDFResource* aSource,
     114             :                       nsIRDFResource* aProperty,
     115             :                       nsIRDFNode* aOldTarget,
     116             :                       nsIRDFNode* aNewTarget) override {
     117           0 :         return mInner->Change(aSource, aProperty, aOldTarget, aNewTarget);
     118             :     }
     119             : 
     120           0 :     NS_IMETHOD Move(nsIRDFResource* aOldSource,
     121             :                     nsIRDFResource* aNewSource,
     122             :                     nsIRDFResource* aProperty,
     123             :                     nsIRDFNode* aTarget) override {
     124           0 :         return mInner->Move(aOldSource, aNewSource, aProperty, aTarget);
     125             :     }
     126             : 
     127           0 :     NS_IMETHOD HasAssertion(nsIRDFResource* aSource,
     128             :                             nsIRDFResource* aProperty,
     129             :                             nsIRDFNode* aTarget,
     130             :                             bool aTruthValue,
     131             :                             bool* hasAssertion) override {
     132           0 :         return mInner->HasAssertion(aSource, aProperty, aTarget, aTruthValue, hasAssertion);
     133             :     }
     134             : 
     135           0 :     NS_IMETHOD AddObserver(nsIRDFObserver* aObserver) override {
     136           0 :         return NS_ERROR_NOT_IMPLEMENTED;
     137             :     }
     138             : 
     139           0 :     NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver) override {
     140           0 :         return NS_ERROR_NOT_IMPLEMENTED;
     141             :     }
     142             : 
     143           0 :     NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *_retval) override {
     144           0 :         return mInner->HasArcIn(aNode, aArc, _retval);
     145             :     }
     146             : 
     147           0 :     NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *_retval) override {
     148           0 :         return mInner->HasArcOut(aSource, aArc, _retval);
     149             :     }
     150             : 
     151           0 :     NS_IMETHOD ArcLabelsIn(nsIRDFNode* aNode,
     152             :                            nsISimpleEnumerator** aLabels) override {
     153           0 :         return mInner->ArcLabelsIn(aNode, aLabels);
     154             :     }
     155             : 
     156           0 :     NS_IMETHOD ArcLabelsOut(nsIRDFResource* aSource,
     157             :                             nsISimpleEnumerator** aLabels) override {
     158           0 :         return mInner->ArcLabelsOut(aSource, aLabels);
     159             :     }
     160             : 
     161           0 :     NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult) override {
     162           0 :         return mInner->GetAllResources(aResult);
     163             :     }
     164             : 
     165             :     NS_IMETHOD GetAllCmds(nsIRDFResource* aSource,
     166             :                               nsISimpleEnumerator/*<nsIRDFResource>*/** aCommands) override;
     167             : 
     168             :     NS_IMETHOD IsCommandEnabled(nsISupports* aSources,
     169             :                                 nsIRDFResource*   aCommand,
     170             :                                 nsISupports* aArguments,
     171             :                                 bool* aResult) override;
     172             : 
     173             :     NS_IMETHOD DoCommand(nsISupports* aSources,
     174             :                          nsIRDFResource*   aCommand,
     175             :                          nsISupports* aArguments) override;
     176             : 
     177           0 :     NS_IMETHOD BeginUpdateBatch() override {
     178           0 :         return mInner->BeginUpdateBatch();
     179             :     }
     180             : 
     181           0 :     NS_IMETHOD EndUpdateBatch() override {
     182           0 :         return mInner->EndUpdateBatch();
     183             :     }
     184             : 
     185             :     NS_IMETHOD GetLoaded(bool* _result) override;
     186             :     NS_IMETHOD Init(const char *uri) override;
     187             :     NS_IMETHOD Flush() override;
     188             :     NS_IMETHOD FlushTo(const char *aURI) override;
     189             :     NS_IMETHOD Refresh(bool sync) override;
     190             : 
     191             :     // nsIObserver
     192             :     NS_DECL_NSIOBSERVER
     193             : };
     194             : 
     195             : ////////////////////////////////////////////////////////////////////////
     196             : 
     197             : 
     198           0 : LocalStoreImpl::LocalStoreImpl(void)
     199             : {
     200           0 : }
     201             : 
     202           0 : LocalStoreImpl::~LocalStoreImpl(void)
     203             : {
     204           0 :     if (mRDFService)
     205           0 :         mRDFService->UnregisterDataSource(this);
     206           0 : }
     207             : 
     208             : 
     209             : nsresult
     210           0 : NS_NewLocalStore(nsISupports* aOuter, REFNSIID aIID, void** aResult)
     211             : {
     212           0 :     NS_PRECONDITION(aOuter == nullptr, "no aggregation");
     213           0 :     if (aOuter)
     214           0 :         return NS_ERROR_NO_AGGREGATION;
     215             : 
     216           0 :     NS_PRECONDITION(aResult != nullptr, "null ptr");
     217           0 :     if (! aResult)
     218           0 :         return NS_ERROR_NULL_POINTER;
     219             : 
     220           0 :     LocalStoreImpl* impl = new LocalStoreImpl();
     221           0 :     if (! impl)
     222           0 :         return NS_ERROR_OUT_OF_MEMORY;
     223             : 
     224           0 :     NS_ADDREF(impl);
     225             : 
     226             :     nsresult rv;
     227           0 :     rv = impl->Init();
     228           0 :     if (NS_SUCCEEDED(rv)) {
     229             :         // Set up the result pointer
     230           0 :         rv = impl->QueryInterface(aIID, aResult);
     231             :     }
     232             : 
     233           0 :     NS_RELEASE(impl);
     234           0 :     return rv;
     235             : }
     236             : 
     237           0 : NS_IMPL_CYCLE_COLLECTION(LocalStoreImpl, mInner)
     238           0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(LocalStoreImpl)
     239           0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(LocalStoreImpl)
     240             : 
     241           0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(LocalStoreImpl)
     242           0 :     NS_INTERFACE_MAP_ENTRY(nsILocalStore)
     243           0 :     NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
     244           0 :     NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource)
     245           0 :     NS_INTERFACE_MAP_ENTRY(nsIObserver)
     246           0 :     NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     247           0 :     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsILocalStore)
     248           0 : NS_INTERFACE_MAP_END
     249             : 
     250             : // nsILocalStore interface
     251             : 
     252             : // nsIRDFDataSource interface
     253             : 
     254             : NS_IMETHODIMP
     255           0 : LocalStoreImpl::GetLoaded(bool* _result)
     256             : {
     257           0 :         nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(mInner);
     258           0 :     NS_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource");
     259           0 :         if (! remote)
     260           0 :         return NS_ERROR_UNEXPECTED;
     261             : 
     262           0 :     return remote->GetLoaded(_result);
     263             : }
     264             : 
     265             : 
     266             : NS_IMETHODIMP
     267           0 : LocalStoreImpl::Init(const char *uri)
     268             : {
     269           0 :         return(NS_OK);
     270             : }
     271             : 
     272             : NS_IMETHODIMP
     273           0 : LocalStoreImpl::Flush()
     274             : {
     275           0 :         nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(mInner);
     276             :     // FIXME Bug 340242: Temporarily make this a warning rather than an
     277             :     // assertion until we sort out the ordering of how we write
     278             :     // everything to the localstore, flush it, and disconnect it when
     279             :     // we're getting profile-change notifications.
     280           0 :     NS_WARNING_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource");
     281           0 :         if (! remote)
     282           0 :         return NS_ERROR_UNEXPECTED;
     283             : 
     284           0 :     return remote->Flush();
     285             : }
     286             : 
     287             : NS_IMETHODIMP
     288           0 : LocalStoreImpl::FlushTo(const char *aURI)
     289             : {
     290             :   // Do not ever implement this (security)
     291           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     292             : }
     293             : 
     294             : NS_IMETHODIMP
     295           0 : LocalStoreImpl::Refresh(bool sync)
     296             : {
     297           0 :         nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(mInner);
     298           0 :     NS_ASSERTION(remote != nullptr, "not an nsIRDFRemoteDataSource");
     299           0 :         if (! remote)
     300           0 :         return NS_ERROR_UNEXPECTED;
     301             : 
     302           0 :     return remote->Refresh(sync);
     303             : }
     304             : 
     305             : nsresult
     306           0 : LocalStoreImpl::Init()
     307             : {
     308             :     nsresult rv;
     309             : 
     310           0 :     rv = LoadData();
     311           0 :     if (NS_FAILED(rv)) return rv;
     312             : 
     313             :     // register this as a named data source with the RDF service
     314           0 :     mRDFService = do_GetService(NS_RDF_CONTRACTID "/rdf-service;1", &rv);
     315           0 :     if (NS_FAILED(rv)) return rv;
     316             : 
     317           0 :     mRDFService->RegisterDataSource(this, false);
     318             : 
     319             :     // Register as an observer of profile changes
     320             :     nsCOMPtr<nsIObserverService> obs =
     321           0 :         do_GetService("@mozilla.org/observer-service;1");
     322             : 
     323           0 :     if (obs) {
     324           0 :         obs->AddObserver(this, "profile-before-change", true);
     325           0 :         obs->AddObserver(this, "profile-do-change", true);
     326             :     }
     327             : 
     328           0 :     return NS_OK;
     329             : }
     330             : 
     331             : nsresult
     332           0 : LocalStoreImpl::CreateLocalStore(nsIFile* aFile)
     333             : {
     334             :     nsresult rv;
     335             : 
     336           0 :     rv = aFile->Create(nsIFile::NORMAL_FILE_TYPE, 0666);
     337           0 :     if (NS_FAILED(rv)) return rv;
     338             : 
     339           0 :     nsCOMPtr<nsIOutputStream> outStream;
     340           0 :     rv = NS_NewLocalFileOutputStream(getter_AddRefs(outStream), aFile);
     341           0 :     if (NS_FAILED(rv)) return rv;
     342             : 
     343             :     const char defaultRDF[] =
     344             :         "<?xml version=\"1.0\"?>\n" \
     345             :         "<RDF:RDF xmlns:RDF=\"" RDF_NAMESPACE_URI "\"\n" \
     346             :         "         xmlns:NC=\""  NC_NAMESPACE_URI "\">\n" \
     347             :         "  <!-- Empty -->\n" \
     348           0 :         "</RDF:RDF>\n";
     349             : 
     350             :     uint32_t count;
     351           0 :     rv = outStream->Write(defaultRDF, sizeof(defaultRDF)-1, &count);
     352           0 :     if (NS_FAILED(rv)) return rv;
     353             : 
     354           0 :     if (count != sizeof(defaultRDF)-1)
     355           0 :         return NS_ERROR_UNEXPECTED;
     356             : 
     357             :     // Okay, now see if the file exists _for real_. If it's still
     358             :     // not there, it could be that the profile service gave us
     359             :     // back a read-only directory. Whatever.
     360           0 :     bool fileExistsFlag = false;
     361           0 :     aFile->Exists(&fileExistsFlag);
     362           0 :     if (!fileExistsFlag)
     363           0 :         return NS_ERROR_UNEXPECTED;
     364             : 
     365           0 :     return NS_OK;
     366             : }
     367             : 
     368             : nsresult
     369           0 : LocalStoreImpl::LoadData()
     370             : {
     371             :     nsresult rv;
     372             : 
     373             :     // Look for localstore.rdf in the current profile
     374             :     // directory. Bomb if we can't find it.
     375             : 
     376           0 :     nsCOMPtr<nsIFile> aFile;
     377           0 :     rv = NS_GetSpecialDirectory(NS_APP_LOCALSTORE_50_FILE, getter_AddRefs(aFile));
     378           0 :     if (NS_FAILED(rv)) return rv;
     379             : 
     380           0 :     bool fileExistsFlag = false;
     381           0 :     (void)aFile->Exists(&fileExistsFlag);
     382           0 :     if (!fileExistsFlag) {
     383             :         // if file doesn't exist, create it
     384           0 :         rv = CreateLocalStore(aFile);
     385           0 :         if (NS_FAILED(rv)) return rv;
     386             :     }
     387             : 
     388           0 :     mInner = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "xml-datasource", &rv);
     389           0 :     if (NS_FAILED(rv)) return rv;
     390             : 
     391           0 :     nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(mInner, &rv);
     392           0 :     if (NS_FAILED(rv)) return rv;
     393             : 
     394           0 :     nsCOMPtr<nsIURI> aURI;
     395           0 :     rv = NS_NewFileURI(getter_AddRefs(aURI), aFile);
     396           0 :     if (NS_FAILED(rv)) return rv;
     397             : 
     398           0 :     nsAutoCString spec;
     399           0 :     rv = aURI->GetSpec(spec);
     400           0 :     if (NS_FAILED(rv)) return rv;
     401             : 
     402           0 :     rv = remote->Init(spec.get());
     403           0 :     if (NS_FAILED(rv)) return rv;
     404             : 
     405             :     // Read the datasource synchronously.
     406           0 :     rv = remote->Refresh(true);
     407             : 
     408           0 :     if (NS_FAILED(rv)) {
     409             :         // Load failed, delete and recreate a fresh localstore
     410           0 :         aFile->Remove(true);
     411           0 :         rv = CreateLocalStore(aFile);
     412           0 :         if (NS_FAILED(rv)) return rv;
     413             : 
     414           0 :         rv = remote->Refresh(true);
     415             :     }
     416             : 
     417           0 :     return rv;
     418             : }
     419             : 
     420             : 
     421             : NS_IMETHODIMP
     422           0 : LocalStoreImpl::GetURI(char* *aURI)
     423             : {
     424           0 :     NS_PRECONDITION(aURI != nullptr, "null ptr");
     425           0 :     if (! aURI)
     426           0 :         return NS_ERROR_NULL_POINTER;
     427             : 
     428           0 :     *aURI = NS_strdup("rdf:local-store");
     429           0 :     if (! *aURI)
     430           0 :         return NS_ERROR_OUT_OF_MEMORY;
     431             : 
     432           0 :     return NS_OK;
     433             : }
     434             : 
     435             : 
     436             : NS_IMETHODIMP
     437           0 : LocalStoreImpl::GetAllCmds(nsIRDFResource* aSource,
     438             :                                nsISimpleEnumerator/*<nsIRDFResource>*/** aCommands)
     439             : {
     440           0 :         return(NS_NewEmptyEnumerator(aCommands));
     441             : }
     442             : 
     443             : NS_IMETHODIMP
     444           0 : LocalStoreImpl::IsCommandEnabled(nsISupports* aSources,
     445             :                                  nsIRDFResource*   aCommand,
     446             :                                  nsISupports* aArguments,
     447             :                                  bool* aResult)
     448             : {
     449           0 :     return NS_ERROR_NOT_IMPLEMENTED;
     450             : }
     451             : 
     452             : NS_IMETHODIMP
     453           0 : LocalStoreImpl::DoCommand(nsISupports* aSources,
     454             :                           nsIRDFResource*   aCommand,
     455             :                           nsISupports* aArguments)
     456             : {
     457           0 :     return NS_ERROR_NOT_IMPLEMENTED;
     458             : }
     459             : 
     460             : NS_IMETHODIMP
     461           0 : LocalStoreImpl::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData)
     462             : {
     463           0 :     nsresult rv = NS_OK;
     464             : 
     465           0 :     if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
     466             :         // Write out the old datasource's contents.
     467           0 :         if (mInner) {
     468           0 :             nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(mInner);
     469           0 :             if (remote)
     470           0 :                 remote->Flush();
     471             :         }
     472             : 
     473             :         // Create an in-memory datasource for use while we're
     474             :         // profile-less.
     475           0 :         mInner = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "in-memory-datasource");
     476             :     }
     477           0 :     else if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
     478           0 :         rv = LoadData();
     479             :     }
     480           0 :     return rv;
     481             : }

Generated by: LCOV version 1.13