~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/toolkit/components/extensions/src/nsExtensionManagerDataSource.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Mozilla Public License Version
 
6
 * 1.1 (the "License"); you may not use this file except in compliance with
 
7
 * the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/MPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is the Extension Manager.
 
16
 *
 
17
 * The Initial Developer of the Original Code is Ben Goodger.
 
18
 * Portions created by the Initial Developer are Copyright (C) 2004
 
19
 * the Initial Developer. All Rights Reserved.
 
20
 *
 
21
 * Contributor(s):
 
22
 *  Ben Goodger <ben@bengoodger.com>
 
23
 *
 
24
 * Alternatively, the contents of this file may be used under the terms of
 
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
28
 * of those above. If you wish to allow use of your version of this file only
 
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
30
 * use your version of this file under the terms of the MPL, indicate your
 
31
 * decision by deleting the provisions above and replace them with the notice
 
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
33
 * the provisions above, a recipient may use your version of this file under
 
34
 * the terms of any one of the MPL, the GPL or the LGPL.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
 
 
38
#include "nsAppDirectoryServiceDefs.h"
 
39
#include "nsCRT.h"
 
40
#include "nsDirectoryServiceDefs.h"
 
41
#include "nsExtensionManagerDataSource.h"
 
42
#include "nsIFileProtocolHandler.h"
 
43
#include "nsIIOService.h"
 
44
#include "nsILocalFile.h"
 
45
#include "nsIProtocolHandler.h"
 
46
#include "nsIRDFContainer.h"
 
47
#include "nsIRDFRemoteDataSource.h"
 
48
#include "nsIRDFService.h"
 
49
#include "nsLiteralString.h"
 
50
#include "rdf.h"
 
51
 
 
52
NS_IMPL_ISUPPORTS2(nsExtensionManagerDataSource, nsIRDFDataSource, nsIRDFRemoteDataSource)
 
53
 
 
54
static nsIRDFService* gRDFService = nsnull;
 
55
 
 
56
static nsIRDFResource* gIDArc = nsnull;
 
57
static nsIRDFResource* gNameArc = nsnull;
 
58
static nsIRDFResource* gDescriptionArc = nsnull;
 
59
static nsIRDFResource* gCreatorArc = nsnull;
 
60
static nsIRDFResource* gContributorArc = nsnull;
 
61
static nsIRDFResource* gDisabledArc = nsnull;
 
62
static nsIRDFResource* gHomepageURLArc = nsnull;
 
63
static nsIRDFResource* gUpdateURLArc = nsnull;
 
64
static nsIRDFResource* gVersionArc = nsnull;
 
65
static nsIRDFResource* gTargetApplicationArc = nsnull;
 
66
static nsIRDFResource* gMinAppVersionArc = nsnull;
 
67
static nsIRDFResource* gMaxAppVersionArc = nsnull;
 
68
static nsIRDFResource* gRequiresArc = nsnull;
 
69
static nsIRDFResource* gOptionsURLArc = nsnull;
 
70
static nsIRDFResource* gAboutURLArc = nsnull;
 
71
static nsIRDFResource* gIconURLArc = nsnull;
 
72
static nsIRDFResource* gPackageArc = nsnull;
 
73
static nsIRDFResource* gSkinArc = nsnull;
 
74
static nsIRDFResource* gLanguageArc = nsnull;
 
75
static nsIRDFResource* gToBeEnabledArc = nsnull;
 
76
static nsIRDFResource* gToBeDisabledArc = nsnull;
 
77
static nsIRDFResource* gToBeUninstalledArc = nsnull;
 
78
static nsIRDFResource* gInstallLocationArc = nsnull;
 
79
static nsIRDFLiteral* gTrueValue = nsnull;
 
80
static nsIRDFLiteral* gFalseValue = nsnull;
 
81
static nsIRDFLiteral* gInstallProfile = nsnull;
 
82
static nsIRDFLiteral* gInstallGlobal = nsnull;
 
83
static nsIRDFResource* gExtensionsRoot = nsnull;
 
84
static nsIRDFResource* gThemesRoot = nsnull;
 
85
 
 
86
#define EM_RDF_URI "http://www.mozilla.org/2004/em-rdf#"
 
87
 
 
88
#define PREF_EM_DEFAULTUPDATEURL "update.url.extensions"
 
89
#define PREF_EM_APP_ID "app.id"
 
90
 
 
91
///////////////////////////////////////////////////////////////////////////////
 
92
// nsIRDFDataSource
 
