michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: michael@0: A simple test program that reads in RDF/XML into an in-memory data michael@0: source, then periodically updates it. It prints the messages michael@0: indicating assert and unassert activity to the console. michael@0: michael@0: The program takes two parameters: the URL from which to read, and michael@0: the poll-interval at which to re-load the . michael@0: michael@0: */ michael@0: michael@0: #include michael@0: #include michael@0: #include "nsXPCOM.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsIInputStream.h" michael@0: #include "nsIIOService.h" michael@0: #include "nsIRDFCompositeDataSource.h" michael@0: #include "nsIRDFRemoteDataSource.h" michael@0: #include "nsIRDFNode.h" michael@0: #include "nsIRDFService.h" michael@0: #include "nsIRDFXMLSource.h" michael@0: #include "nsIServiceManager.h" michael@0: #include "nsServiceManagerUtils.h" michael@0: #include "nsIStreamListener.h" michael@0: #include "nsIURL.h" michael@0: #include "nsRDFCID.h" michael@0: #include "nsIComponentManager.h" michael@0: #include "nsComponentManagerUtils.h" michael@0: #include "nsThreadUtils.h" michael@0: #include "prthread.h" michael@0: #include "plstr.h" michael@0: #include "nsEmbedString.h" michael@0: #include "nsNetCID.h" michael@0: #include "prtime.h" michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: // CIDs michael@0: michael@0: // rdf michael@0: static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID); michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: // IIDs michael@0: michael@0: michael@0: #include "nsIMemory.h" // for the CID michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: michael@0: class Observer : public nsIRDFObserver michael@0: { michael@0: public: michael@0: Observer(); michael@0: virtual ~Observer() {} michael@0: michael@0: // nsISupports interface michael@0: NS_DECL_ISUPPORTS michael@0: michael@0: // nsIRDFObserver interface michael@0: NS_DECL_NSIRDFOBSERVER michael@0: }; michael@0: michael@0: Observer::Observer() michael@0: { michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS(Observer, nsIRDFObserver) michael@0: michael@0: static nsresult michael@0: rdf_WriteOp(const char* aOp, michael@0: nsIRDFResource* aSource, michael@0: nsIRDFResource* aProperty, michael@0: nsIRDFNode* aTarget) michael@0: { michael@0: nsresult rv; michael@0: michael@0: nsCString source; michael@0: rv = aSource->GetValue(getter_Copies(source)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: nsCString property; michael@0: rv = aProperty->GetValue(getter_Copies(property)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: nsCOMPtr resource; michael@0: nsCOMPtr literal; michael@0: nsCOMPtr date; michael@0: nsCOMPtr number; michael@0: michael@0: printf("%.8s [%s]\n", aOp, source.get()); michael@0: printf(" --[%s]--\n", property.get()); michael@0: michael@0: if ((resource = do_QueryInterface(aTarget)) != nullptr) { michael@0: nsCString target; michael@0: rv = resource->GetValue(getter_Copies(target)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: printf(" ->[%s]\n", target.get()); michael@0: } michael@0: else if ((literal = do_QueryInterface(aTarget)) != nullptr) { michael@0: nsString target; michael@0: rv = literal->GetValue(getter_Copies(target)); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: printf(" ->\"%s\"\n", NS_ConvertUTF16toUTF8(target).get()); michael@0: } michael@0: else if ((date = do_QueryInterface(aTarget)) != nullptr) { michael@0: PRTime value; michael@0: date->GetValue(&value); michael@0: michael@0: PRExplodedTime t; michael@0: PR_ExplodeTime(value, PR_GMTParameters, &t); michael@0: michael@0: printf(" -> %02d/%02d/%04d %02d:%02d:%02d +%06d\n", michael@0: t.tm_month + 1, michael@0: t.tm_mday, michael@0: t.tm_year, michael@0: t.tm_hour, michael@0: t.tm_min, michael@0: t.tm_sec, michael@0: t.tm_usec); michael@0: } michael@0: else if ((number = do_QueryInterface(aTarget)) != nullptr) { michael@0: int32_t value; michael@0: number->GetValue(&value); michael@0: michael@0: printf(" -> %d\n", value); michael@0: } michael@0: else { michael@0: printf(" -> (unknown node type)\n"); michael@0: } michael@0: michael@0: printf("\n"); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: Observer::OnAssert(nsIRDFDataSource* aDataSource, michael@0: nsIRDFResource* aSource, michael@0: nsIRDFResource* aProperty, michael@0: nsIRDFNode* aTarget) michael@0: { michael@0: return rdf_WriteOp("assert", aSource, aProperty, aTarget); michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: Observer::OnUnassert(nsIRDFDataSource* aDataSource, michael@0: nsIRDFResource* aSource, michael@0: nsIRDFResource* aProperty, michael@0: nsIRDFNode* aTarget) michael@0: { michael@0: return rdf_WriteOp("unassert", aSource, aProperty, aTarget); michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: Observer::OnChange(nsIRDFDataSource* aDataSource, michael@0: nsIRDFResource* aSource, michael@0: nsIRDFResource* aProperty, michael@0: nsIRDFNode* aOldTarget, michael@0: nsIRDFNode* aNewTarget) michael@0: { michael@0: nsresult rv; michael@0: rv = rdf_WriteOp("chg-from", aSource, aProperty, aOldTarget); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: rv = rdf_WriteOp("chg-to", aSource, aProperty, aNewTarget); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: Observer::OnMove(nsIRDFDataSource* aDataSource, michael@0: nsIRDFResource* aOldSource, michael@0: nsIRDFResource* aNewSource, michael@0: nsIRDFResource* aProperty, michael@0: nsIRDFNode* aTarget) michael@0: { michael@0: nsresult rv; michael@0: rv = rdf_WriteOp("mv-from", aOldSource, aProperty, aTarget); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: rv = rdf_WriteOp("mv-to", aNewSource, aProperty, aTarget); michael@0: if (NS_FAILED(rv)) return rv; michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: Observer::OnBeginUpdateBatch(nsIRDFDataSource* aDataSource) michael@0: { michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: Observer::OnEndUpdateBatch(nsIRDFDataSource* aDataSource) michael@0: { michael@0: return NS_OK; michael@0: } michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: michael@0: int michael@0: main(int argc, char** argv) michael@0: { michael@0: nsresult rv; michael@0: michael@0: if (argc < 2) { michael@0: fprintf(stderr, "usage: %s []\n", argv[0]); michael@0: return 1; michael@0: } michael@0: michael@0: rv = NS_InitXPCOM2(nullptr, nullptr, nullptr); michael@0: if (NS_FAILED(rv)) { michael@0: fprintf(stderr, "NS_InitXPCOM2 failed\n"); michael@0: return 1; michael@0: } michael@0: michael@0: // Create a stream data source and initialize it on argv[1], which michael@0: // is hopefully a "file:" URL. (Actually, we can do _any_ kind of michael@0: // URL, but only a "file:" URL will be written back to disk.) michael@0: nsCOMPtr ds = do_CreateInstance(kRDFXMLDataSourceCID, &rv); michael@0: if (NS_FAILED(rv)) { michael@0: NS_ERROR("unable to create RDF/XML data source"); michael@0: return 1; michael@0: } michael@0: michael@0: nsCOMPtr remote = do_QueryInterface(ds); michael@0: if (! remote) michael@0: return 1; michael@0: michael@0: rv = remote->Init(argv[1]); michael@0: NS_ASSERTION(NS_SUCCEEDED(rv), "unable to initialize data source"); michael@0: if (NS_FAILED(rv)) return 1; michael@0: michael@0: // The do_QI() on the pointer is a hack to make sure that the new michael@0: // object gets AddRef()-ed. michael@0: nsCOMPtr observer = do_QueryInterface(new Observer); michael@0: if (! observer) michael@0: return 1; michael@0: michael@0: rv = ds->AddObserver(observer); michael@0: if (NS_FAILED(rv)) return 1; michael@0: michael@0: while (1) { michael@0: // Okay, this should load the XML file... michael@0: rv = remote->Refresh(true); michael@0: NS_ASSERTION(NS_SUCCEEDED(rv), "unable to open datasource"); michael@0: if (NS_FAILED(rv)) return 1; michael@0: michael@0: if (argc <= 2) michael@0: break; michael@0: michael@0: int32_t pollinterval = atol(argv[2]); michael@0: if (! pollinterval) michael@0: break; michael@0: michael@0: PR_Sleep(PR_SecondsToInterval(pollinterval)); michael@0: } michael@0: michael@0: return 0; michael@0: }