Back to index

lightning-sunbird  0.9+nobinonly
rdfpoll.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 /*
00040 
00041   A simple test program that reads in RDF/XML into an in-memory data
00042   source, then periodically updates it. It prints the messages
00043   indicating assert and unassert activity to the console.
00044 
00045   The program takes two parameters: the URL from which to read, and
00046   the poll-interval at which to re-load the .
00047 
00048  */
00049 
00050 #include <stdlib.h>
00051 #include "nsXPCOM.h"
00052 #include "nsCOMPtr.h"
00053 #include "nsIEventQueueService.h"
00054 #include "nsIInputStream.h"
00055 #include "nsIIOService.h"
00056 #include "nsIRDFCompositeDataSource.h"
00057 #include "nsIRDFRemoteDataSource.h"
00058 #include "nsIRDFNode.h"
00059 #include "nsIRDFService.h"
00060 #include "nsIRDFXMLSource.h"
00061 #include "nsIServiceManager.h"
00062 #include "nsIStreamListener.h"
00063 #include "nsIURL.h"
00064 #include "nsRDFCID.h"
00065 #include "nsIComponentManager.h"
00066 #include "nsXPIDLString.h"
00067 #include "prthread.h"
00068 #include "plevent.h"
00069 #include "plstr.h"
00070 #include "nsString.h"
00071 #include "nsReadableUtils.h"
00072 #include "nsNetCID.h"
00073 #include "nsCRT.h"
00074 
00076 // CIDs
00077 
00078 // rdf
00079 static NS_DEFINE_CID(kRDFXMLDataSourceCID,  NS_RDFXMLDATASOURCE_CID);
00080 
00081 // xpcom
00082 static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
00083 
00085 // IIDs
00086 
00087 
00088 #include "nsIMemory.h" // for the CID
00089 
00091 
00092 class Observer : public nsIRDFObserver
00093 {
00094 public:
00095     Observer();
00096     virtual ~Observer() {}
00097 
00098     // nsISupports interface
00099     NS_DECL_ISUPPORTS
00100 
00101     // nsIRDFObserver interface
00102     NS_DECL_NSIRDFOBSERVER
00103 };
00104 
00105 Observer::Observer()
00106 {
00107 }
00108 
00109 NS_IMPL_ISUPPORTS1(Observer, nsIRDFObserver)
00110 
00111 static nsresult
00112 rdf_WriteOp(const char* aOp,
00113             nsIRDFResource* aSource,
00114             nsIRDFResource* aProperty,
00115             nsIRDFNode* aTarget)
00116 {
00117     nsresult rv;
00118 
00119     nsXPIDLCString source;
00120     rv = aSource->GetValue(getter_Copies(source));
00121     if (NS_FAILED(rv)) return rv;
00122 
00123     nsXPIDLCString property;
00124     rv = aProperty->GetValue(getter_Copies(property));
00125     if (NS_FAILED(rv)) return rv;
00126 
00127     nsCOMPtr<nsIRDFResource> resource;
00128     nsCOMPtr<nsIRDFLiteral> literal;
00129     nsCOMPtr<nsIRDFDate> date;
00130     nsCOMPtr<nsIRDFInt> number;
00131 
00132     printf("%.8s [%s]\n", aOp, (const char*) source);
00133     printf("       --[%s]--\n", (const char*) property);
00134 
00135     if ((resource = do_QueryInterface(aTarget)) != nsnull) {
00136         nsXPIDLCString target;
00137         rv = resource->GetValue(getter_Copies(target));
00138         if (NS_FAILED(rv)) return rv;
00139 
00140         printf("       ->[%s]\n", (const char*) target);
00141     }
00142     else if ((literal = do_QueryInterface(aTarget)) != nsnull) {
00143         nsXPIDLString target;
00144         rv = literal->GetValue(getter_Copies(target));
00145         if (NS_FAILED(rv)) return rv;
00146 
00147         char* p = ToNewCString(target);
00148         if (! p)
00149             return NS_ERROR_OUT_OF_MEMORY;
00150         
00151         printf("       ->\"%s\"\n", p);
00152 
00153         NS_Free(p);
00154     }
00155     else if ((date = do_QueryInterface(aTarget)) != nsnull) {
00156         PRTime value;
00157         date->GetValue(&value);
00158 
00159         PRExplodedTime t;
00160         PR_ExplodeTime(value, PR_GMTParameters, &t);
00161 
00162         printf("       -> %02d/%02d/%04d %02d:%02d:%02d +%06d\n",
00163                t.tm_month + 1,
00164                t.tm_mday,
00165                t.tm_year,
00166                t.tm_hour,
00167                t.tm_min,
00168                t.tm_sec,
00169                t.tm_usec);
00170     }
00171     else if ((number = do_QueryInterface(aTarget)) != nsnull) {
00172         PRInt32 value;
00173         number->GetValue(&value);
00174 
00175         printf("       -> %d\n", value);
00176     }
00177     else {
00178         printf("       -> (unknown node type)\n");
00179     }
00180 
00181     printf("\n");
00182     return NS_OK;
00183 }
00184 
00185 NS_IMETHODIMP
00186 Observer::OnAssert(nsIRDFDataSource* aDataSource,
00187                    nsIRDFResource* aSource,
00188                    nsIRDFResource* aProperty,
00189                    nsIRDFNode* aTarget)
00190 {
00191     return rdf_WriteOp("assert", aSource, aProperty, aTarget);
00192 }
00193 
00194 
00195 NS_IMETHODIMP
00196 Observer::OnUnassert(nsIRDFDataSource* aDataSource,
00197                      nsIRDFResource* aSource,
00198                      nsIRDFResource* aProperty,
00199                      nsIRDFNode* aTarget)
00200 {
00201     return rdf_WriteOp("unassert", aSource, aProperty, aTarget);
00202 }
00203 
00204 
00205 NS_IMETHODIMP
00206 Observer::OnChange(nsIRDFDataSource* aDataSource,
00207                    nsIRDFResource* aSource,
00208                    nsIRDFResource* aProperty,
00209                    nsIRDFNode* aOldTarget,
00210                    nsIRDFNode* aNewTarget)
00211 {
00212     nsresult rv;
00213     rv = rdf_WriteOp("chg-from", aSource, aProperty, aOldTarget);
00214     if (NS_FAILED(rv)) return rv;
00215 
00216     rv = rdf_WriteOp("chg-to", aSource, aProperty, aNewTarget);
00217     if (NS_FAILED(rv)) return rv;
00218 
00219     return NS_OK;
00220 }
00221 
00222 NS_IMETHODIMP
00223 Observer::OnMove(nsIRDFDataSource* aDataSource,
00224                  nsIRDFResource* aOldSource,
00225                  nsIRDFResource* aNewSource,
00226                  nsIRDFResource* aProperty,
00227                  nsIRDFNode* aTarget)
00228 {
00229     nsresult rv;
00230     rv = rdf_WriteOp("mv-from", aOldSource, aProperty, aTarget);
00231     if (NS_FAILED(rv)) return rv;
00232 
00233     rv = rdf_WriteOp("mv-to", aNewSource, aProperty, aTarget);
00234     if (NS_FAILED(rv)) return rv;
00235 
00236     return NS_OK;
00237 }
00238 
00239 NS_IMETHODIMP
00240 Observer::OnBeginUpdateBatch(nsIRDFDataSource* aDataSource)
00241 {
00242     return NS_OK;
00243 }
00244 
00245 NS_IMETHODIMP
00246 Observer::OnEndUpdateBatch(nsIRDFDataSource* aDataSource)
00247 {
00248     return NS_OK;
00249 }
00250 
00252 
00253 int
00254 main(int argc, char** argv)
00255 {
00256     nsresult rv;
00257 
00258     if (argc < 2) {
00259         fprintf(stderr, "usage: %s <url> [<poll-interval>]\n", argv[0]);
00260         return 1;
00261     }
00262 
00263     rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
00264     if (NS_FAILED(rv)) {
00265         fprintf(stderr, "NS_InitXPCOM2 failed\n");
00266         return 1;
00267     }
00268 
00269     // Get netlib off the floor...
00270     nsCOMPtr<nsIEventQueueService> theEventQueueService = 
00271              do_GetService(kEventQueueServiceCID, &rv);
00272     if (NS_FAILED(rv)) return rv;
00273 
00274     rv = theEventQueueService->CreateThreadEventQueue();
00275     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create thread event queue");
00276     if (NS_FAILED(rv)) return rv;
00277 
00278     // Create a stream data source and initialize it on argv[1], which
00279     // is hopefully a "file:" URL. (Actually, we can do _any_ kind of
00280     // URL, but only a "file:" URL will be written back to disk.)
00281     nsCOMPtr<nsIRDFDataSource> ds = do_CreateInstance(kRDFXMLDataSourceCID, &rv);
00282     if (NS_FAILED(rv)) {
00283         NS_ERROR("unable to create RDF/XML data source");
00284         return rv;
00285     }
00286 
00287     nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(ds);
00288     if (! remote)
00289         return NS_ERROR_UNEXPECTED;
00290 
00291     rv = remote->Init(argv[1]);
00292     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to initialize data source");
00293     if (NS_FAILED(rv)) return rv;
00294 
00295     // The do_QI() on the pointer is a hack to make sure that the new
00296     // object gets AddRef()-ed.
00297     nsCOMPtr<nsIRDFObserver> observer = do_QueryInterface(new Observer);
00298     if (! observer)
00299         return NS_ERROR_OUT_OF_MEMORY;
00300 
00301     rv = ds->AddObserver(observer);
00302     if (NS_FAILED(rv)) return rv;
00303 
00304     while (1) {
00305         // Okay, this should load the XML file...
00306         rv = remote->Refresh(PR_TRUE);
00307         NS_ASSERTION(NS_SUCCEEDED(rv), "unable to open datasource");
00308         if (NS_FAILED(rv)) return rv;
00309 
00310         if (argc <= 2)
00311             break;
00312 
00313         PRInt32 pollinterval = atol(argv[2]);
00314         if (! pollinterval)
00315             break;
00316 
00317         PR_Sleep(PR_SecondsToInterval(pollinterval));
00318     }
00319 
00320     return NS_OK;
00321 }