93
 
 
94
nsExtensionManagerDataSource::nsExtensionManagerDataSource()
 
95
{
 
96
  if (!gRDFService)
 
97
    CallGetService("@mozilla.org/rdf/rdf-service;1", &gRDFService);
 
98
 
 
99
  gRDFService->GetResource(NS_LITERAL_CSTRING(EM_RDF_URI "name"), &gNameArc);
 
100
  gRDFService->GetResource(NS_LITERAL_CSTRING(EM_RDF_URI "version"), &gVersionArc);
 
101
  gRDFService->GetResource(NS_LITERAL_CSTRING(EM_RDF_URI "iconURL"), &gIconURLArc);
 
102
  gRDFService->GetResource(NS_LITERAL_CSTRING(EM_RDF_URI "toBeEnabled"), &gToBeEnabledArc);
 
103
  gRDFService->GetResource(NS_LITERAL_CSTRING(EM_RDF_URI "toBeDisabled"), &gToBeDisabledArc);
 
104
  gRDFService->GetResource(NS_LITERAL_CSTRING(EM_RDF_URI "toBeUninstalled"), &gToBeUninstalledArc);
 
105
  gRDFService->GetResource(NS_LITERAL_CSTRING(EM_RDF_URI "disabled"), &gDisabledArc);
 
106
  gRDFService->GetResource(NS_LITERAL_CSTRING(EM_RDF_URI "installLocation"), &gInstallLocationArc);
 
107
 
 
108
  gRDFService->GetLiteral(NS_LITERAL_STRING("profile").get(), &gInstallProfile);
 
109
  gRDFService->GetLiteral(NS_LITERAL_STRING("global").get(), &gInstallGlobal);
 
110
  gRDFService->GetLiteral(NS_LITERAL_STRING("true").get(), &gTrueValue);
 
111
  gRDFService->GetLiteral(NS_LITERAL_STRING("false").get(), &gFalseValue);
 
112
 
 
113
  gRDFService->GetResource(NS_LITERAL_CSTRING("urn:mozilla:extension:root"), &gExtensionsRoot);
 
114
  gRDFService->GetResource(NS_LITERAL_CSTRING("urn:mozilla:themes:root"), &gThemesRoot);
 
115
}
 
116
 
 
117
nsExtensionManagerDataSource::~nsExtensionManagerDataSource()
 
118
{
 
119
  NS_IF_RELEASE(gRDFService);
 
120
  NS_IF_RELEASE(gIDArc);
 
121
  NS_IF_RELEASE(gNameArc);
 
122
  NS_IF_RELEASE(gDescriptionArc);
 
123
  NS_IF_RELEASE(gCreatorArc);
 
124
  NS_IF_RELEASE(gContributorArc);
 
125
  NS_IF_RELEASE(gDisabledArc);
 
126
  NS_IF_RELEASE(gHomepageURLArc);
 
127
  NS_IF_RELEASE(gUpdateURLArc);
 
128
  NS_IF_RELEASE(gVersionArc);
 
129
  NS_IF_RELEASE(gTargetApplicationArc);
 
130
  NS_IF_RELEASE(gMinAppVersionArc);
 
131
  NS_IF_RELEASE(gMaxAppVersionArc);
 
132
  NS_IF_RELEASE(gRequiresArc);
 
133
  NS_IF_RELEASE(gOptionsURLArc);
 
134
  NS_IF_RELEASE(gAboutURLArc);
 
135
  NS_IF_RELEASE(gIconURLArc);
 
136
  NS_IF_RELEASE(gPackageArc);
 
137
  NS_IF_RELEASE(gSkinArc);
 
138
  NS_IF_RELEASE(gLanguageArc);
 
139
  NS_IF_RELEASE(gToBeEnabledArc);
 
140
  NS_IF_RELEASE(gToBeDisabledArc);
 
141
  NS_IF_RELEASE(gToBeUninstalledArc);
 
142
  NS_IF_RELEASE(gInstallLocationArc);
 
143
  NS_IF_RELEASE(gTrueValue);
 
144
  NS_IF_RELEASE(gFalseValue);
 
145
  NS_IF_RELEASE(gInstallProfile);
 
146
  NS_IF_RELEASE(gInstallGlobal);
 
147
  NS_IF_RELEASE(gExtensionsRoot);
 
148
  NS_IF_RELEASE(gThemesRoot);
 
149
}
 
150
 
 
151
///////////////////////////////////////////////////////////////////////////////
 
152
//
 
153
nsresult
 
154
nsExtensionManagerDataSource::LoadExtensions(PRBool aProfile)
 
