|
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 test program that reads in RDF/XML into an in-memory data |
|
9 source, then periodically updates it. It prints the messages |
|
10 indicating assert and unassert activity to the console. |
|
11 |
|
12 The program takes two parameters: the URL from which to read, and |
|
13 the poll-interval at which to re-load the . |
|
14 |
|
15 */ |
|
16 |
|
17 #include <stdlib.h> |
|
18 #include <stdio.h> |
|
19 #include "nsXPCOM.h" |
|
20 #include "nsCOMPtr.h" |
|
21 #include "nsIInputStream.h" |
|
22 #include "nsIIOService.h" |
|
23 #include "nsIRDFCompositeDataSource.h" |
|
24 #include "nsIRDFRemoteDataSource.h" |
|
25 #include "nsIRDFNode.h" |
|
26 #include "nsIRDFService.h" |
|
27 #include "nsIRDFXMLSource.h" |
|
28 #include "nsIServiceManager.h" |
|
29 #include "nsServiceManagerUtils.h" |
|
30 #include "nsIStreamListener.h" |
|
31 #include "nsIURL.h" |
|
32 #include "nsRDFCID.h" |
|
33 #include "nsIComponentManager.h" |
|
34 #include "nsComponentManagerUtils.h" |
|
35 #include "nsThreadUtils.h" |
|
36 #include "prthread.h" |
|
37 #include "plstr.h" |
|
38 #include "nsEmbedString.h" |
|
39 #include "nsNetCID.h" |
|
40 #include "prtime.h" |
|
41 |
|
42 //////////////////////////////////////////////////////////////////////// |
|
43 // CIDs |
|
44 |
|
45 // rdf |
|
46 static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID); |
|
47 |
|
48 //////////////////////////////////////////////////////////////////////// |
|
49 // IIDs |
|
50 |
|
51 |
|
52 #include "nsIMemory.h" // for the CID |
|
53 |
|
54 //////////////////////////////////////////////////////////////////////// |
|
55 |
|
56 class Observer : public nsIRDFObserver |
|
57 { |
|
58 public: |
|
59 Observer(); |
|
60 virtual ~Observer() {} |
|
61 |
|
62 // nsISupports interface |
|
63 NS_DECL_ISUPPORTS |
|
64 |
|
65 // nsIRDFObserver interface |
|
66 NS_DECL_NSIRDFOBSERVER |
|
67 }; |
|
68 |
|
69 Observer::Observer() |
|
70 { |
|
71 } |
|
72 |
|
73 NS_IMPL_ISUPPORTS(Observer, nsIRDFObserver) |
|
74 |
|
75 static nsresult |
|
76 rdf_WriteOp(const char* aOp, |
|
77 nsIRDFResource* aSource, |
|
78 nsIRDFResource* aProperty, |
|
79 nsIRDFNode* aTarget) |
|
80 { |
|
81 nsresult rv; |
|
82 |
|
83 nsCString source; |
|
84 rv = aSource->GetValue(getter_Copies(source)); |
|
85 if (NS_FAILED(rv)) return rv; |
|
86 |
|
87 nsCString property; |
|
88 rv = aProperty->GetValue(getter_Copies(property)); |
|
89 if (NS_FAILED(rv)) return rv; |
|
90 |
|
91 nsCOMPtr<nsIRDFResource> resource; |
|
92 nsCOMPtr<nsIRDFLiteral> literal; |
|
93 nsCOMPtr<nsIRDFDate> date; |
|
94 nsCOMPtr<nsIRDFInt> number; |
|
95 |
|
96 printf("%.8s [%s]\n", aOp, source.get()); |
|
97 printf(" --[%s]--\n", property.get()); |
|
98 |
|
99 if ((resource = do_QueryInterface(aTarget)) != nullptr) { |
|
100 nsCString target; |
|
101 rv = resource->GetValue(getter_Copies(target)); |
|
102 if (NS_FAILED(rv)) return rv; |
|
103 |
|
104 printf(" ->[%s]\n", target.get()); |
|
105 } |
|
106 else if ((literal = do_QueryInterface(aTarget)) != nullptr) { |
|
107 nsString target; |
|
108 rv = literal->GetValue(getter_Copies(target)); |
|
109 if (NS_FAILED(rv)) return rv; |
|
110 |
|
111 printf(" ->\"%s\"\n", NS_ConvertUTF16toUTF8(target).get()); |
|
112 } |
|
113 else if ((date = do_QueryInterface(aTarget)) != nullptr) { |
|
114 PRTime value; |
|
115 date->GetValue(&value); |
|
116 |
|
117 PRExplodedTime t; |
|
118 PR_ExplodeTime(value, PR_GMTParameters, &t); |
|
119 |
|
120 printf(" -> %02d/%02d/%04d %02d:%02d:%02d +%06d\n", |
|
121 t.tm_month + 1, |
|
122 t.tm_mday, |
|
123 t.tm_year, |
|
124 t.tm_hour, |
|
125 t.tm_min, |
|
126 t.tm_sec, |
|
127 t.tm_usec); |
|
128 } |
|
129 else if ((number = do_QueryInterface(aTarget)) != nullptr) { |
|
130 int32_t value; |
|
131 number->GetValue(&value); |
|
132 |
|
133 printf(" -> %d\n", value); |
|
134 } |
|
135 else { |
|
136 printf(" -> (unknown node type)\n"); |
|
137 } |
|
138 |
|
139 printf("\n"); |
|
140 return NS_OK; |
|
141 } |
|
142 |
|
143 NS_IMETHODIMP |
|
144 Observer::OnAssert(nsIRDFDataSource* aDataSource, |
|
145 nsIRDFResource* aSource, |
|
146 nsIRDFResource* aProperty, |
|
147 nsIRDFNode* aTarget) |
|
148 { |
|
149 return rdf_WriteOp("assert", aSource, aProperty, aTarget); |
|
150 } |
|
151 |
|
152 |
|
153 NS_IMETHODIMP |
|
154 Observer::OnUnassert(nsIRDFDataSource* aDataSource, |
|
155 nsIRDFResource* aSource, |
|
156 nsIRDFResource* aProperty, |
|
157 nsIRDFNode* aTarget) |
|
158 { |
|
159 return rdf_WriteOp("unassert", aSource, aProperty, aTarget); |
|
160 } |
|
161 |
|
162 |
|
163 NS_IMETHODIMP |
|
164 Observer::OnChange(nsIRDFDataSource* aDataSource, |
|
165 nsIRDFResource* aSource, |
|
166 nsIRDFResource* aProperty, |
|
167 nsIRDFNode* aOldTarget, |
|
168 nsIRDFNode* aNewTarget) |
|
169 { |
|
170 nsresult rv; |
|
171 rv = rdf_WriteOp("chg-from", aSource, aProperty, aOldTarget); |
|
172 if (NS_FAILED(rv)) return rv; |
|
173 |
|
174 rv = rdf_WriteOp("chg-to", aSource, aProperty, aNewTarget); |
|
175 if (NS_FAILED(rv)) return rv; |
|
176 |
|
177 return NS_OK; |
|
178 } |
|
179 |
|
180 NS_IMETHODIMP |
|
181 Observer::OnMove(nsIRDFDataSource* aDataSource, |
|
182 nsIRDFResource* aOldSource, |
|
183 nsIRDFResource* aNewSource, |
|
184 nsIRDFResource* aProperty, |
|
185 nsIRDFNode* aTarget) |
|
186 { |
|
187 nsresult rv; |
|
188 rv = rdf_WriteOp("mv-from", aOldSource, aProperty, aTarget); |
|
189 if (NS_FAILED(rv)) return rv; |
|
190 |
|
191 rv = rdf_WriteOp("mv-to", aNewSource, aProperty, aTarget); |
|
192 if (NS_FAILED(rv)) return rv; |
|
193 |
|
194 return NS_OK; |
|
195 } |
|
196 |
|
197 NS_IMETHODIMP |
|
198 Observer::OnBeginUpdateBatch(nsIRDFDataSource* aDataSource) |
|
199 { |
|
200 return NS_OK; |
|
201 } |
|
202 |
|
203 NS_IMETHODIMP |
|
204 Observer::OnEndUpdateBatch(nsIRDFDataSource* aDataSource) |
|
205 { |
|
206 return NS_OK; |
|
207 } |
|
208 |
|
209 //////////////////////////////////////////////////////////////////////// |
|
210 |
|
211 int |
|
212 main(int argc, char** argv) |
|
213 { |
|
214 nsresult rv; |
|
215 |
|
216 if (argc < 2) { |
|
217 fprintf(stderr, "usage: %s <url> [<poll-interval>]\n", argv[0]); |
|
218 return 1; |
|
219 } |
|
220 |
|
221 rv = NS_InitXPCOM2(nullptr, nullptr, nullptr); |
|
222 if (NS_FAILED(rv)) { |
|
223 fprintf(stderr, "NS_InitXPCOM2 failed\n"); |
|
224 return 1; |
|
225 } |
|
226 |
|
227 // Create a stream data source and initialize it on argv[1], which |
|
228 // is hopefully a "file:" URL. (Actually, we can do _any_ kind of |
|
229 // URL, but only a "file:" URL will be written back to disk.) |
|
230 nsCOMPtr<nsIRDFDataSource> ds = do_CreateInstance(kRDFXMLDataSourceCID, &rv); |
|
231 if (NS_FAILED(rv)) { |
|
232 NS_ERROR("unable to create RDF/XML data source"); |
|
233 return 1; |
|
234 } |
|
235 |
|
236 nsCOMPtr<nsIRDFRemoteDataSource> remote = do_QueryInterface(ds); |
|
237 if (! remote) |
|
238 return 1; |
|
239 |
|
240 rv = remote->Init(argv[1]); |
|
241 NS_ASSERTION(NS_SUCCEEDED(rv), "unable to initialize data source"); |
|
242 if (NS_FAILED(rv)) return 1; |
|
243 |
|
244 // The do_QI() on the pointer is a hack to make sure that the new |
|
245 // object gets AddRef()-ed. |
|
246 nsCOMPtr<nsIRDFObserver> observer = do_QueryInterface(new Observer); |
|
247 if (! observer) |
|
248 return 1; |
|
249 |
|
250 rv = ds->AddObserver(observer); |
|
251 if (NS_FAILED(rv)) return 1; |
|
252 |
|
253 while (1) { |
|
254 // Okay, this should load the XML file... |
|
255 rv = remote->Refresh(true); |
|
256 NS_ASSERTION(NS_SUCCEEDED(rv), "unable to open datasource"); |
|
257 if (NS_FAILED(rv)) return 1; |
|
258 |
|
259 if (argc <= 2) |
|
260 break; |
|
261 |
|
262 int32_t pollinterval = atol(argv[2]); |
|
263 if (! pollinterval) |
|
264 break; |
|
265 |
|
266 PR_Sleep(PR_SecondsToInterval(pollinterval)); |
|
267 } |
|
268 |
|
269 return 0; |
|
270 } |