|
1 // -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 |
|
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 var Cc = Components.classes; |
|
8 var Ci = Components.interfaces; |
|
9 |
|
10 var gRDF; |
|
11 |
|
12 const CLASS_MIMEINFO = "mimetype"; |
|
13 const CLASS_PROTOCOLINFO = "scheme"; |
|
14 |
|
15 // namespace prefix |
|
16 const NC_NS = "http://home.netscape.com/NC-rdf#"; |
|
17 |
|
18 // type list properties |
|
19 |
|
20 const NC_MIME_TYPES = NC_NS + "MIME-types"; |
|
21 const NC_PROTOCOL_SCHEMES = NC_NS + "Protocol-Schemes"; |
|
22 |
|
23 /////////////////////////////////////////////////////////////////////////////// |
|
24 // MIME Types DataSource Wrapper |
|
25 |
|
26 function NC_URI(aProperty) |
|
27 { |
|
28 return "http://home.netscape.com/NC-rdf#" + aProperty; |
|
29 } |
|
30 |
|
31 function MIME_URI(aType) |
|
32 { |
|
33 return "urn:mimetype:" + aType; |
|
34 } |
|
35 |
|
36 function HANDLER_URI(aHandler) |
|
37 { |
|
38 return "urn:mimetype:handler:" + aHandler; |
|
39 } |
|
40 |
|
41 function APP_URI(aType) |
|
42 { |
|
43 return "urn:mimetype:externalApplication:" + aType; |
|
44 } |
|
45 |
|
46 function ArrayEnumerator(aItems) { |
|
47 if (aItems) { |
|
48 for (var i = 0; i < aItems.length; ++i) { |
|
49 if (!aItems[i]) |
|
50 aItems.splice(i--, 1); |
|
51 } |
|
52 this._contents = aItems; |
|
53 } else { |
|
54 this._contents = []; |
|
55 } |
|
56 } |
|
57 |
|
58 ArrayEnumerator.prototype = { |
|
59 _index: 0, |
|
60 |
|
61 hasMoreElements: function () { |
|
62 return this._index < this._contents.length; |
|
63 }, |
|
64 |
|
65 getNext: function () { |
|
66 return this._contents[this._index++]; |
|
67 }, |
|
68 |
|
69 push: function (aElement) { |
|
70 if (aElement) |
|
71 this._contents.push(aElement); |
|
72 } |
|
73 }; |
|
74 |
|
75 function HelperApps() |
|
76 { |
|
77 if (!gRDF) |
|
78 gRDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService); |
|
79 |
|
80 const mimeTypes = "UMimTyp"; |
|
81 var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties); |
|
82 |
|
83 var file = fileLocator.get(mimeTypes, Components.interfaces.nsIFile); |
|
84 |
|
85 var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService); |
|
86 var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler); |
|
87 this._inner = gRDF.GetDataSourceBlocking(fileHandler.getURLSpecFromFile(file)); |
|
88 this._inner.AddObserver(this); |
|
89 |
|
90 this._fileTypeArc = gRDF.GetResource(NC_URI("FileType")); |
|
91 this._fileHandlerArc = gRDF.GetResource(NC_URI("FileHandler")); |
|
92 this._fileIconArc = gRDF.GetResource(NC_URI("FileIcon")); |
|
93 this._fileExtensionArc = gRDF.GetResource(NC_URI("FileExtension")); |
|
94 this._fileExtensionsArc = gRDF.GetResource(NC_URI("FileExtensions")); |
|
95 this._handleAutoArc = gRDF.GetResource(NC_URI("FileHandleAuto")); |
|
96 this._valueArc = gRDF.GetResource(NC_URI("value")); |
|
97 this._handlerPropArc = gRDF.GetResource(NC_URI("handlerProp")); |
|
98 this._externalAppArc = gRDF.GetResource(NC_URI("externalApplication")); |
|
99 } |
|
100 |
|
101 HelperApps.prototype = { |
|
102 mimeHandlerExists: function (aMIMEType) |
|
103 { |
|
104 var valueProperty = gRDF.GetUnicodeResource(NC_URI("value")); |
|
105 var mimeSource = gRDF.GetUnicodeResource(MIME_URI(aMIMEType)); |
|
106 var mimeLiteral = gRDF.GetLiteral(aMIMEType); |
|
107 return this._inner.HasAssertion(mimeSource, valueProperty, mimeLiteral, true); |
|
108 }, |
|
109 |
|
110 updateTypeInfo: function (aMIMEInfo) |
|
111 { |
|
112 var mimeType = aMIMEInfo.MIMEType; |
|
113 var isNewMIMEType = this.mimeHandlerExists(mimeType); |
|
114 var entry = new HandlerOverride(MIME_URI(mimeType), this._inner); |
|
115 entry.mimeType = mimeType; |
|
116 entry.isEditable = true; |
|
117 entry.alwaysAsk = aMIMEInfo.alwaysAskBeforeHandling; |
|
118 |
|
119 // If not updating (i.e., a newly encountered mime type), |
|
120 // then update extension list and description. |
|
121 if (!isNewMIMEType) { |
|
122 var extEnumerator = aMIMEInfo.getFileExtensions(); |
|
123 while (extEnumerator.hasMore()) { |
|
124 entry.addExtension(extEnumerator.getNext()); |
|
125 } |
|
126 entry.description = aMIMEInfo.description; |
|
127 entry.appDisplayName = ""; |
|
128 } |
|
129 |
|
130 const nsIMIMEInfo = Components.interfaces.nsIMIMEInfo; |
|
131 if (aMIMEInfo.preferredAction == nsIMIMEInfo.saveToDisk) { |
|
132 entry.saveToDisk = true; |
|
133 if (!isNewMIMEType) { |
|
134 // Creating a new entry, set path. |
|
135 entry.appPath = ""; |
|
136 } |
|
137 } |
|
138 else if (aMIMEInfo.preferredAction == nsIMIMEInfo.useSystemDefault || |
|
139 aMIMEInfo.preferredApplicationHandler == null) { |
|
140 entry.useSystemDefault = true; |
|
141 if (!isNewMIMEType) { |
|
142 // Creating a new entry, set path. |
|
143 entry.appPath = ""; |
|
144 } |
|
145 } |
|
146 else if (aMIMEInfo.preferredApplicationHandler instanceof Components.interfaces.nsILocalHandlerApp) { |
|
147 entry.saveToDisk = false; |
|
148 entry.useSystemDefault = false; |
|
149 entry.handleInternal = false; |
|
150 entry.appPath = aMIMEInfo.preferredApplicationHandler.executable.path; |
|
151 entry.appDisplayName = aMIMEInfo.preferredApplicationHandler.name; |
|
152 } |
|
153 |
|
154 // Do RDF magic. |
|
155 entry.buildLinks(); |
|
156 this.flush(); |
|
157 }, |
|
158 |
|
159 getLiteralValue: function (aResource, aProperty) |
|
160 { |
|
161 var res = gRDF.GetResource(aResource); |
|
162 var prop = gRDF.GetResource(NC_URI(aProperty)); |
|
163 var val = this.GetTarget(res, prop, true); |
|
164 if (val) { |
|
165 val = val.QueryInterface(Components.interfaces.nsIRDFLiteral); |
|
166 return val.Value; |
|
167 } |
|
168 return ""; |
|
169 }, |
|
170 |
|
171 /* nsIRDFDataSource */ |
|
172 get URI() { |
|
173 return this._inner.URI; |
|
174 }, |
|
175 |
|
176 GetSource: function (aProperty, aTarget, aTruthValue) { |
|
177 return this._inner.GetSource(aProperty, aTarget, aTruthValue); |
|
178 }, |
|
179 GetSources: function (aProperty, aTarget, aTruthValue) { |
|
180 return this._inner.GetSources(aProperty, aTarget, aTruthValue); |
|
181 }, |
|
182 |
|
183 _isRootTypeResource: function (aResource) { |
|
184 aResource = aResource.QueryInterface(Components.interfaces.nsIRDFResource); |
|
185 const kRootTypePrefix = "urn:mimetype:"; |
|
186 return (aResource.Value.substr(0, kRootTypePrefix.length) == kRootTypePrefix); |
|
187 }, |
|
188 |
|
189 getMIMEInfo: function (aResource) { |
|
190 var types = this._inner.GetTarget(aResource, this._valueArc, true); |
|
191 if (types) { |
|
192 types = types.QueryInterface(Components.interfaces.nsIRDFLiteral); |
|
193 types = types.Value.split(", "); |
|
194 |
|
195 mimeSvc = Components.classes["@mozilla.org/mime;1"].getService(Components.interfaces.nsIMIMEService); |
|
196 return mimeSvc.getFromTypeAndExtension(types[0], null); |
|
197 } |
|
198 |
|
199 return null; |
|
200 }, |
|
201 |
|
202 GetTarget: function (aSource, aProperty, aTruthValue) { |
|
203 if (this._isRootTypeResource(aSource)) { |
|
204 var typeInfo = this.getMIMEInfo(aSource); |
|
205 if (typeInfo) { |
|
206 var bundle = document.getElementById("strings"); |
|
207 if (aProperty.EqualsNode(this._handleAutoArc)) { |
|
208 var handler = this.GetTarget(aSource, this._handlerPropArc, true); |
|
209 if (handler) { |
|
210 handler = handler.QueryInterface(Components.interfaces.nsIRDFResource); |
|
211 return gRDF.GetLiteral(!(this.getLiteralValue(handler.Value, "alwaysAsk") == "true")); |
|
212 } |
|
213 } |
|
214 else if (aProperty.EqualsNode(this._fileTypeArc)) { |
|
215 if (typeInfo.description == "") { |
|
216 try { |
|
217 var literal = bundle.getFormattedString("fileEnding", [typeInfo.primaryExtension.toUpperCase()]); |
|
218 return gRDF.GetLiteral(literal); |
|
219 } |
|
220 catch (e) { |
|
221 // Wow, this sucks, just show the MIME type as a last ditch effort to display |
|
222 // the type of file that this is. |
|
223 return gRDF.GetLiteral(typeInfo.MIMEType); |
|
224 } |
|
225 } |
|
226 return gRDF.GetLiteral(typeInfo.description); |
|
227 } |
|
228 else if (aProperty.EqualsNode(this._fileHandlerArc)) { |
|
229 var handler = this.GetTarget(aSource, this._handlerPropArc, true); |
|
230 if (handler) { |
|
231 handler = handler.QueryInterface(Components.interfaces.nsIRDFResource); |
|
232 if (this.getLiteralValue(handler.Value, "saveToDisk") == "true") { |
|
233 var saveToDisk = bundle.getString("saveToDisk"); |
|
234 return gRDF.GetLiteral(saveToDisk); |
|
235 } |
|
236 else if (this.getLiteralValue(handler.Value, "useSystemDefault") == "false") { |
|
237 var extApp = this.GetTarget(handler, this._externalAppArc, true); |
|
238 if (extApp) { |
|
239 extApp = extApp.QueryInterface(Components.interfaces.nsIRDFResource); |
|
240 var openWith = bundle.getFormattedString("openWith", [this.getLiteralValue(extApp.Value, "prettyName")]); |
|
241 return gRDF.GetLiteral(openWith); |
|
242 } |
|
243 } |
|
244 } |
|
245 |
|
246 var openWith2 = bundle.getFormattedString("openWith", [typeInfo.defaultDescription]); |
|
247 return gRDF.GetLiteral(openWith2); |
|
248 } |
|
249 else if (aProperty.EqualsNode(this._fileIconArc)) { |
|
250 try { |
|
251 return gRDF.GetLiteral("moz-icon://goat." + typeInfo.primaryExtension + "?size=16"); |
|
252 } |
|
253 catch (e) { |
|
254 return gRDF.GetLiteral("moz-icon://goat?size=16&contentType=" + typeInfo.MIMEType); |
|
255 } |
|
256 } |
|
257 else if (aProperty.EqualsNode(this._fileExtensionArc)) { |
|
258 try { |
|
259 return gRDF.GetLiteral(typeInfo.primaryExtension.toUpperCase()); |
|
260 } |
|
261 catch (e) { } |
|
262 return gRDF.GetLiteral(""); |
|
263 } |
|
264 else if (aProperty.EqualsNode(this._fileExtensionsArc)) { |
|
265 var extns = typeInfo.getFileExtensions(); |
|
266 |
|
267 // Prevent duplicates. |
|
268 var hash = { }; |
|
269 while (extns.hasMore()) |
|
270 hash[extns.getNext().toUpperCase()] = 0; |
|
271 |
|
272 var str = ""; |
|
273 for (var extn in hash) |
|
274 str += extn + ","; |
|
275 str = str.substring(0, str.length - 1); |
|
276 |
|
277 return gRDF.GetLiteral(str); |
|
278 } |
|
279 } |
|
280 } |
|
281 |
|
282 return this._inner.GetTarget(aSource, aProperty, aTruthValue); |
|
283 }, |
|
284 |
|
285 GetTargets: function (aSource, aProperty, aTruthValue) { |
|
286 if (this._isRootTypeResource(aSource)) { |
|
287 return new ArrayEnumerator([this.GetTarget(aSource, aProperty, aTruthValue)]); |
|
288 } |
|
289 |
|
290 return this._inner.GetTargets(aSource, aProperty, aTruthValue); |
|
291 }, |
|
292 Assert: function (aSource, aProperty, aTarget, aTruthValue) { |
|
293 return this._inner.Assert(aSource, aProperty, aTarget, aTruthValue); |
|
294 }, |
|
295 Unassert: function (aSource, aProperty, aTarget) { |
|
296 return this._inner.Unassert(aSource, aProperty, aTarget); |
|
297 }, |
|
298 Change: function (aSource, aProperty, aOldTarget, aNewTarget) { |
|
299 if (aOldTarget) |
|
300 var ot = aOldTarget.QueryInterface(Components.interfaces.nsIRDFLiteral); |
|
301 if (aNewTarget) |
|
302 var nt = aNewTarget.QueryInterface(Components.interfaces.nsIRDFLiteral); |
|
303 |
|
304 return this._inner.Change(aSource, aProperty, aOldTarget, aNewTarget); |
|
305 }, |
|
306 Move: function (aOldSource, aNewSource, aProperty, aTarget) { |
|
307 return this._inner.Assert(aOldSource, aNewSource, aProperty, aTarget); |
|
308 }, |
|
309 HasAssertion: function (aSource, aProperty, aTarget, aTruthValue) { |
|
310 if (this._isRootTypeResource(aSource)) { |
|
311 // Don't show entries in the list for types that we DO NOT handle |
|
312 // automatically. i.e. this list is a means of editing and removing |
|
313 // automatic overrides only. |
|
314 if (aProperty.EqualsNode(this._handleAutoArc)) { |
|
315 var handler = this.GetTarget(aSource, this._handlerPropArc, true); |
|
316 if (handler) { |
|
317 handler = handler.QueryInterface(Components.interfaces.nsIRDFResource); |
|
318 return !(this.getLiteralValue(handler.Value, "alwaysAsk") == "true"); |
|
319 } |
|
320 } |
|
321 } |
|
322 return this._inner.HasAssertion(aSource, aProperty, aTarget, aTruthValue); |
|
323 }, |
|
324 ArcLabelsIn: function (aNode) { |
|
325 return this._inner.ArcLabelsIn(aNode); |
|
326 }, |
|
327 ArcLabelsOut: function (aNode) { |
|
328 return this._inner.ArcLabelsOut(aNode); |
|
329 }, |
|
330 GetAllResources: function () { |
|
331 return this._inner.GetAllResources(); |
|
332 }, |
|
333 hasArcIn: function (aNode, aArc) { |
|
334 return this._inner.hasArcIn(aNode, aArc); |
|
335 }, |
|
336 hasArcOut: function (aNode, aArc) { |
|
337 return this._inner.hasArcOut(aNode, aArc); |
|
338 }, |
|
339 |
|
340 _observers: [], |
|
341 AddObserver: function (aObserver) { |
|
342 this._observers.push(aObserver); |
|
343 }, |
|
344 |
|
345 RemoveObserver: function (aObserver) { |
|
346 for (var i = 0; i < this._observers.length; ++i) { |
|
347 if (this._observers[i] == aObserver) { |
|
348 this._observers.splice(i, 1); |
|
349 break; |
|
350 } |
|
351 } |
|
352 }, |
|
353 |
|
354 onAssert: function (aDataSource, aSource, aProperty, aTarget) { |
|
355 for (var i = 0; i < this._observers.length; ++i) { |
|
356 this._observers[i].onAssert(aDataSource, aSource, aProperty, aTarget); |
|
357 } |
|
358 }, |
|
359 |
|
360 onUnassert: function (aDataSource, aSource, aProperty, aTarget) { |
|
361 for (var i = 0; i < this._observers.length; ++i) { |
|
362 this._observers[i].onUnassert(aDataSource, aSource, aProperty, aTarget); |
|
363 } |
|
364 }, |
|
365 |
|
366 onChange: function (aDataSource, aSource, aProperty, aOldTarget, aNewTarget) { |
|
367 for (var i = 0; i < this._observers.length; ++i) { |
|
368 this._observers[i].onChange(aDataSource, aSource, aProperty, aOldTarget, aNewTarget); |
|
369 } |
|
370 }, |
|
371 |
|
372 onMove: function (aDataSource, aOldSource, aNewSource, aProperty, aTarget) { |
|
373 for (var i = 0; i < this._observers.length; ++i) { |
|
374 this._observers[i].onMove(aDataSource, aOldSource, aNewSource, aProperty, aTarget); |
|
375 } |
|
376 }, |
|
377 |
|
378 onBeginUpdateBatch: function (aDataSource) { |
|
379 for (var i = 0; i < this._observers.length; ++i) { |
|
380 this._observers[i].onBeginUpdateBatch(aDataSource); |
|
381 } |
|
382 }, |
|
383 |
|
384 onEndUpdateBatch: function (aDataSource) { |
|
385 for (var i = 0; i < this._observers.length; ++i) { |
|
386 this._observers[i].onEndUpdateBatch(aDataSource); |
|
387 } |
|
388 }, |
|
389 |
|
390 beginUpdateBatch: function (aDataSource) { |
|
391 for (var i = 0; i < this._observers.length; ++i) { |
|
392 this._observers[i].beginUpdateBatch(aDataSource); |
|
393 } |
|
394 }, |
|
395 |
|
396 endUpdateBatch: function (aDataSource) { |
|
397 for (var i = 0; i < this._observers.length; ++i) { |
|
398 this._observers[i].endUpdateBatch(aDataSource); |
|
399 } |
|
400 }, |
|
401 |
|
402 flush: function () { |
|
403 var rds = this._inner.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource); |
|
404 if (rds) |
|
405 rds.Flush(); |
|
406 }, |
|
407 |
|
408 destroy: function () { |
|
409 this._inner.RemoveObserver(this); |
|
410 } |
|
411 }; |
|
412 |
|
413 /** |
|
414 * Handler Override class |
|
415 **/ |
|
416 function HandlerOverride(aURI, aDatasource) |
|
417 { |
|
418 this.URI = aURI; |
|
419 this._DS = aDatasource; |
|
420 } |
|
421 |
|
422 HandlerOverride.prototype = { |
|
423 // general information |
|
424 get mimeType() |
|
425 { |
|
426 return this.getLiteralForContentType(this.URI, "value"); |
|
427 }, |
|
428 |
|
429 set mimeType(aMIMETypeString) |
|
430 { |
|
431 this.changeMIMEStuff(MIME_URI(aMIMETypeString), "value", aMIMETypeString.toLowerCase()); |
|
432 return aMIMETypeString; |
|
433 }, |
|
434 |
|
435 get description() |
|
436 { |
|
437 return this.getLiteralForContentType(this.URI, "description"); |
|
438 }, |
|
439 |
|
440 set description(aDescriptionString) |
|
441 { |
|
442 this.changeMIMEStuff(MIME_URI(this.mimeType), "description", aDescriptionString); |
|
443 return aDescriptionString; |
|
444 }, |
|
445 |
|
446 get isEditable() |
|
447 { |
|
448 return this.getLiteralForContentType(this.URI, "editable"); |
|
449 }, |
|
450 |
|
451 set isEditable(aIsEditableString) |
|
452 { |
|
453 this.changeMIMEStuff(MIME_URI(this.mimeType), "editable", aIsEditableString); |
|
454 return aIsEditableString; |
|
455 }, |
|
456 |
|
457 get extensions() |
|
458 { |
|
459 var extensionResource = gRDF.GetUnicodeResource(NC_URI("fileExtensions")); |
|
460 var contentTypeResource = gRDF.GetUnicodeResource(MIME_URI(this.mimeType)); |
|
461 var extensionTargets = this._DS.GetTargets(contentTypeResource, extensionResource, true); |
|
462 var extString = ""; |
|
463 if (extensionTargets) { |
|
464 while (extensionTargets.hasMoreElements()) { |
|
465 var currentExtension = extensionTargets.getNext(); |
|
466 if (currentExtension) { |
|
467 currentExtension = currentExtension.QueryInterface(Components.interfaces.nsIRDFLiteral); |
|
468 if (extString != "") { |
|
469 extString += " "; |
|
470 } |
|
471 extString += currentExtension.Value.toLowerCase(); |
|
472 } |
|
473 } |
|
474 } |
|
475 return extString; |
|
476 }, |
|
477 |
|
478 addExtension: function (aExtensionString) |
|
479 { |
|
480 this.assertMIMEStuff(MIME_URI(this.mimeType), "fileExtensions", aExtensionString.toLowerCase()); |
|
481 }, |
|
482 |
|
483 removeExtension: function (aExtensionString) |
|
484 { |
|
485 this.unassertMIMEStuff(MIME_URI(this.mimeType), "fileExtensions", aExtensionString.toLowerCase()); |
|
486 }, |
|
487 |
|
488 clearExtensions: function () |
|
489 { |
|
490 var extArray = this.extensions.split(" "); |
|
491 for (i = extArray.length - 1; i >= 0; --i) { |
|
492 this.removeExtension(extArray[i]); |
|
493 } |
|
494 }, |
|
495 |
|
496 // content handling |
|
497 get saveToDisk() |
|
498 { |
|
499 return this.getHandlerInfoForType(this.URI, "saveToDisk"); |
|
500 }, |
|
501 |
|
502 set saveToDisk(aSavedToDisk) |
|
503 { |
|
504 this.changeMIMEStuff(HANDLER_URI(this.mimeType), "saveToDisk", aSavedToDisk); |
|
505 this.setHandlerProcedure("handleInternal", "false"); |
|
506 this.setHandlerProcedure("useSystemDefault", "false"); |
|
507 return aSavedToDisk; |
|
508 }, |
|
509 |
|
510 get useSystemDefault() |
|
511 { |
|
512 return this.getHandlerInfoForType(this.URI, "useSystemDefault"); |
|
513 }, |
|
514 |
|
515 set useSystemDefault(aUseSystemDefault) |
|
516 { |
|
517 this.changeMIMEStuff(HANDLER_URI(this.mimeType), "useSystemDefault", aUseSystemDefault); |
|
518 this.setHandlerProcedure("handleInternal", "false"); |
|
519 this.setHandlerProcedure("saveToDisk", "false"); |
|
520 return aUseSystemDefault; |
|
521 }, |
|
522 |
|
523 get handleInternal() |
|
524 { |
|
525 return this.getHandlerInfoForType(this.URI, "handleInternal"); |
|
526 }, |
|
527 |
|
528 set handleInternal(aHandledInternally) |
|
529 { |
|
530 this.changeMIMEStuff(HANDLER_URI(this.mimeType), "handleInternal", aHandledInternally); |
|
531 this.setHandlerProcedure("saveToDisk", "false"); |
|
532 this.setHandlerProcedure("useSystemDefault", "false"); |
|
533 return aHandledInternally; |
|
534 }, |
|
535 |
|
536 setHandlerProcedure: function (aHandlerProcedure, aValue) |
|
537 { |
|
538 var handlerSource = gRDF.GetUnicodeResource(HANDLER_URI(this.mimeType)); |
|
539 var handlerProperty = gRDF.GetUnicodeResource(NC_URI(aHandlerProcedure)); |
|
540 var oppositeValue = aValue == "false" ? "true" : "false"; |
|
541 var trueLiteral = gRDF.GetLiteral(oppositeValue); |
|
542 var hasCounterpart = this._DS.HasAssertion(handlerSource, handlerProperty, trueLiteral, true); |
|
543 if (hasCounterpart) { |
|
544 var falseLiteral = gRDF.GetLiteral(aValue); |
|
545 this._DS.Change(handlerSource, handlerProperty, trueLiteral, falseLiteral); |
|
546 } |
|
547 }, |
|
548 |
|
549 get alwaysAsk() |
|
550 { |
|
551 return this.getHandlerInfoForType(this.URI, "alwaysAsk"); |
|
552 }, |
|
553 |
|
554 set alwaysAsk(aAlwaysAsk) |
|
555 { |
|
556 this.changeMIMEStuff(HANDLER_URI(this.mimeType), "alwaysAsk", aAlwaysAsk); |
|
557 return aAlwaysAsk; |
|
558 }, |
|
559 |
|
560 // helper application |
|
561 get appDisplayName() |
|
562 { |
|
563 return getHelperAppInfoForType(this.URI, "prettyName"); |
|
564 }, |
|
565 |
|
566 set appDisplayName(aDisplayName) |
|
567 { |
|
568 if (aDisplayName) |
|
569 this.changeMIMEStuff(APP_URI(this.mimeType), "prettyName", aDisplayName); |
|
570 else { |
|
571 var currentValue = this.getLiteralForContentType(APP_URI(this.mimeType), "prettyName"); |
|
572 this.unassertMIMEStuff(APP_URI(this.mimeType), "prettyName", currentValue); |
|
573 } |
|
574 |
|
575 return aDisplayName; |
|
576 }, |
|
577 |
|
578 get appPath() |
|
579 { |
|
580 return this.getHelperAppInfoForType(this.URI, "path"); |
|
581 }, |
|
582 |
|
583 set appPath(aAppPath) |
|
584 { |
|
585 if (aAppPath) |
|
586 this.changeMIMEStuff(APP_URI(this.mimeType), "path", aAppPath); |
|
587 else { |
|
588 var currentValue = this.getLiteralForContentType(APP_URI(this.mimeType), "path"); |
|
589 this.unassertMIMEStuff(APP_URI(this.mimeType), "path", currentValue); |
|
590 } |
|
591 |
|
592 return aAppPath; |
|
593 }, |
|
594 |
|
595 /** |
|
596 * After setting the various properties on this override, we need to |
|
597 * build the links between the mime type resource, the handler for that |
|
598 * resource, and the helper app (if any) associated with the resource. |
|
599 * We also need to add this mime type to the RDF seq (list) of types. |
|
600 **/ |
|
601 buildLinks: function() |
|
602 { |
|
603 // assert the handler resource |
|
604 var mimeSource = gRDF.GetUnicodeResource(MIME_URI(this.mimeType)); |
|
605 var handlerProperty = gRDF.GetUnicodeResource(NC_URI("handlerProp")); |
|
606 var handlerResource = gRDF.GetUnicodeResource(HANDLER_URI(this.mimeType)); |
|
607 this._DS.Assert(mimeSource, handlerProperty, handlerResource, true); |
|
608 // assert the helper app resource |
|
609 var helperAppProperty = gRDF.GetUnicodeResource(NC_URI("externalApplication")); |
|
610 var helperAppResource = gRDF.GetUnicodeResource(APP_URI(this.mimeType)); |
|
611 this._DS.Assert(handlerResource, helperAppProperty, helperAppResource, true); |
|
612 // add the mime type to the MIME types seq |
|
613 var container = this.ensureAndGetTypeList("mimetype"); |
|
614 var element = gRDF.GetUnicodeResource(MIME_URI(this.mimeType)); |
|
615 if (container.IndexOf(element) == -1) |
|
616 container.AppendElement(element); |
|
617 }, |
|
618 |
|
619 // Implementation helper methods |
|
620 |
|
621 getLiteralForContentType: function (aURI, aProperty) |
|
622 { |
|
623 var contentTypeResource = gRDF.GetUnicodeResource(aURI); |
|
624 var propertyResource = gRDF.GetUnicodeResource(NC_URI(aProperty)); |
|
625 return this.getLiteral(contentTypeResource, propertyResource); |
|
626 }, |
|
627 |
|
628 getLiteral: function (aSource, aProperty) |
|
629 { |
|
630 var node = this._DS.GetTarget(aSource, aProperty, true); |
|
631 if (node) { |
|
632 node = node.QueryInterface(Components.interfaces.nsIRDFLiteral); |
|
633 return node.Value; |
|
634 } |
|
635 return ""; |
|
636 }, |
|
637 |
|
638 getHandlerInfoForType: function (aURI, aPropertyString) |
|
639 { |
|
640 // get current selected type |
|
641 var handler = HANDLER_URI(this.getLiteralForContentType(aURI, "value")); |
|
642 var source = gRDF.GetUnicodeResource(handler); |
|
643 var property = gRDF.GetUnicodeResource(NC_URI(aPropertyString)); |
|
644 var target = this._DS.GetTarget(source, property, true); |
|
645 if (target) { |
|
646 target = target.QueryInterface(Components.interfaces.nsIRDFLiteral); |
|
647 return target.Value; |
|
648 } |
|
649 return ""; |
|
650 }, |
|
651 |
|
652 getHelperAppInfoForType: function (aURI, aPropertyString) |
|
653 { |
|
654 var appURI = APP_URI(this.getLiteralForContentType(aURI, "value")); |
|
655 var appRes = gRDF.GetUnicodeResource(appURI); |
|
656 var appProperty = gRDF.GetUnicodeResource(NC_URI(aPropertyString)); |
|
657 return getLiteral(appRes, appProperty); |
|
658 }, |
|
659 |
|
660 // write to the ds |
|
661 assertMIMEStuff: function (aMIMEString, aPropertyString, aValueString) |
|
662 { |
|
663 var mimeSource = gRDF.GetUnicodeResource(aMIMEString); |
|
664 var valueProperty = gRDF.GetUnicodeResource(NC_URI(aPropertyString)); |
|
665 var mimeLiteral = gRDF.GetLiteral(aValueString); |
|
666 this._DS.Assert(mimeSource, valueProperty, mimeLiteral, true); |
|
667 }, |
|
668 |
|
669 changeMIMEStuff: function(aMIMEString, aPropertyString, aValueString) |
|
670 { |
|
671 var mimeSource = gRDF.GetUnicodeResource(aMIMEString); |
|
672 var valueProperty = gRDF.GetUnicodeResource(NC_URI(aPropertyString)); |
|
673 var mimeLiteral = gRDF.GetLiteral(aValueString); |
|
674 var currentValue = this._DS.GetTarget(mimeSource, valueProperty, true); |
|
675 if (currentValue) { |
|
676 this._DS.Change(mimeSource, valueProperty, currentValue, mimeLiteral); |
|
677 } else { |
|
678 this._DS.Assert(mimeSource, valueProperty, mimeLiteral, true); |
|
679 } |
|
680 }, |
|
681 |
|
682 unassertMIMEStuff: function(aMIMEString, aPropertyString, aValueString) |
|
683 { |
|
684 var mimeSource = gRDF.GetUnicodeResource(aMIMEString); |
|
685 var valueProperty = gRDF.GetUnicodeResource(NC_URI(aPropertyString)); |
|
686 var mimeLiteral = gRDF.GetLiteral(aValueString); |
|
687 this._DS.Unassert(mimeSource, valueProperty, mimeLiteral, true); |
|
688 }, |
|
689 |
|
690 /** |
|
691 * Get the list of types for the given class, creating the list if it doesn't |
|
692 * already exist. The class can be either CLASS_MIMEINFO or CLASS_PROTOCOLINFO |
|
693 * (i.e. the result of a call to _getClass). |
|
694 * |
|
695 * |urn:<class>s| |
|
696 * |urn:<class>s:root| |
|
697 * |
|
698 * @param aClass {string} the class for which to retrieve a list of types |
|
699 * |
|
700 * @returns {nsIRDFContainer} the list of types |
|
701 */ |
|
702 ensureAndGetTypeList: function (aClass) { |
|
703 var source = gRDF.GetResource("urn:" + aClass + "s"); |
|
704 var property = |
|
705 gRDF.GetResource(aClass == CLASS_MIMEINFO ? NC_MIME_TYPES |
|
706 : NC_PROTOCOL_SCHEMES); |
|
707 var target = gRDF.GetResource("urn:" + aClass + "s:root"); |
|
708 |
|
709 // Make sure we have an arc from the source to the target. |
|
710 if (!this._DS.HasAssertion(source, property, target, true)) |
|
711 this._DS.Assert(source, property, target, true); |
|
712 |
|
713 // Make sure the target is a container. |
|
714 var containerUtils = Cc["@mozilla.org/rdf/container-utils;1"] |
|
715 .getService(Ci.nsIRDFContainerUtils); |
|
716 if (!containerUtils.IsContainer(this._DS, target)) |
|
717 containerUtils.MakeSeq(this._DS, target); |
|
718 |
|
719 // Get the type list as an RDF container. |
|
720 var typeList = |
|
721 Cc["@mozilla.org/rdf/container;1"].createInstance(Ci.nsIRDFContainer); |
|
722 typeList.Init(this._DS, target); |
|
723 |
|
724 return typeList; |
|
725 } |
|
726 }; |
|
727 |