155
{
 
156
  nsCOMPtr<nsIFile> extensionsFile;
 
157
  NS_GetSpecialDirectory(aProfile ? NS_APP_USER_PROFILE_50_DIR : 
 
158
                                    NS_XPCOM_CURRENT_PROCESS_DIR, 
 
159
                         getter_AddRefs(extensionsFile));
 
160
  extensionsFile->AppendNative(NS_LITERAL_CSTRING("Extensions"));
 
161
  extensionsFile->AppendNative(NS_LITERAL_CSTRING("extensions.rdf"));
 
162
 
 
163
  PRBool exists;
 
164
  extensionsFile->Exists(&exists);
 
165
  if (!exists)
 
166
    return NS_OK;
 
167
 
 
168
  nsCOMPtr<nsIIOService> ioService(do_GetService("@mozilla.org/network/io-service;1"));
 
169
  nsCOMPtr<nsIProtocolHandler> ph;
 
170
  ioService->GetProtocolHandler("file", getter_AddRefs(ph));
 
171
  nsCOMPtr<nsIFileProtocolHandler> fph(do_QueryInterface(ph));
 
172
 
 
173
  nsCAutoString dsURL;
 
174
  fph->GetURLSpecFromFile(extensionsFile, dsURL);
 
175
 
 
176
  nsCOMPtr<nsIRDFDataSource> ds;
 
177
  gRDFService->GetDataSourceBlocking(dsURL.get(), getter_AddRefs(ds));
 
178
 
 
179
  if (aProfile) {
 
180
    mProfileExtensions = ds;
 
181
 
 
182
    if (!mComposite)
 
183
      mComposite = do_CreateInstance("@mozilla.org/rdf/datasource;1?name=composite-datasource");
 
184
  
 
185
    if (mAppExtensions)
 
186
      mComposite->RemoveDataSource(mAppExtensions);
 
187
    mComposite->AddDataSource(mProfileExtensions);
 
188
    if (mAppExtensions)
 
189
      mComposite->AddDataSource(mAppExtensions);
 
190
  }
 
191
  else {
 
192
    mAppExtensions = ds;
 
193
 
 
194
    if (!mComposite)
 
195
      mComposite = do_CreateInstance("@mozilla.org/rdf/datasource;1?name=composite-datasource");
 
196
    mComposite->AddDataSource(mAppExtensions);
 
197
  }
 
198
 
 
199
  return NS_OK;
 
200
}
 
201
 
 
202
#define SET_PROPERTY(datasource, source, property, value) \
 
203
    rv |= datasource->GetTarget(source, property, PR_FALSE, \
 
204
                                getter_AddRefs(oldNode)); \
 
205
    if (oldNode) \
 
206
      rv |= datasource->Change(source, property, oldNode, value); \
 
207
    else \
 
208
      rv |= datasource->Assert(source, property, value, PR_FALSE);
 
209
 
 
210
nsresult
 
211
nsExtensionManagerDataSource::InstallExtension(nsIRDFDataSource* aSourceDataSource,
 
212
                                               PRBool aProfile)
 
