summaryrefslogtreecommitdiffstats
path: root/mailnews/base/src/nsMsgServiceProvider.cpp
blob: 224ae799df79d3b3038dba86da873733184b1fce (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsMsgServiceProvider.h"
#include "nsIServiceManager.h"

#include "nsRDFCID.h"
#include "nsIRDFService.h"
#include "nsIRDFRemoteDataSource.h"

#include "nsIFileChannel.h"
#include "nsNetUtil.h"
#include "nsMsgBaseCID.h"

#include "nsMailDirServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsISimpleEnumerator.h"
#include "nsIDirectoryEnumerator.h"

static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kRDFCompositeDataSourceCID, NS_RDFCOMPOSITEDATASOURCE_CID);
static NS_DEFINE_CID(kRDFXMLDataSourceCID, NS_RDFXMLDATASOURCE_CID);

nsMsgServiceProviderService::nsMsgServiceProviderService()
{}

nsMsgServiceProviderService::~nsMsgServiceProviderService()
{}

NS_IMPL_ISUPPORTS(nsMsgServiceProviderService, nsIRDFDataSource)

nsresult
nsMsgServiceProviderService::Init()
{
  nsresult rv;
  nsCOMPtr<nsIRDFService> rdf = do_GetService(kRDFServiceCID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);
  
  mInnerDataSource = do_CreateInstance(kRDFCompositeDataSourceCID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  LoadISPFiles();
  return NS_OK;
}

/**
 * Looks for ISP configuration files in <.exe>\isp and any sub directories called isp
 * located in the user's extensions directory.
 */
void nsMsgServiceProviderService::LoadISPFiles()
{
  nsresult rv;
  nsCOMPtr<nsIProperties> dirSvc = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
  if (NS_FAILED(rv))
    return;

  // Walk through the list of isp directories
  nsCOMPtr<nsISimpleEnumerator> ispDirectories;
  rv = dirSvc->Get(ISP_DIRECTORY_LIST,
                   NS_GET_IID(nsISimpleEnumerator), getter_AddRefs(ispDirectories));
  if (NS_FAILED(rv))
    return;

  bool hasMore;
  nsCOMPtr<nsIFile> ispDirectory;
  while (NS_SUCCEEDED(ispDirectories->HasMoreElements(&hasMore)) && hasMore) 
  {
    nsCOMPtr<nsISupports> elem;
    ispDirectories->GetNext(getter_AddRefs(elem));

    ispDirectory = do_QueryInterface(elem);
    if (ispDirectory)
      LoadISPFilesFromDir(ispDirectory);
  }
}

void nsMsgServiceProviderService::LoadISPFilesFromDir(nsIFile* aDir)
{
  nsresult rv;

  bool check = false;
  rv = aDir->Exists(&check);
  if (NS_FAILED(rv) || !check)
    return;

  rv = aDir->IsDirectory(&check);
  if (NS_FAILED(rv) || !check)
    return;

  nsCOMPtr<nsISimpleEnumerator> e;
  rv = aDir->GetDirectoryEntries(getter_AddRefs(e));
  if (NS_FAILED(rv))
    return;

  nsCOMPtr<nsIDirectoryEnumerator> files(do_QueryInterface(e));
  if (!files)
    return;

  // we only care about the .rdf files in this directory
  nsCOMPtr<nsIFile> file;
  while (NS_SUCCEEDED(files->GetNextFile(getter_AddRefs(file))) && file) {
    nsAutoString leafName;
    file->GetLeafName(leafName);
    if (!StringEndsWith(leafName, NS_LITERAL_STRING(".rdf")))
      continue;

    nsAutoCString urlSpec;
    rv = NS_GetURLSpecFromFile(file, urlSpec);
    if (NS_SUCCEEDED(rv))
      LoadDataSource(urlSpec.get());
  }
}

nsresult
nsMsgServiceProviderService::LoadDataSource(const char *aURI)
{
  nsresult rv;

  nsCOMPtr<nsIRDFDataSource> ds =
      do_CreateInstance(kRDFXMLDataSourceCID, &rv);
  NS_ENSURE_SUCCESS(rv,rv);

  nsCOMPtr<nsIRDFRemoteDataSource> remote =
      do_QueryInterface(ds, &rv);
  NS_ENSURE_SUCCESS(rv, rv);
  
  rv = remote->Init(aURI);
  NS_ENSURE_SUCCESS(rv, rv);
  // for now load synchronously (async seems to be busted)
  rv = remote->Refresh(true);
  NS_ASSERTION(NS_SUCCEEDED(rv), "failed refresh?\n");

  rv = mInnerDataSource->AddDataSource(ds);

  return rv;
}