213
{
 
214
  nsresult rv = NS_OK;
 
215
 
 
216
  nsCOMPtr<nsIRDFDataSource> targetDS = aProfile ? mProfileExtensions : mAppExtensions;
 
217
 
 
218
  // Install an extension from a source manifest datasource into the specified
 
219
  // datasource (profile or target). 
 
220
 
 
221
  // Step 1 is to copy all the properties from the manifest to the application
 
222
  // datasource. We check for existing assertions because an extension with
 
223
  // the same id (basically, a previous version) may already exist and we need
 
224
  // to change property values. 
 
225
  nsCOMPtr<nsIRDFResource> manifest;
 
226
  gRDFService->GetResource(NS_LITERAL_CSTRING("extension:manifest"), 
 
227
                           getter_AddRefs(manifest));
 
228
 
 
229
  nsCOMPtr<nsIRDFNode> node;
 
230
  aSourceDataSource->GetTarget(manifest, gIDArc, PR_FALSE, getter_AddRefs(node));
 
231
 
 
232
  nsCOMPtr<nsIRDFLiteral> id(do_QueryInterface(node));
 
233
  nsXPIDLString val;
 
234
  id->GetValue(getter_Copies(val));
 
235
 
 
236
  nsCOMPtr<nsIRDFResource> extension;
 
237
  gRDFService->GetUnicodeResource(val, getter_AddRefs(extension));
 
238
 
 
239
  nsCOMPtr<nsIRDFNode> oldNode, newNode;
 
240
  PRInt32 i;
 
241
 
 
242
  nsIRDFResource* resources[] = { gNameArc, gDescriptionArc, gHomepageURLArc, 
 
243
                                  gUpdateURLArc, gVersionArc, gTargetApplicationArc,
 
244
                                  gMinAppVersionArc, gMaxAppVersionArc, 
 
245
                                  gOptionsURLArc, gAboutURLArc, gIconURLArc };
 
246
  for (i = 0; i < 11; ++i) {
 
247
    rv |= aSourceDataSource->GetTarget(manifest, resources[i], PR_FALSE,
 
248
                                       getter_AddRefs(newNode));
 
249
    SET_PROPERTY(targetDS, extension, resources[i], newNode)
 
250
  }
 
251
 
 
252
  nsCOMPtr<nsISimpleEnumerator> e;
 
253
  nsIRDFResource* resources2[] = { gCreatorArc, gContributorArc, gRequiresArc, 
 
254
                                  gPackageArc, gSkinArc, gLanguageArc };
 
255
  for (i = 0; i < 6; ++i) {
 
256
    // Remove all old values for the extension
 
257
    rv |= targetDS->GetTargets(extension, resources2[i], PR_FALSE,
 
258
                               getter_AddRefs(e));
 
259
    do {
 
260
      PRBool hasMore;
 
261
      e->HasMoreElements(&hasMore);
 
262
      if (!hasMore)
 
263
        break;
 
264
      nsCOMPtr<nsIRDFNode> node;
 
265
      e->GetNext(getter_AddRefs(node));
 
266
      rv |= targetDS->Unassert(extension, resources2[i], node);
 
267
    }
 
268
    while (1);
 
269
 
 
270
    // Now add the new values
 
271
    rv |= aSourceDataSource->GetTargets(manifest, resources2[i], PR_FALSE,
 
272
                                  getter_AddRefs(e));
 
273
    do {
 
274
      PRBool hasMore;
 
275
      e->HasMoreElements(&hasMore);
 
276
      if (!hasMore)
 
277
        break;
 
278
      nsCOMPtr<nsIRDFNode> node;
 
279
      e->GetNext(getter_AddRefs(node));
 
280
      rv |= targetDS->Assert(extension, resources2[i], node, PR_FALSE);
 
281
    }
 
282
    while (1); 
 
283
  }
 
284
 
 
285
  // Now that we've migrated data from the extensions manifest we need
 
286
  // to set a flag to trigger chrome registration on the next restart.
 
287
  SET_PROPERTY(targetDS, extension, gToBeEnabledArc, gTrueValue)
 
288
 
 
289
  // Write out the extensions datasource
 
290
  rv |= Flush(aProfile);
 
291
 
 
292
  return rv;
 
293
}
 
294
 
 
295
nsresult
 
296
nsExtensionManagerDataSource::SetExtensionProperty(const char* aExtensionID, 
 
297
                                                   nsIRDFResource* aPropertyArc, 
 
298
                                                   nsIRDFNode* aPropertyValue)
 
299
{
 
300
  nsresult rv = NS_OK;
 
301
 
 
302
  nsCString resourceURI = NS_LITERAL_CSTRING("urn:mozilla:extension:");
 
303
  resourceURI += aExtensionID;
 
304
 
 
305
  nsCOMPtr<nsIRDFResource> extension;
 
306
  gRDFService->GetResource(resourceURI, getter_AddRefs(extension));
 
307
 
 
308
  nsCOMPtr<nsIRDFNode> installLocation;
 
309
  rv |= GetTarget(extension, gInstallLocationArc, PR_TRUE, 
 
310
                  getter_AddRefs(installLocation));
 
311
 
 
312
  PRBool isProfile;
 
313
  installLocation->EqualsNode(gInstallProfile, &isProfile);
 
314
  nsCOMPtr<nsIRDFDataSource> ds = isProfile ? mProfileExtensions : mAppExtensions;
 
315
 
 
316
  nsCOMPtr<nsIRDFNode> oldNode;
 
317
  ds->GetTarget(extension, aPropertyArc, PR_FALSE, getter_AddRefs(oldNode));
 
318
  
 
319
  SET_PROPERTY(ds, extension, aPropertyArc, aPropertyValue)
 
320
  if (NS_FAILED(rv) && rv != NS_RDF_NO_VALUE)
 
321
    return rv;
 
322
 
 
323
  // Write out the extensions datasource
 
324
  return Flush(isProfile);
 
325
}
 
326
 
 
327
nsresult
 
328
nsExtensionManagerDataSource::EnableExtension(const char* aExtensionID)
 
329
{
 
330
  return SetExtensionProperty(aExtensionID, gToBeEnabledArc, gTrueValue) |
 
331
         SetExtensionProperty(aExtensionID, gDisabledArc, gFalseValue);
 
332
}
 
333
 
 
334
nsresult
 
335
nsExtensionManagerDataSource::DisableExtension(const char* aExtensionID)
 
336
{
 
337
  return SetExtensionProperty(aExtensionID, gToBeDisabledArc, gTrueValue) | 
 
338
         SetExtensionProperty(aExtensionID, gDisabledArc, gTrueValue);
 
339
}
 
340
 
 
341
nsresult
 
342
nsExtensionManagerDataSource::UninstallExtension(const char* aExtensionID)
 
343
{
 
344
  nsCOMPtr<nsIRDFContainer> ctr(do_CreateInstance("@mozilla.org/rdf/container;1"));
 
345
  ctr->Init(this, gExtensionsRoot);
 
346
 
 
347
  nsCString resourceURI = NS_LITERAL_CSTRING("urn:mozilla:extension:");
 
348
  resourceURI += aExtensionID;
 
349
 
 
350
  nsCOMPtr<nsIRDFResource> extension;
 
351
  gRDFService->GetResource(resourceURI, getter_AddRefs(extension));
 
352
 
 
353
  ctr->RemoveElement(extension, PR_TRUE);
 
354
 
 
355
  return SetExtensionProperty(aExtensionID, gToBeUninstalledArc, gTrueValue);
 
356
}
 
357
 
 
358
// This returns an array of URIs in the form:
 
359
// http://www.foo.com/software/ext1/update.cgi
 
360
// http://www.bar.com/update.php?ext=%7B0e4007ea-0b6b-4487-8e1b-479f65599e74%7D
 
361
// http://update.mozilla.org/genericUpdate.php?ext=%7B0e4007ea-0b6b-4487-8e1b-479f65599e74%7D%2C%7B0e4007ea-0b6b-4487-8e1b-479f65599e74%7D&app=%7Bec8030f7-c20a-464f-9b0e-13a3a9e97384%7D
 
362
// (specific URLs first, followed by a generic 
 
363
nsresult
 
364
nsExtensionManagerDataSource::GetConsolidatedUpdateURLs(nsISupportsArray* aURIs)
 
365
{
 
366
  nsCOMPtr<nsIRDFContainer> ctr(do_CreateInstance("@mozilla.org/rdf/container;1"));
 
367
  ctr->Init(this, gExtensionsRoot);
 
368
 
 
369
  nsCOMPtr<nsISimpleEnumerator> e;
 
370
  ctr->GetElements(getter_AddRefs(e));
 
371
 
 
372
  do {
 
373
    e->HasMoreElements(&hasMore);
 
374
    if (!hasMore)
 
375
      break;
 
376
 
 
377
    nsCOMPtr<nsIRDFResource> res;
 
378
    e->GetNext(getter_AddRefs(res));
 
379
 
 
380
    nsCAutoString url;
 
381
    GetUpdateURLForExtensionInternal(res, url);
 
382
    
 
383
    // If there's no specific Update URL specified for this extension, we want to
 
384
    // add this extension to the list that we'll pass to the generic update server.
 
385
    if (url.IsEmpty())  {
 
386
      
 
387
    }
 
388
 
 
389
 
 
390
  }
 
391
  while (PR_TRUE);
 
392
}
 
393
 
 
394
nsresult
 
395
nsExtensionManagerDataSource::GetUpdateURLForExtension(const char* aExtensionID, PRUnichar* aResult)
 
396
{
 
397
  nsCString resourceURI = NS_LITERAL_CSTRING("urn:mozilla:extension:");
 
398
  resourceURI += aExtensionID;
 
399
 
 
400
  nsCOMPtr<nsIRDFResource> extension;
 
401
  gRDFService->GetResource(resourceURI, getter_AddRefs(extension));
 
402
 
 
403
  nsCAutoString url;
 
404
  GetUpdateURLForExtensionInternal(extension, url);
 
405
 
 
406
}
 
407
 
 
408
void
 
409
nsExtensionManagerDataSource::GetUpdateURLForExtensionInternal(nsIRDFResource* aResource, nsACString& aResult)
 
410
{
 
411
  PRBool hasUpdateURLArc;
 
412
  mDataSource->HasArcOut(extension, gUpdateURLArc, &hasUpdateURLArc);
 
413
  if (hasUpdateURLArc) {
 
414
    nsCOMPtr<nsIRDFNode> updateURL;
 
415
    mDataSource->GetTarget(extension, gUpdateURLArc, PR_TRUE, getter_AddRefs(updateURL));
 
416
 
 
417
    nsCOMPtr<nsIRDFResource> updateURLResource(do_QueryInterface(updateURL));
 
418
 
 
419
    if (updateURLResource) {
 
420
      nsXPIDLCString value;
 
421
      updateURLResource->GetValueConst(getter_Shares(value));
 
422
 
 
423
      nsXPIDLCString app;
 
424
      nsCOMPtr<nsIPrefBranch> prefSvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
 
425
      prefSvc->GetCharPref(PREF_EM_APP_ID, getter_Copies(app));
 
426
      
 
427
      nsXPIDLCString id;
 
428
      extension->GetValue(getter_Copies(id));
 
429
      const nsACString& extensionPrefix = NS_LITERAL_CSTRING("urn:mozilla:extension:");
 
430
      PRInt32 prefixLength = extensionPrefix.Length();
 
431
      id.Cut(prefixLength, id.Length() - prefixLength);
 
432
 
 
433
      ReplaceAll(value, NS_LITERAL_CSTRING("%APP%"), app);
 
434
      ReplaceAll(value, NS_LITERAL_CSTRING("%ITEM%"), id);
 
435
 
 
436
      aResult = value;
 
437
    }
 
438
  }
 
439
}
 
440
 
 
441
void
 
442
nsExtensionManagerDataSource::ReplaceAll(nsACString& aString, const nsACString& aKey, const nsACString& aReplace)
 
443
{
 
444
  nsACString::const_iterator startString, startSubstring, end;
 
445
  aString.BeginReading(startString);
 
446
  aString.BeginReading(startSubstring);
 
447
  aString.EndReading(end);
 
448
 
 
449
  while (FindInReadable(aKey, startSubstring, end))
 
450
    aString.Replace(Distance(startString, startSubstring), aKey.Length(), aReplace);
 
451
}
 
452
 
 
453
///////////////////////////////////////////////////////////////////////////////
 
454
// nsIRDFDataSource
 
455
 
 
456
NS_IMETHODIMP 
 
457
nsExtensionManagerDataSource::GetURI(char** aURI)
 
458
{
 
459
  *aURI = nsCRT::strdup("rdf:extensions");
 
460
        if (!*aURI)
 
461
                return NS_ERROR_OUT_OF_MEMORY;
 
462
 
 
463
        return NS_OK;
 
464
}
 
465
 
 
466
NS_IMETHODIMP 
 
467
nsExtensionManagerDataSource::GetSource(nsIRDFResource* aProperty, 
 
468
                                        nsIRDFNode* aTarget, 
 
469
                                        PRBool aTruthValue, 
 
470
                                        nsIRDFResource** aResult)
 
471
{
 
472
  return mComposite->GetSource(aProperty, aTarget, aTruthValue, aResult);
 
473
}
 
474
 
 
475
NS_IMETHODIMP 
 
476
nsExtensionManagerDataSource::GetSources(nsIRDFResource* aProperty, 
 
477
                                         nsIRDFNode* aTarget, 
 
478
                                         PRBool aTruthValue, 
 
479
                                         nsISimpleEnumerator** aResult)
 
480
{
 
481
  return mComposite->GetSources(aProperty, aTarget, aTruthValue, aResult);
 
482
}
 
483
 
 
484
NS_IMETHODIMP 
 
485
nsExtensionManagerDataSource::GetTarget(nsIRDFResource* aSource, 
 
486
                                        nsIRDFResource* aProperty, 
 
487
                                        PRBool aTruthValue, 
 
488
                                        nsIRDFNode** aResult)
 
489
{
 
490
  nsresult rv = NS_OK;
 
491
 
 
492
  if (aProperty == gIconURLArc) {
 
493
    PRBool hasIconURLArc;
 
494
    rv = mComposite->HasArcOut(aSource, aProperty, &hasIconURLArc);
 
495
    if (NS_FAILED(rv)) return rv;
 
496
 
 
497
    // If the download entry doesn't have a IconURL property, use a
 
498
    // generic icon URL instead.
 
499
    if (!hasIconURLArc) {
 
500
      nsCOMPtr<nsIRDFResource> res;
 
501
      gRDFService->GetResource(NS_LITERAL_CSTRING("chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png"),
 
502
                               getter_AddRefs(res));
 
503
 
 
504
      *aResult = res;
 
505
      NS_IF_ADDREF(*aResult);
 
506
    }
 
507
  }
 
508
  else if (aProperty == gInstallLocationArc) {
 
509
    PRBool hasNameArc, hasVersionArc;
 
510
    rv |= mProfileExtensions->HasArcOut(aSource, gNameArc, &hasNameArc);
 
511
    rv |= mProfileExtensions->HasArcOut(aSource, gVersionArc, &hasVersionArc);
 
512
 
 
513
    *aResult = (hasNameArc && hasVersionArc) ? gInstallProfile : gInstallGlobal;
 
514
    NS_IF_ADDREF(*aResult);
 
515
  }
 
516
 
 
517
  if (!*aResult)
 
518
    rv |= mComposite->GetTarget(aSource, aProperty, aTruthValue, aResult);
 
519
 
 
520
  return rv;
 
521
}
 
522
 
 
523
NS_IMETHODIMP 
 
524
nsExtensionManagerDataSource::GetTargets(nsIRDFResource* aSource, 
 
525
                                         nsIRDFResource* aProperty, 
 
526
                                         PRBool aTruthValue, 
 
527
                                         nsISimpleEnumerator** aResult)
 
528
{
 
529
  return mComposite->GetTargets(aSource, aProperty, aTruthValue, aResult);
 
530
}
 
531
 
 
532
NS_IMETHODIMP 
 
533
nsExtensionManagerDataSource::Assert(nsIRDFResource* aSource, 
 
534
                                     nsIRDFResource* aProperty, 
 
535
                                     nsIRDFNode* aTarget, 
 
536
                                     PRBool aTruthValue)
 
537
{
 
538
  return mComposite->Assert(aSource, aProperty, aTarget, aTruthValue);
 
539
}
 
540
 
 
541
NS_IMETHODIMP 
 
542
nsExtensionManagerDataSource::Unassert(nsIRDFResource* aSource, 
 
543
                                       nsIRDFResource* aProperty, 
 
544
                                       nsIRDFNode* aTarget)
 
545
{
 
546
  return mComposite->Unassert(aSource, aProperty, aTarget);
 
547
}
 
548
 
 
549
NS_IMETHODIMP 
 
550
nsExtensionManagerDataSource::Change(nsIRDFResource* aSource, 
 
551
                                     nsIRDFResource* aProperty, 
 
552
                                     nsIRDFNode* aOldTarget, 
 
553
                                     nsIRDFNode* aNewTarget)
 
554
{
 
555
  return mComposite->Change(aSource, aProperty, aOldTarget, aNewTarget);
 
556
}
 
557
 
 
558
NS_IMETHODIMP 
 
559
nsExtensionManagerDataSource::Move(nsIRDFResource* aOldSource, 
 
560
                                   nsIRDFResource* aNewSource, 
 
561
                                   nsIRDFResource* aProperty, 
 
562
                                   nsIRDFNode* aTarget)
 
563
{
 
564
  return mComposite->Move(aOldSource, aNewSource, aProperty, aTarget);
 
565
}
 
566
 
 
567
NS_IMETHODIMP 
 
568
nsExtensionManagerDataSource::HasAssertion(nsIRDFResource* aSource, 
 
569
                                           nsIRDFResource* aProperty, 
 
570
                                           nsIRDFNode* aTarget, 
 
571
                                           PRBool aTruthValue, 
 
572
                                           PRBool* aResult)
 
573
{
 
574
  return mComposite->HasAssertion(aSource, aProperty, aTarget, aTruthValue, aResult);
 
575
}
 
576
 
 
577
NS_IMETHODIMP 
 
578
nsExtensionManagerDataSource::AddObserver(nsIRDFObserver* aObserver)
 
579
{
 
580
  return mComposite->AddObserver(aObserver);
 
581
}
 
582
 
 
583
NS_IMETHODIMP 
 
584
nsExtensionManagerDataSource::RemoveObserver(nsIRDFObserver* aObserver)
 
585
{
 
586
  return mComposite->RemoveObserver(aObserver);
 
587
}
 
588
 
 
589
NS_IMETHODIMP 
 
590
nsExtensionManagerDataSource::ArcLabelsIn(nsIRDFNode* aNode, 
 
591
                                          nsISimpleEnumerator** aResult)
 
592
{
 
593
  return mComposite->ArcLabelsIn(aNode, aResult);
 
594
}
 
595
 
 
596
NS_IMETHODIMP 
 
597
nsExtensionManagerDataSource::ArcLabelsOut(nsIRDFResource* aSource, 
 
598
                                           nsISimpleEnumerator** aResult)
 
599
{
 
600
  return mComposite->ArcLabelsOut(aSource, aResult);
 
601
}
 
602
 
 
603
NS_IMETHODIMP 
 
604
nsExtensionManagerDataSource::GetAllResources(nsISimpleEnumerator** aResult)
 
605
{
 
606
  return mComposite->GetAllResources(aResult);
 
607
}
 
608
 
 
609
NS_IMETHODIMP 
 
610
nsExtensionManagerDataSource::IsCommandEnabled(nsISupportsArray* aSources, 
 
611
                                               nsIRDFResource* aCommand, 
 
612
                                               nsISupportsArray* aArguments, 
 
613
                                               PRBool* aResult)
 
614
{
 
615
  return mComposite->IsCommandEnabled(aSources, aCommand, aArguments, aResult);
 
616
}
 
617
 
 
618
NS_IMETHODIMP 
 
619
nsExtensionManagerDataSource::DoCommand(nsISupportsArray* aSources, 
 
620
                                        nsIRDFResource* aCommand, 
 
621
                                        nsISupportsArray* aArguments)
 
622
{
 
623
  return mComposite->DoCommand(aSources, aCommand, aArguments);
 
624
}
 
625
 
 
626
NS_IMETHODIMP 
 
627
nsExtensionManagerDataSource::GetAllCmds(nsIRDFResource* aSource, 
 
628
                                         nsISimpleEnumerator** aResult)
 
629
{
 
630
  return mComposite->GetAllCmds(aSource, aResult);
 
631
}
 
632
 
 
633
NS_IMETHODIMP 
 
634
nsExtensionManagerDataSource::HasArcIn(nsIRDFNode* aNode, 
 
635
                                       nsIRDFResource* aArc, 
 
636
                                       PRBool* aResult)
 
637
{
 
638
  return mComposite->HasArcIn(aNode, aArc, aResult);
 
639
}
 
640
 
 
641
NS_IMETHODIMP 
 
642
nsExtensionManagerDataSource::HasArcOut(nsIRDFResource* aSource, 
 
643
                                        nsIRDFResource* aArc, 
 
644
                                        PRBool* aResult)
 
645
{
 
646
  return mComposite->HasArcOut(aSource, aArc, aResult);
 
647
}
 
648
 
 
649
NS_IMETHODIMP 
 
650
nsExtensionManagerDataSource::BeginUpdateBatch()
 
651
{
 
652
  return mComposite->BeginUpdateBatch();
 
653
}
 
654
 
 
655
NS_IMETHODIMP 
 
656
nsExtensionManagerDataSource::EndUpdateBatch()
 
657
{
 
658
  return mComposite->EndUpdateBatch();
 
659
}
 
660
 
 
661
///////////////////////////////////////////////////////////////////////////////
 
662
// nsIRDFRemoteDataSource
 
663
 
 
664
NS_IMETHODIMP
 
665
nsExtensionManagerDataSource::GetLoaded(PRBool* aResult)
 
666
{
 
667
  return NS_ERROR_NOT_IMPLEMENTED;
 
668
}
 
669
 
 
670
NS_IMETHODIMP
 
671
nsExtensionManagerDataSource::Init(const char* aURI)
 
672
{
 
673
  return NS_ERROR_NOT_IMPLEMENTED;
 
674
}
 
675
 
 
676
NS_IMETHODIMP
 
677
nsExtensionManagerDataSource::Refresh(PRBool aBlocking)
 
678
{
 
679
  return NS_ERROR_NOT_IMPLEMENTED;
 
680
}
 
681
 
 
682
NS_IMETHODIMP
 
683
nsExtensionManagerDataSource::Flush()
 
684
{
 
685
  return Flush(PR_FALSE) | Flush(PR_TRUE);
 
686
}
 
687
 
 
688
NS_IMETHODIMP
 
689
nsExtensionManagerDataSource::FlushTo(const char* aURI)
 
690
{
 
691
  return NS_ERROR_NOT_IMPLEMENTED;
 
692
}
 
693
 
 
694
nsresult
 
695
nsExtensionManagerDataSource::Flush(PRBool aIsProfile)
 
696
{
 
697
  nsCOMPtr<nsIRDFRemoteDataSource> rds(do_QueryInterface(aIsProfile ? mProfileExtensions : mAppExtensions));
 
698
  return rds ? rds->Flush() : NS_OK;
 
699
}
 
700