This is just some static backup of the original site, don't expect every link to work!

source: modules/vI_rdfDatasource.js @ 9d2ae5

ng_0.9
Last change on this file since 9d2ae5 was 9d2ae5, checked in by rene <rene@…>, 4 years ago

replaced filepicker and nsILocalFile

  • Property mode set to 100644
File size: 57.0 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2    This program is free software; you can redistribute it and/or modify
3    it under the terms of the GNU General Public License as published by
4    the Free Software Foundation; either version 2 of the License, or
5    (at your option) any later version.
6
7    This program is distributed in the hope that it will be useful,
8    but WITHOUT ANY WARRANTY; without even the implied warranty of
9    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10    GNU General Public License for more details.
11
12    You should have received a copy of the GNU General Public License
13    along with this program; if not, write to the Free Software
14    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15
16    The Original Code is the Virtual Identity Extension.
17
18    The Initial Developer of the Original Code is Rene Ejury.
19    Portions created by the Initial Developer are Copyright (C) 2007
20    the Initial Developer. All Rights Reserved.
21
22    Contributor(s):
23 * ***** END LICENSE BLOCK ***** */
24
25var EXPORTED_SYMBOLS = ["rdfDatasource", "rdfDatasourceAccess", "rdfDatasourceImporter"]
26
27Components.utils.import("resource://v_identity/vI_log.js");
28let Log = setupLogging("virtualIdentity.rdfDatasource");
29
30Components.utils.import("resource://v_identity/vI_accountUtils.js");
31Components.utils.import("resource://v_identity/vI_prefs.js");
32Components.utils.import("resource://v_identity/vI_identityData.js");
33Components.utils.import("resource://gre/modules/Services.jsm");
34
35// if no 3pane-window found, return current window
36function get3PaneWindow() {
37  var windowMediator = Components.classes['@mozilla.org/appshell/window-mediator;1']
38    .getService(Components.interfaces.nsIWindowMediator);
39  var mail3paneWindow = windowMediator.getMostRecentWindow("mail:3pane");
40  if (!mail3paneWindow) return windowMediator.getMostRecentWindow(null);
41  return mail3paneWindow;
42};
43
44function initWithFilePath_tryDelimiters(_nsIFile, path, filename) {
45  try {
46    Log.debug("Filename try linux delimiter: '" + path + "/" + filename + "'");
47    _nsIFile.initWithPath(path + "/" + filename);
48  } catch (NS_ERROR_FILE_UNRECOGNIZED_PATH) {
49    try {
50      Log.debug("Filename try windows delimiter: '" + path + "\\" + filename + "'");
51      _nsIFile.initWithPath(path + "\\" + filename);
52    } catch (NS_ERROR_FILE_UNRECOGNIZED_PATH) {
53      Log.debug("Filename not valid: '" + path + "[\\/]" + filename + "'");
54      Log.debug("can't open rdfDatasource - storage won't work");
55      var debugMsg = "Filename not valid: '" + path + "\\" + filename + "'\n" +
56        "Filename not valid: '" + path + "/" + filename + "'\n" +
57        "Virtual Identity Storage won't work.\n\n" +
58        "Please report this issue with filename on https://www.absorb.it/virtual-id\n\n" +
59        "You can just copy the lines below in your browser to create a ticket\n\n" +
60        "https://www.absorb.it/virtual-id/newticket?summary=RDF Filename Error&description=Filename " + path + "[\\/]" + filename + " for rdf not valid"
61      get3PaneWindow().alert(debugMsg);
62      return;
63    }
64  }
65};
66
67function rdfDatasource(currentWindow, rdfFileName, dontRegisterObserver) {
68  this._currentWindow = currentWindow;
69  this._rdfFileName = rdfFileName;
70  if (this._rdfFileName) this.init();
71  if (!dontRegisterObserver) this.AccountManagerObserver.register(this);
72  try {
73    this._extVersion = get3PaneWindow().virtualIdentityExtension.extensionVersion;
74  } catch (e) {}
75}
76
77rdfDatasource.prototype = {
78  _currentWindow: null,
79  _extVersion: null,
80  _rdfVersion: "0.0.5",
81  _rdfService: Components.classes["@mozilla.org/rdf/rdf-service;1"]
82    .getService(Components.interfaces.nsIRDFService),
83  _rdfDataSource: null,
84  _rdfFileName: null,
85  _rdfNS: "http://virtual-id.absorb.it/",
86  _rdfNSStorage: "vIStorage",
87  _rdfNSEmail: "vIStorage/email",
88  _rdfNSMaillist: "vIStorage/maillist",
89  _rdfNSNewsgroup: "vIStorage/newsgroup",
90  _rdfNSFilter: "vIStorage/filter",
91  _rdfNSAccounts: "vIAccounts",
92  _rdfNSIdentities: "vIAccounts/id",
93  _rdfNSSMTPservers: "vIAccounts/smtp",
94
95  _virtualIdentityID: "{dddd428e-5ac8-4a81-9f78-276c734f75b8}",
96
97  _emailContainer: Components.classes["@mozilla.org/rdf/container;1"]
98    .createInstance(Components.interfaces.nsIRDFContainer),
99
100  _maillistContainer: Components.classes["@mozilla.org/rdf/container;1"]
101    .createInstance(Components.interfaces.nsIRDFContainer),
102
103  _newsgroupContainer: Components.classes["@mozilla.org/rdf/container;1"]
104    .createInstance(Components.interfaces.nsIRDFContainer),
105
106  _filterContainer: Components.classes["@mozilla.org/rdf/container;1"]
107    .createInstance(Components.interfaces.nsIRDFContainer),
108
109  _identityContainer: Components.classes["@mozilla.org/rdf/container;1"]
110    .createInstance(Components.interfaces.nsIRDFContainer),
111
112  _smtpContainer: Components.classes["@mozilla.org/rdf/container;1"]
113    .createInstance(Components.interfaces.nsIRDFContainer),
114
115  getContainer: function (type) {
116    switch (type) {
117    case "email":
118      return this._emailContainer;
119    case "maillist":
120      return this._maillistContainer;
121    case "newsgroup":
122      return this._newsgroupContainer;
123    case "filter":
124      return this._filterContainer;
125    case "identity":
126      return this._identityContainer;
127    case "smtp":
128      return this._smtpContainer;
129    }
130    return null;
131  },
132
133  init: function () {
134    //         Log.debug("init.");
135
136    this._openRdfDataSource();
137    if (!this._rdfDataSource) return;
138    this._initContainers();
139    if (this.rdfUpgradeRequired()) this.rdfUpgrade();
140
141    // store version everytime to recognize downgrades later
142    this.storeRDFVersion();
143
144    //         this.refreshAccountInfo();
145    //         Log.debug("init done.");
146  },
147
148  _openRdfDataSource: function () {
149    //         if (!this._rdfFileName || this._rdfDataSource);
150    var protoHandler = Components.classes["@mozilla.org/network/protocol;1?name=file"]
151      .getService(Components.interfaces.nsIFileProtocolHandler)
152    var newFile = Components.classes["@mozilla.org/file/local;1"]
153      .createInstance(Components.interfaces.nsIFile);
154
155    var file = Components.classes["@mozilla.org/file/directory_service;1"]
156      .getService(Components.interfaces.nsIProperties)
157      .get("ProfD", Components.interfaces.nsIFile);
158
159    //         Log.debug("_openRdfDataSource");
160    initWithFilePath_tryDelimiters(newFile, file.path, this._rdfFileName);
161
162    var fileURI = protoHandler.newFileURI(newFile);
163
164    Log.debug("init: read rdf from '" + fileURI.spec + "'");
165
166    this._rdfDataSource =
167      this._rdfService.GetDataSourceBlocking(fileURI.spec);
168
169    //         Log.debug("read rdf from '" + fileURI.spec + "' done." + this._rdfService);
170  },
171
172  _initContainers: function () {
173    try { // will possibly fail before upgrade
174      var storageRes = this._rdfService
175        .GetResource(this._rdfNS + this._rdfNSEmail);
176      this._emailContainer.Init(this._rdfDataSource, storageRes);
177      storageRes = this._rdfService
178        .GetResource(this._rdfNS + this._rdfNSMaillist);
179      this._maillistContainer.Init(this._rdfDataSource, storageRes);
180      storageRes = this._rdfService
181        .GetResource(this._rdfNS + this._rdfNSNewsgroup);
182      this._newsgroupContainer.Init(this._rdfDataSource, storageRes);
183      storageRes = this._rdfService
184        .GetResource(this._rdfNS + this._rdfNSFilter);
185      this._filterContainer.Init(this._rdfDataSource, storageRes);
186      storageRes = this._rdfService
187        .GetResource(this._rdfNS + this._rdfNSIdentities);
188      this._identityContainer.Init(this._rdfDataSource, storageRes);
189      storageRes = this._rdfService
190        .GetResource(this._rdfNS + this._rdfNSSMTPservers);
191      this._smtpContainer.Init(this._rdfDataSource, storageRes);
192    } catch (e) {};
193  },
194
195  // ******************************************************************************************
196  // **************    BEGIN RDF UPGRADE CODE    **********************************************
197  rdfUpgradeRequired: function () {
198    var oldRdfVersion = this.getCurrentRDFFileVersion();
199    var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
200      .getService(Components.interfaces.nsIVersionComparator);
201    return (!oldRdfVersion || versionChecker.compare(oldRdfVersion, this._rdfVersion) < 0)
202  },
203  // **************    RDF UPGRADE CODE    ****************************************************
204  extUpgradeRequired: function () {
205    if (!this._extVersion) return false;
206    var oldExtVersion = this.getCurrentExtFileVersion()
207    var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"]
208      .getService(Components.interfaces.nsIVersionComparator);
209    return (!oldExtVersion || versionChecker.compare(oldExtVersion, this._extVersion) < 0)
210  },
211  // **************    RDF UPGRADE CODE    ****************************************************
212  rdfUpgrade: function () {
213    var currentVersion = this.getCurrentRDFFileVersion();
214    Log.debug("checking for previous version of rdf, found " +
215      currentVersion + " - rdf-upgrade required.")
216    switch (currentVersion) {
217    case null:
218    case "0.0.1":
219    case "0.0.2":
220      this._createRDFContainers(); // no break
221    case "0.0.3":
222      this._tagDefaultSMTP();
223    case "0.0.4":
224    default:
225      this._createAccountInfoContainers();
226    }
227    this.storeRDFVersion();
228    Log.debug("rdf-upgrade to " + this.getCurrentRDFFileVersion() + " done.");
229  },
230  // **************    RDF UPGRADE CODE    ****************************************************
231  // only used for upgrade to 0.0.3 - loop through all ressources.
232  _transferAllResources: function () {
233    Log.debug("upgrade: transferAllResources");
234    var enumerator = this._rdfDataSource.GetAllResources();
235    while (enumerator && enumerator.hasMoreElements()) {
236      var resource = enumerator.getNext();
237      resource.QueryInterface(Components.interfaces.nsIRDFResource);
238
239      var type;
240      var name;
241      if (resource.ValueUTF8.match(new RegExp(this._rdfNS + this._rdfNSEmail + "/", "i"))) {
242        type = "email";
243        name = RegExp.rightContext
244      } else if (resource.ValueUTF8.match(new RegExp(this._rdfNS + this._rdfNSNewsgroup + "/", "i"))) {
245        type = "newsgroup";
246        name = RegExp.rightContext
247      } else if (resource.ValueUTF8.match(new RegExp(this._rdfNS + this._rdfNSMaillist + "/", "i"))) {
248        type = "maillist";
249        name = RegExp.rightContext
250      } else continue;
251
252      var container = this.getContainer(type);
253      this._setRDFValue(resource, "name", name);
254
255      if (container.IndexOf(resource) == -1) container.AppendElement(resource);
256    }
257  },
258  // **************    RDF UPGRADE CODE    ****************************************************
259  _tagDefaultSMTP: function () {
260    Log.debug("upgrade: tagDefaultSMTP");
261    for (let treeType of Array("email", "maillist", "newsgroup", "filter")) {
262      var enumerator = this.getContainer(treeType).GetElements();
263      while (enumerator && enumerator.hasMoreElements()) {
264        var resource = enumerator.getNext();
265        resource.QueryInterface(Components.interfaces.nsIRDFResource);
266        var smtp = this._getRDFValue(resource, "smtp")
267        if (!smtp || smtp == "") this._setRDFValue(resource, "smtp", DEFAULT_SMTP_TAG);
268      }
269    }
270  },
271  // **************    RDF UPGRADE CODE    ****************************************************
272  _createAccountInfoContainers: function () {
273    Log.debug("upgrade: createAccountInfoContainers");
274    var rdfContainerUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].
275    getService(Components.interfaces.nsIRDFContainerUtils);
276
277    var accountRes = this._rdfService
278      .GetResource(this._rdfNS + this._rdfNSAccounts);
279    var identityRes = this._rdfService
280      .GetResource(this._rdfNS + this._rdfNSIdentities);
281    var smtpRes = this._rdfService
282      .GetResource(this._rdfNS + this._rdfNSSMTPservers);
283    this._setRDFValue(accountRes, "name", "Accounts");
284    this._setRDFValue(identityRes, "name", "Identities");
285    this._setRDFValue(smtpRes, "name", "SMTP-Server");
286
287    rdfContainerUtils.MakeBag(this._rdfDataSource, accountRes);
288    rdfContainerUtils.MakeBag(this._rdfDataSource, identityRes);
289    rdfContainerUtils.MakeBag(this._rdfDataSource, smtpRes);
290
291    var accountContainer = Components.classes["@mozilla.org/rdf/container;1"].
292    createInstance(Components.interfaces.nsIRDFContainer);
293
294    // initialize container with accountRes
295    accountContainer.Init(this._rdfDataSource, accountRes);
296    // append all new containers to accountRes
297    if (accountContainer.IndexOf(identityRes) == -1) accountContainer.AppendElement(identityRes);
298    if (accountContainer.IndexOf(smtpRes) == -1) accountContainer.AppendElement(smtpRes);
299
300    this._initContainers();
301    this.refreshAccountInfo();
302  },
303  // **************    RDF UPGRADE CODE    ****************************************************
304  _createRDFContainers: function () {
305    Log.debug("upgrade: createRDFContainers");
306    var rdfContainerUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].
307    getService(Components.interfaces.nsIRDFContainerUtils);
308
309    var storageRes = this._rdfService
310      .GetResource(this._rdfNS + this._rdfNSStorage);
311    var emailRes = this._rdfService
312      .GetResource(this._rdfNS + this._rdfNSEmail);
313    var maillistRes = this._rdfService
314      .GetResource(this._rdfNS + this._rdfNSMaillist);
315    var newsgroupRes = this._rdfService
316      .GetResource(this._rdfNS + this._rdfNSNewsgroup);
317    var filterRes = this._rdfService
318      .GetResource(this._rdfNS + this._rdfNSFilter);
319    this._setRDFValue(emailRes, "name", "E-Mail");
320    this._setRDFValue(maillistRes, "name", "Mailing-List");
321    this._setRDFValue(newsgroupRes, "name", "Newsgroup");
322    this._setRDFValue(filterRes, "name", "Filter");
323
324    rdfContainerUtils.MakeBag(this._rdfDataSource, storageRes);
325    rdfContainerUtils.MakeBag(this._rdfDataSource, emailRes);
326    rdfContainerUtils.MakeBag(this._rdfDataSource, maillistRes);
327    rdfContainerUtils.MakeBag(this._rdfDataSource, newsgroupRes);
328    // use a sequence for the filters, order does matter
329    rdfContainerUtils.MakeSeq(this._rdfDataSource, filterRes);
330
331    var container = Components.classes["@mozilla.org/rdf/container;1"].
332    createInstance(Components.interfaces.nsIRDFContainer);
333
334    // initialize container with storageRes
335    container.Init(this._rdfDataSource, storageRes);
336    // append all new containers to storageRes
337    if (container.IndexOf(emailRes) == -1) container.AppendElement(emailRes);
338    if (container.IndexOf(maillistRes) == -1) container.AppendElement(maillistRes);
339    if (container.IndexOf(newsgroupRes) == -1) container.AppendElement(newsgroupRes);
340    if (container.IndexOf(filterRes) == -1) container.AppendElement(filterRes);
341
342    this._initContainers();
343
344    this._transferAllResources();
345  },
346  // **************    END RDF UPGRADE CODE    ************************************************
347  // ******************************************************************************************
348
349  getCurrentRDFFileVersion: function () {
350    return this._getRDFValue(
351      this._rdfService.GetResource(this._rdfNS + "virtualIdentity"), "rdfVersion");
352  },
353
354  getCurrentExtFileVersion: function () {
355    return this._getRDFValue(
356      this._rdfService.GetResource(this._rdfNS + "virtualIdentity"), "version");
357  },
358
359  storeRDFVersion: function () {
360    this._setRDFValue(
361      this._rdfService.GetResource(this._rdfNS + "virtualIdentity"), "rdfVersion",
362      this._rdfVersion);
363    this._flush();
364  },
365
366  storeExtVersion: function () {
367    this._setRDFValue(
368      this._rdfService.GetResource(this._rdfNS + "virtualIdentity"), "version", this._extVersion)
369    this._flush();
370  },
371
372  clean: function () {
373    this.AccountManagerObserver.unregister();
374    this._flush();
375  },
376
377  _flush: function () {
378    this._rdfDataSource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
379    try {
380      // this might fail for instance with NS_ERROR_FILE_NO_DEVICE_SPACE
381      this._rdfDataSource.Flush();
382    } catch (e) {}
383  },
384
385  refreshAccountInfo: function () {
386    try { // will possibly fail before upgrade
387      this.cleanAccountInfo();
388      this.storeAccountInfo();
389    } catch (e) {};
390  },
391
392  cleanAccountInfo: function () {
393    Log.debug("cleanAccountInfo");
394
395    var enumerator = this._identityContainer.GetElements();
396    while (enumerator && enumerator.hasMoreElements()) {
397      var resource = enumerator.getNext();
398      resource.QueryInterface(Components.interfaces.nsIRDFResource);
399      this._unsetRDFValue(resource, "identityName", this._getRDFValue(resource, "identityName"))
400      this._unsetRDFValue(resource, "fullName", this._getRDFValue(resource, "fullName"))
401      this._unsetRDFValue(resource, "email", this._getRDFValue(resource, "email"))
402      this._identityContainer.RemoveElement(resource, false);
403    }
404
405    enumerator = this._smtpContainer.GetElements();
406    while (enumerator && enumerator.hasMoreElements()) {
407      var resource = enumerator.getNext();
408      resource.QueryInterface(Components.interfaces.nsIRDFResource);
409      this._unsetRDFValue(resource, "label", this._getRDFValue(resource, "label"))
410      this._unsetRDFValue(resource, "hostname", this._getRDFValue(resource, "hostname"))
411      this._unsetRDFValue(resource, "username", this._getRDFValue(resource, "username"))
412      this._smtpContainer.RemoveElement(resource, false);
413    }
414  },
415
416  getRelevantIDs: function () {
417    var relevantIDs = new Object();
418    // search relevant Identities
419    for (let treeType of Array("email", "maillist", "newsgroup", "filter")) {
420      var enumerator = this.getContainer(treeType).GetElements();
421      while (enumerator && enumerator.hasMoreElements()) {
422        var resource = enumerator.getNext();
423        resource.QueryInterface(Components.interfaces.nsIRDFResource);
424        var id = this._getRDFValue(resource, "id")
425        if (id) {
426          if (!relevantIDs[id]) relevantIDs[id] = 1;
427          else relevantIDs[id] += 1;
428        }
429      }
430    }
431    return relevantIDs;
432  },
433
434  searchIdentityMismatch: function () {
435    Log.debug("searchIdentityMismatch");
436
437    var relevantIDs = this.getRelevantIDs();
438    var mismatchIDs = [];
439
440    for (var id in relevantIDs) {
441      var found = false;
442      var accounts = getAccountsArray();
443      var identity = null;
444      for (let acc = 0; acc < accounts.length; acc++) {
445        let account = accounts[acc];
446        let identities = getIdentitiesArray(account);
447        for (let i = 0; i < identities.length; i++) {
448          identity = identities[i];
449          if (id == identity.key) {
450            found = true;
451            break;
452          }
453        }
454        if (found) break;
455      }
456      var resource = this._rdfService.GetResource(this._rdfNS + this._rdfNSIdentities + "/" + id);
457      var rdfIdentityName = this._getRDFValue(resource, "identityName");
458      var rdfEmail = this._getRDFValue(resource, "email");
459      var rdfFullName = this._getRDFValue(resource, "fullName")
460
461      if (!found || rdfIdentityName != identity.identityName && rdfEmail != identity.email)
462        mismatchIDs.push({
463          oldkey: id,
464          label: rdfIdentityName,
465          ext1: rdfEmail,
466          ext2: rdfFullName,
467          count: relevantIDs[id],
468          key: ""
469        })
470    }
471    if (mismatchIDs.length > 0) {
472      Log.debug(" found mismatches on id(s).");
473      get3PaneWindow().openDialog("chrome://v_identity/content/vI_rdfAccountMismatchDialog.xul", 0,
474        "chrome, dialog, modal, alwaysRaised, resizable=yes", "identity", mismatchIDs,
475        /* callback chance: */
476        this).focus();
477      return true;
478    } else {
479      Log.debug(" found no mismatch");
480      return false;
481    }
482  },
483
484  repairAccountMismatch: function (type, mismatchItems) {
485    var keyField = (type == "identity") ? "id" : "smtp" // field to change is 'id' or 'smtp' dependent on type
486    for (var i = 0; i < mismatchItems.length; i++) {
487      Log.debug("repairAccountMismatch change " + mismatchItems[i].oldkey + " into " + mismatchItems[i].key);
488      // search relevant Identities
489      for (let treeType of Array("email", "maillist", "newsgroup", "filter")) {
490        var enumerator = this.getContainer(treeType).GetElements();
491        while (enumerator && enumerator.hasMoreElements()) {
492          var resource = enumerator.getNext();
493          resource.QueryInterface(Components.interfaces.nsIRDFResource);
494          if (this._getRDFValue(resource, keyField) == mismatchItems[i].oldkey) {
495            if (mismatchItems[i].key == "") this._unsetRDFValue(resource, keyField, mismatchItems[i].oldkey)
496            else this._setRDFValue(resource, keyField, mismatchItems[i].key)
497          }
498        }
499      }
500    }
501  },
502
503  getRelevantSMTPs: function () {
504    var relevantSMTPs = new Object();
505    // search relevant SMTPs
506    for (let treeType of Array("email", "maillist", "newsgroup", "filter")) {
507      var enumerator = this.getContainer(treeType).GetElements();
508      while (enumerator && enumerator.hasMoreElements()) {
509        var resource = enumerator.getNext();
510        resource.QueryInterface(Components.interfaces.nsIRDFResource);
511        var smtp = this._getRDFValue(resource, "smtp")
512        if (smtp && smtp != DEFAULT_SMTP_TAG) {
513          if (!relevantSMTPs[smtp]) relevantSMTPs[smtp] = 1;
514          else relevantSMTPs[smtp] += 1;
515        }
516      }
517    }
518    return relevantSMTPs;
519  },
520
521  searchSmtpMismatch: function () {
522    Log.debug("searchSmtpMismatch");
523
524    var relevantSMTPs = this.getRelevantSMTPs();
525    var mismatchSMTPs = [];
526
527    for (var smtp in relevantSMTPs) {
528      var servers, smtpService = Components.classes["@mozilla.org/messengercompose/smtp;1"]
529        .getService(Components.interfaces.nsISmtpService);
530      // check for new https://hg.mozilla.org/comm-central/rev/fab9e5145cd4 smtpService
531      if (typeof (smtpService.servers) == "object") servers = smtpService.servers;
532      else servers = smtpService.smtpServers;
533
534      var found = false;
535      while (servers && servers.hasMoreElements()) {
536        var server = servers.getNext();
537        if (server instanceof Components.interfaces.nsISmtpServer &&
538          !server.redirectorType && smtp == server.key) {
539          found = true;
540          break;
541        }
542      }
543      var resource = this._rdfService.GetResource(this._rdfNS + this._rdfNSSMTPservers + "/" + smtp);
544      var rdfSMTPlabel = this._getRDFValue(resource, "label");
545      var rdfHostname = this._getRDFValue(resource, "hostname");
546      var rdfUsername = this._getRDFValue(resource, "username")
547      if (!found || rdfSMTPlabel != (server.description ? server.description : server.hostname) && rdfHostname != server.hostname)
548        mismatchSMTPs.push({
549          oldkey: smtp,
550          label: rdfSMTPlabel,
551          ext1: rdfHostname,
552          ext2: rdfUsername,
553          count: relevantSMTPs[smtp],
554          key: ""
555        })
556    }
557    if (mismatchSMTPs.length > 0) {
558      Log.debug(" found mismatches on smtp(s).");
559      get3PaneWindow().openDialog("chrome://v_identity/content/vI_rdfAccountMismatchDialog.xul", 0,
560        "chrome, dialog, modal, alwaysRaised, resizable=yes", "smtp", mismatchSMTPs,
561        /* callback: */
562        this).focus();
563      return true;
564    } else {
565      Log.debug(" found no mismatch");
566      return false;
567    }
568  },
569
570  storeAccountInfo: function () {
571    Log.debug("storeAccounts");
572    var accounts = getAccountsArray();
573    for (let acc = 0; acc < accounts.length; acc++) {
574      let account = accounts[acc];
575      let identities = getIdentitiesArray(account);
576      for (let i = 0; i < identities.length; i++) {
577        let identity = identities[i];
578        //                 Log.debug("storeAccounts identity store id " + identity.key);
579
580        var resource = this._rdfService.GetResource(this._rdfNS + this._rdfNSIdentities + "/" + identity.key);
581        this._setRDFValue(resource, "identityName", identity.identityName);
582        this._setRDFValue(resource, "fullName", identity.fullName);
583        this._setRDFValue(resource, "email", identity.email);
584
585        var position = this._identityContainer.IndexOf(resource); // check for index in new recType
586        if (position != -1) this._identityContainer.InsertElementAt(resource, position, false);
587        else this._identityContainer.AppendElement(resource);
588      }
589    }
590
591    function storeSmtp(server, parent) {
592      //             Log.debug("storeAccounts smtp store id " + server.key);
593      var resource = parent._rdfService.GetResource(parent._rdfNS + parent._rdfNSSMTPservers + "/" + server.key);
594      parent._setRDFValue(resource, "label", (server.description ? server.description : server.hostname));
595      parent._setRDFValue(resource, "hostname", server.hostname);
596      parent._setRDFValue(resource, "username", server.username);
597      var position = parent._smtpContainer.IndexOf(resource); // check for index in new recType
598      if (position != -1) parent._smtpContainer.InsertElementAt(resource, position, false);
599      else parent._smtpContainer.AppendElement(resource);
600    }
601
602    var servers, smtpService = Components.classes["@mozilla.org/messengercompose/smtp;1"]
603      .getService(Components.interfaces.nsISmtpService);
604    // check for new https://hg.mozilla.org/comm-central/rev/fab9e5145cd4 smtpService
605    if (typeof (smtpService.servers) == "object") servers = smtpService.servers;
606    else servers = smtpService.smtpServers;
607
608    while (servers && servers.hasMoreElements()) {
609      var server = servers.getNext();
610      if (server instanceof Components.interfaces.nsISmtpServer && !server.redirectorType) storeSmtp(server, this);
611    }
612
613    //         Log.debug("storeAccounts done");
614  },
615
616  export: function (rdfFileName) {
617    Log.debug("vI_rdfDatasource export: " + rdfFileName + "\n");
618    var filePicker = Components.classes["@mozilla.org/filepicker;1"]
619      .createInstance(Components.interfaces.nsIFilePicker);
620    filePicker.init(get3PaneWindow(), "", Components.interfaces.nsIFilePicker.modeSave);
621    filePicker.appendFilters(Components.interfaces.nsIFilePicker.filterAll | Components.interfaces.nsIFilePicker.filterText);
622    filePicker.appendFilter("RDF Files", "*.rdf");
623
624    if (this._pickerShow(filePicker) != Components.interfaces.nsIFilePicker.returnCancel) {
625      var rdfDataFile = Components.classes["@mozilla.org/file/local;1"]
626        .createInstance(Components.interfaces.nsIFile);
627      var file = Components.classes["@mozilla.org/file/directory_service;1"]
628        .getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
629
630      initWithFilePath_tryDelimiters(rdfDataFile, file.path, rdfFileName);
631      rdfDataFile.copyTo(filePicker.file.parent, filePicker.file.leafName);
632    }
633  },
634
635  _pickerShow: function (fp) {
636    let done = false;
637    let rv, result;
638    fp.open(result => {
639      rv = result;
640      done = true;
641    });
642    let thread = Components.classes["@mozilla.org/thread-manager;1"]
643                          .getService().currentThread;
644    while (!done) {
645      thread.processNextEvent(true);
646    }
647    return rv;
648  },
649 
650  _getRDFResourceForVIdentity: function (recDescription, recType) {
651    if (!this._rdfDataSource) return null;
652    if (!recDescription) {
653      Log.debug("_getRDFResourceForVIdentity: no Recipient given.");
654      return null;
655    }
656    var _rdfNSRecType = null
657    switch (recType) {
658    case "email":
659      _rdfNSRecType = this._rdfNSEmail;
660      break;
661    case "newsgroup":
662      _rdfNSRecType = this._rdfNSNewsgroup;
663      break;
664    case "maillist":
665      _rdfNSRecType = this._rdfNSMaillist;
666      break;
667    case "filter":
668      _rdfNSRecType = this._rdfNSFilter;
669      break;
670    }
671    return this._rdfService.GetResource(this._rdfNS + _rdfNSRecType + "/" + recDescription);
672
673
674  },
675
676  removeVIdentityFromRDF: function (resource, recType) {
677    //      Log.debug("removeVIdentityFromRDF " + resource.ValueUTF8);
678    this._unsetRDFValue(resource, "email", this._getRDFValue(resource, "email"))
679    this._unsetRDFValue(resource, "fullName", this._getRDFValue(resource, "fullName"))
680    this._unsetRDFValue(resource, "id", this._getRDFValue(resource, "id"))
681    this._unsetRDFValue(resource, "smtp", this._getRDFValue(resource, "smtp"))
682    this._unsetRDFValue(resource, "name", this._getRDFValue(resource, "name"))
683
684    let self = this;
685    var extras = new identityDataExtras(this._currentWindow, self, resource)
686    extras.loopThroughExtras(
687      function (extra) {
688        extra.value = self._unsetRDFValue(resource, extra.field, extra.value)
689      });
690
691    this.getContainer(recType).RemoveElement(resource, true);
692  },
693
694  _unsetRDFValue: function (resource, field, value) {
695    //      Log.debug("_unsetRDFValue " + this._rdfService  + " " + this._rdfDataSource);
696    var predicate = this._rdfService.GetResource(this._rdfNS + "rdf#" + field);
697    var name = this._rdfService.GetLiteral(value ? value : "");
698    var target = this._rdfDataSource.GetTarget(resource, predicate, true);
699    if (target instanceof Components.interfaces.nsIRDFLiteral) {
700      this._rdfDataSource.Unassert(resource, predicate, name, true);
701      return null;
702    } else return value;
703  },
704
705  // this will be used from rdfDataTree to get all RDF values, callFunction is vI.rdfDataTreeCollection.__addNewDatum
706  readAllEntriesFromRDF: function (addNewDatum, treeType, idData) {
707    //      Log.debug("readAllEntriesFromRDF " + this._rdfService  + " " + this._rdfDataSource + " " + this);
708    var enumerator = this.getContainer(treeType).GetElements();
709    while (enumerator && enumerator.hasMoreElements()) {
710      var resource = enumerator.getNext();
711      resource.QueryInterface(Components.interfaces.nsIRDFResource);
712      var name = this._getRDFValue(resource, "name")
713      var email = this._getRDFValue(resource, "email")
714      var fullName = this._getRDFValue(resource, "fullName")
715      var id = this._getRDFValue(resource, "id")
716      var smtp = this._getRDFValue(resource, "smtp")
717      var used = this._getRDFValue(resource, "timeUsed")
718      var changed = this._getRDFValue(resource, "timeChanged")
719      if (!smtp) smtp = NO_SMTP_TAG;
720      let self = this;
721      var localIdentityData = new identityData(this._currentWindow, email, fullName, id, smtp,
722        new identityDataExtras(this._currentWindow, self, resource))
723      addNewDatum(resource, name, localIdentityData, idData, used, changed)
724    }
725  },
726
727  __getDescriptionAndType: function (recipient, recipientType) {
728    if (recipientType == "addr_newsgroups") {
729      return {
730        recDesc: recipient,
731        recType: "newsgroup"
732      }
733    } else if (this.__isMailingList(recipient)) {
734      Log.debug("__getDescriptionAndType: '" + recipient + "' is MailList");
735      return {
736        recDesc: this.__getMailListName(recipient),
737        recType: "maillist"
738      }
739    } else {
740      Log.debug("__getDescriptionAndType: '" + recipient + "' is no MailList");
741      var localIdentityData = new identityData(this._currentWindow, recipient, null, null, null, null, null, null);
742      return {
743        recDesc: localIdentityData.combinedName,
744        recType: "email"
745      }
746    }
747  },
748
749  // --------------------------------------------------------------------
750  // check if recipient is a mailing list.
751  // Similiar to Thunderbird, if there are muliple cards with the same displayName the mailinglist is preferred
752  // see also https://bugzilla.mozilla.org/show_bug.cgi?id=408575
753  __isMailingList: function (recipient) {
754    let abManager = Components.classes["@mozilla.org/abmanager;1"]
755      .getService(Components.interfaces.nsIAbManager);
756    let allAddressBooks = abManager.directories;
757    while (allAddressBooks.hasMoreElements()) {
758      let ab = allAddressBooks.getNext();
759      if (ab instanceof Components.interfaces.nsIAbDirectory && !ab.isRemote) {
760        let abdirectory = abManager.getDirectory(ab.URI +
761          "?(and(DisplayName,=," + encodeURIComponent(this.__getMailListName(recipient)) + ")(IsMailList,=,TRUE))");
762        if (abdirectory) {
763          try { // just try, sometimes there are no childCards at all...
764            let cards = abdirectory.childCards;
765            if (cards.hasMoreElements()) return true; // only interested if there is at least one element...
766          } catch (e) {}
767        }
768      }
769    }
770    return false;
771  },
772
773  // --------------------------------------------------------------------
774
775  __getMailListName: function (recipient) {
776    if (recipient.match(/<[^>]*>/) || recipient.match(/$/)) {
777      var mailListName = RegExp.leftContext + RegExp.rightContext
778      mailListName = mailListName.replace(/^\s+|\s+$/g, "")
779    }
780    return mailListName;
781  },
782
783  findMatchingFilter: function (recipient, recipientType) {
784    var recDescription = this.__getDescriptionAndType(recipient, recipientType).recDesc;
785    Log.debug("findMatchingFilter for " + recDescription);
786    var enumerator = this._filterContainer.GetElements();
787    while (enumerator && enumerator.hasMoreElements()) {
788      var resource = enumerator.getNext();
789      resource.QueryInterface(Components.interfaces.nsIRDFResource);
790      var filter = this._getRDFValue(resource, "name");
791
792      const filterType = {
793        None: 0,
794        RegExp: 1,
795        StrCmp: 2
796      }
797      var recentfilterType;
798
799      if (filter == "") continue;
800      if (/^\/(.*)\/$/.exec(filter)) {
801        Log.debug("findMatchingFilter with RegExp '" + filter.replace(/\\/g, "\\\\") + "'");
802        recentfilterType = filterType.RegExp;
803      } else {
804        Log.debug("findMatchingFilter, compare with '" + filter + "'");
805        recentfilterType = filterType.StrCmp;
806      }
807
808      switch (recentfilterType) {
809      case filterType.RegExp:
810        try {
811          /^\/(.*)\/$/.exec(filter);
812          if (recDescription.match(new RegExp(RegExp.$1, "i"))) {
813            Log.debug("findMatchingFilter found stored data.");
814            return this._readVIdentityFromRDF(resource);
815          }
816        } catch (vErr) {};
817        break;
818      case filterType.StrCmp:
819        if (recDescription.toLowerCase().indexOf(filter.toLowerCase()) != -1) {
820          Log.debug("findMatchingFilter found stored data.");
821          return this._readVIdentityFromRDF(resource);
822        }
823        break;
824      }
825    }
826    Log.debug("findMatchingFilter no match found.");
827    return null;
828  },
829
830  readVIdentityFromRDF: function (recipient, recipientType) {
831    var storedRecipient = this.__getDescriptionAndType(recipient, recipientType);
832    var email = this._rdfService.GetResource(this._rdfNS + "rdf#email");
833    var resource = this._getRDFResourceForVIdentity(storedRecipient.recDesc, storedRecipient.recType);
834    if (!resource) return null;
835    if (!this._rdfDataSource.hasArcOut(resource, email)) {
836      // no data available --> give up.
837      Log.debug("readVIdentityFromRDF no data found.");
838      return null;
839    }
840    Log.debug("readVIdentityFromRDF found stored data.");
841
842    return this._readVIdentityFromRDF(resource);
843  },
844
845  _readVIdentityFromRDF: function (resource) {
846    var email = this._getRDFValue(resource, "email")
847    var fullName = this._getRDFValue(resource, "fullName")
848    var id = this._getRDFValue(resource, "id")
849    var smtp = this._getRDFValue(resource, "smtp")
850    if (!smtp) smtp = NO_SMTP_TAG;
851
852    let _date = new Date();
853    this._setRDFValue(resource, "timeUsed", _date.getTime());
854
855    Log.debug("email='" + email +
856      "' fullName='" + fullName + "' id='" + id + "' smtp='" + smtp + "'");
857
858    let self = this;
859    var localIdentityData = new identityData(this._currentWindow, email, fullName, id, smtp,
860      new identityDataExtras(this._currentWindow, self, resource))
861    return localIdentityData;
862  },
863
864  _getRDFValue: function (resource, field) {
865    //         Log.debug("_getRDFValue " + this._rdfService  + " " + this._rdfDataSource + " " + this);
866    var predicate = this._rdfService.GetResource(this._rdfNS + "rdf#" + field);
867    var target = this._rdfDataSource.GetTarget(resource, predicate, true);
868    if (target instanceof Components.interfaces.nsIRDFLiteral) return target.Value
869    else return null;
870  },
871
872  updateRDFFromVIdentity: function (identityData, recipientName, recipientType) {
873    var recipient = this.__getDescriptionAndType(recipientName, recipientType)
874    this.updateRDF(recipient.recDesc, recipient.recType, identityData,
875      vIprefs.get("storage_store_base_id"),
876      vIprefs.get("storage_store_SMTP"),
877      null, null, false);
878  },
879
880  removeRDF: function (recDescription, recType) {
881    var resource = this._getRDFResourceForVIdentity(recDescription, recType);
882    if (!resource) return null;
883    this.removeVIdentityFromRDF(resource, recType);
884    return resource;
885  },
886
887  updateRDF: function (recDescription, recType, localIdentityData, storeBaseID, storeSMTP, prevRecDescription, prevRecType, updateAllExtras) {
888    //         Log.debug("(" + this._rdfNS + "): updateRDF recDescription=" + recDescription + " localIdentityData.email=" + localIdentityData.email);
889
890    //      if (!localIdentityData.email) {
891    //          Log.debug("updateRDF: no Sender-email for Recipient, aborting.");
892    //          return;
893    //      }
894    if (!recDescription || recDescription.length == 0) return;
895
896    if (!prevRecDescription) prevRecDescription = recDescription;
897    if (!prevRecType) prevRecType = recType;
898
899    var resource = this._getRDFResourceForVIdentity(prevRecDescription, prevRecType);
900    if (!resource) return;
901    //      Log.debug("updateRDF " + resource.ValueUTF8);
902
903    var position = this.getContainer(recType).IndexOf(resource); // check for index in new recType
904    this.removeVIdentityFromRDF(resource, prevRecType);
905
906    resource = this._getRDFResourceForVIdentity(recDescription, recType);
907
908    this._setRDFValue(resource, "email", localIdentityData.email);
909    this._setRDFValue(resource, "fullName", localIdentityData.fullName);
910    if (storeBaseID)
911      this._setRDFValue(resource, "id", localIdentityData.id.key);
912    else this._unsetRDFValue(resource, "id", this._getRDFValue(resource, "id"))
913    if (storeSMTP && localIdentityData.smtp.key != NO_SMTP_TAG)
914      this._setRDFValue(resource, "smtp", localIdentityData.smtp.key);
915    else this._unsetRDFValue(resource, "smtp", this._getRDFValue(resource, "smtp"))
916    this._setRDFValue(resource, "name", recDescription);
917
918    if (localIdentityData.extras) {
919      let self = this;
920      localIdentityData.extras.loopThroughExtras(
921        function (extra) {
922          if (updateAllExtras || extra.active)
923            extra.value = self._setRDFValue(resource, extra.field, extra.value)
924        });
925      //           Log.debug("extras: " + localIdentityData.extras.status());
926    }
927
928    let _date = new Date();
929    this._setRDFValue(resource, "timeChanged", _date.getTime());
930
931    //      Log.debug("updateRDF add " + resource.ValueUTF8 + " at position " + position);
932    if (position != -1) this.getContainer(recType).InsertElementAt(resource, position, true);
933    else this.getContainer(recType).AppendElement(resource);
934  },
935
936  _setRDFValue: function (resource, field, value) {
937    //      Log.debug("_setRDFValue " + resource.ValueUTF8 + " " + field + " " + value);
938    if (!value) return value; // return if some value was not set.
939    //      Log.debug("_setRDFValue " + this._rdfService + " " + this._rdfDataSource);
940    var predicate = this._rdfService.GetResource(this._rdfNS + "rdf#" + field);
941    var name = this._rdfService.GetLiteral(value);
942    var target = this._rdfDataSource.GetTarget(resource, predicate, true);
943
944    if (target instanceof Components.interfaces.nsIRDFLiteral)
945      this._rdfDataSource.Change(resource, predicate, target, name);
946    else this._rdfDataSource.Assert(resource, predicate, name, true);
947    return value;
948  },
949
950  //  code adapted from http://xulsolutions.blogspot.com/2006/07/creating-uninstall-script-for.html
951  AccountManagerObserver: {
952    self: null,
953    _uninstall: false,
954    observe: function (subject, topic, data) {
955      if (topic == "am-smtpChanges" || topic == "am-acceptChanges") {
956        Log.debug("account/smtp changes observed");
957        this.self.searchIdentityMismatch();
958        this.self.searchSmtpMismatch();
959        this.self.refreshAccountInfo();
960      }
961    },
962    register: function (self) {
963      this.self = self;
964      Log.debug("register AccountManagerObserver");
965      var obsService = Components.classes["@mozilla.org/observer-service;1"].
966      getService(Components.interfaces.nsIObserverService)
967      obsService.addObserver(this, "am-smtpChanges", false);
968      obsService.addObserver(this, "am-acceptChanges", false);
969    },
970    unregister: function () {
971      var obsService = Components.classes["@mozilla.org/observer-service;1"].
972      getService(Components.interfaces.nsIObserverService)
973      try {
974        obsService.removeObserver(this, "am-smtpChanges");
975        obsService.removeObserver(this, "am-acceptChanges");
976      } catch (e) {};
977    }
978  }
979}
980
981
982function rdfDatasourceAccess(currentWindow) {
983  this._currentWindow = currentWindow;
984  this._rdfDataSource = new rdfDatasource(this._currentWindow, "virtualIdentity.rdf", false);
985  this.stringBundle = Services.strings.createBundle("chrome://v_identity/locale/v_identity.properties");
986}
987
988rdfDatasourceAccess.prototype = {
989  _currentWindow: null,
990  _rdfDataSource: null,
991  stringBundle: null,
992
993  clean: function () {
994    this._rdfDataSource.clean();
995  },
996
997  updateVIdentityFromStorage: function (recipientName, recipientType, currentIdentity, currentIdentityIsVid, isNotFirstInputElement) {
998    var localIdentities = new identityCollection();
999    localIdentities.addWithoutDuplicates(this._rdfDataSource.readVIdentityFromRDF(recipientName, recipientType));
1000    if (localIdentities.number == 1) Log.debug("using data from direct match");
1001    localIdentities.addWithoutDuplicates(this._rdfDataSource.findMatchingFilter(recipientName, recipientType));
1002
1003    var returnValue = {};
1004    returnValue.identityCollection = localIdentities;
1005    returnValue.result = "drop";
1006    if (localIdentities.number == 0) {
1007      Log.debug("updateVIdentityFromStorage no usable Storage-Data found.");
1008    } else {
1009      Log.debug("compare with current Identity");
1010      if (vIprefs.get("storage_getOneOnly") && // if requested to retrieve only storageID for first recipient entered
1011        isNotFirstInputElement && // and it is now not the first recipient entered
1012        !localIdentities.identityDataCollection[0].equalsIdentity(currentIdentity, false).equal) { // and this id is different than the current used one
1013        StorageNotification.info(this.stringBundle.GetStringFromName("vident.smartIdentity.vIStorageCollidingIdentity"));
1014        //                  returnValue.result = "drop";    // this is the default value
1015      }
1016      // only update fields if new Identity is different than old one.
1017      else {
1018        Log.debug("updateVIdentityFromStorage check if storage-data matches current Identity.");
1019        var compResult = localIdentities.identityDataCollection[0].equalsIdentity(currentIdentity, true);
1020        if (!compResult.equal) {
1021          var warning = this.__getWarning("replaceVIdentity", recipientName, compResult.compareMatrix);
1022          if (!currentIdentityIsVid ||
1023            !vIprefs.get("storage_warn_vI_replace") ||
1024            (this.__askWarning(warning) == "accept")) {
1025            returnValue.result = "accept";
1026          }
1027        } else {
1028          returnValue.result = "equal";
1029        }
1030      }
1031    }
1032    return returnValue;
1033  },
1034
1035  storeVIdentityToAllRecipients: function (identityData, recipients) {
1036    var multipleRecipients = (recipients.length > 1);
1037    var dontUpdateMultipleNoEqual = (vIprefs.get("storage_dont_update_multiple") && multipleRecipients)
1038    Log.debug("storeVIdentityToAllRecipients dontUpdateMultipleNoEqual='" + dontUpdateMultipleNoEqual + "'")
1039
1040    let returnValue = {
1041      update: "cancel"
1042    };
1043    for (var j = 0; j < recipients.length; j++) {
1044      returnValue = this.__updateStorageFromVIdentity(identityData, recipients[j].recipient, recipients[j].recipientType, dontUpdateMultipleNoEqual);
1045      if (returnValue.update != "accept") break;
1046    }
1047    return returnValue;
1048  },
1049
1050  getVIdentityFromAllRecipients: function (allIdentities, recipients) {
1051    if (!vIprefs.get("storage")) {
1052      Log.debug("Storage deactivated");
1053      return;
1054    }
1055    var initnumber = allIdentities.number;
1056    for (var j = 0; j < recipients.length; j++) {
1057      allIdentities.addWithoutDuplicates(this._rdfDataSource.readVIdentityFromRDF(recipients[j].recipient, recipients[j].recipientType));
1058      allIdentities.addWithoutDuplicates(this._rdfDataSource.findMatchingFilter(recipients[j].recipient, recipients[j].recipientType));
1059    }
1060    Log.debug("found " + (allIdentities.number - initnumber) + " address(es)")
1061  },
1062
1063  __updateStorageFromVIdentity: function (identityData, recipient, recipientType, dontUpdateMultipleNoEqual) {
1064    Log.debug("__updateStorageFromVIdentity.")
1065    var storageDataByType = this._rdfDataSource.readVIdentityFromRDF(recipient, recipientType);
1066    var storageDataByFilter = this._rdfDataSource.findMatchingFilter(recipient, recipientType);
1067
1068    // update (storing) of data by type is required if there is
1069    // no data stored by type (or different data stored) and no equal filter found
1070    var storageDataByTypeCompResult = storageDataByType ? storageDataByType.equalsIdentity(identityData, true) : null;
1071    var storageDataByTypeEqual = (storageDataByType && storageDataByTypeCompResult.equal);
1072    var storageDataByFilterEqual = (storageDataByFilter && storageDataByFilter.equalsIdentity(identityData, false).equal);
1073
1074    var doUpdate = "accept";
1075    if ((!storageDataByType && !storageDataByFilterEqual) ||
1076      (!storageDataByTypeEqual && !storageDataByFilterEqual && !dontUpdateMultipleNoEqual)) {
1077      Log.debug("__updateStorageFromVIdentity updating")
1078      if (storageDataByType && !storageDataByTypeEqual && vIprefs.get("storage_warn_update")) {
1079        Log.debug("__updateStorageFromVIdentity overwrite warning");
1080        doUpdate = this.__askWarning(this.__getWarning("updateStorage", recipient, storageDataByTypeCompResult.compareMatrix));
1081      }
1082    }
1083    if (doUpdate == "accept") this._rdfDataSource.updateRDFFromVIdentity(identityData, recipient, recipientType);
1084    return {
1085      update: doUpdate,
1086      storedIdentity: storageDataByType
1087    };
1088  },
1089
1090  __getWarning: function (warningCase, recipient, compareMatrix) {
1091    var warning = {
1092      title: null,
1093      recLabel: null,
1094      recipient: null,
1095      warning: null,
1096      css: null,
1097      query: null,
1098      class: null
1099    };
1100    warning.title = this.stringBundle.GetStringFromName("vident." + warningCase + ".title")
1101    warning.recLabel = this.stringBundle.GetStringFromName("vident." + warningCase + ".recipient") + ":";
1102    warning.recipient = recipient;
1103    warning.warning =
1104      "<table class='" + warningCase + "'><thead><tr><th class='col1'/>" +
1105      "<th class='col2'>" + this.stringBundle.GetStringFromName("vident." + warningCase + ".currentIdentity") + "</th>" +
1106      "<th class='col3'>" + this.stringBundle.GetStringFromName("vident." + warningCase + ".storedIdentity") + "</th>" +
1107      "</tr></thead>" +
1108      "<tbody>" + compareMatrix + "</tbody>" +
1109      "</table>"
1110    warning.css = "vI.DialogBrowser.css";
1111    warning.query = this.stringBundle.GetStringFromName("vident." + warningCase + ".query");
1112    warning.class = warningCase;
1113    return warning;
1114  },
1115
1116  __askWarning: function (warning) {
1117    var retVar = {
1118      returnValue: null
1119    };
1120    var answer = this._currentWindow.openDialog("chrome://v_identity/content/vI_Dialog.xul", "",
1121      "chrome, dialog, modal, alwaysRaised, resizable=yes",
1122      warning, retVar)
1123    Log.debug("retVar.returnValue=" + retVar.returnValue)
1124    return retVar.returnValue;
1125  },
1126}
1127
1128
1129// create with name of the file to import into
1130function rdfDatasourceImporter(currentWindow, rdfFileName) {
1131  this._currentWindow = currentWindow;
1132  this._rdfFileName = rdfFileName;
1133  if (this._rdfFileName) this.import();
1134}
1135
1136rdfDatasourceImporter.prototype = {
1137  _currentWindow: null,
1138  _rdfService: Components.classes["@mozilla.org/rdf/rdf-service;1"]
1139    .getService(Components.interfaces.nsIRDFService),
1140  _rdfDataSource: null,
1141  _rdfFileName: null,
1142  _rdfImportDataSource: null,
1143
1144  _getMatchingIdentity: function (name, email, fullName) {
1145    var accounts = getAccountsArray();
1146    for (let acc = 0; acc < accounts.length; acc++) {
1147      let account = accounts[acc];
1148      let identities = getIdentitiesArray(account);
1149      for (let i = 0; i < identities.length; i++) {
1150        let identity = identities[i];
1151        if (name == identity.identityName || (fullName == identity.fullName && email == identity.email)) return identity.key;
1152      }
1153    }
1154    return null;
1155  },
1156
1157  _getMatchingSMTP: function (label, hostname, username) {
1158    var servers, smtpService = Components.classes["@mozilla.org/messengercompose/smtp;1"]
1159      .getService(Components.interfaces.nsISmtpService);
1160    // check for new https://hg.mozilla.org/comm-central/rev/fab9e5145cd4 smtpService
1161    if (typeof (smtpService.servers) == "object") servers = smtpService.servers;
1162    else servers = smtpService.smtpServers;
1163
1164    while (servers && servers.hasMoreElements()) {
1165      var server = servers.getNext();
1166      if (server instanceof Components.interfaces.nsISmtpServer && !server.redirectorType)
1167        if (label == (server.description ? server.description : server.hostname) || (hostname == server.hostname && username == server.username))
1168          return server.key;
1169    }
1170    return null;
1171  },
1172
1173  _translateRelevantIDs: function () {
1174    var relevantIDs = this._rdfImportDataSource.getRelevantIDs();
1175    for (var id in relevantIDs) {
1176      var resource = this._rdfService.GetResource(this._rdfImportDataSource._rdfNS + this._rdfImportDataSource._rdfNSIdentities + "/" + id);
1177      var values = {
1178        id: null,
1179        identityName: null,
1180        email: null,
1181        fullName: null
1182      }
1183      values.identityName = this._rdfImportDataSource._getRDFValue(resource, "identityName");
1184      values.email = this._rdfImportDataSource._getRDFValue(resource, "email");
1185      values.fullName = this._rdfImportDataSource._getRDFValue(resource, "fullName");
1186      values.id = this._getMatchingIdentity(values.identityName, values.email, values.fullName);
1187      values.id = values.id ? values.id : "import_" + id
1188      relevantIDs[id] = values;
1189      Log.debug("import: translate relevant ID from previous '" + id + "' to current '" + relevantIDs[id].id + "'");
1190    }
1191    return relevantIDs;
1192  },
1193
1194  _storeMappedIDs: function (relevantIDs) {
1195    for (var id in relevantIDs) {
1196      if (relevantIDs[id].id == "import_" + id) {
1197        var resource = this._rdfService
1198          .GetResource(this._rdfDataSource._rdfNS + this._rdfDataSource._rdfNSIdentities + "/" + relevantIDs[id].id);
1199        this._rdfDataSource._setRDFValue(resource, "identityName", relevantIDs[id].identityName);
1200        this._rdfDataSource._setRDFValue(resource, "fullName", relevantIDs[id].fullName);
1201        this._rdfDataSource._setRDFValue(resource, "email", relevantIDs[id].email);
1202
1203        var position = this._rdfDataSource._identityContainer.IndexOf(resource); // check for index in new recType
1204        if (position != -1) this._rdfDataSource._identityContainer.InsertElementAt(resource, position, false);
1205        else this._rdfDataSource._identityContainer.AppendElement(resource);
1206      }
1207    }
1208  },
1209
1210  _translateRelevantSMTPs: function () {
1211    var relevantSMTPs = this._rdfImportDataSource.getRelevantSMTPs();
1212    for (var smtp in relevantSMTPs) {
1213      var resource = this._rdfService.GetResource(this._rdfImportDataSource._rdfNS + this._rdfImportDataSource._rdfNSSMTPservers + "/" + smtp);
1214      var values = {
1215        smtp: null,
1216        label: null,
1217        hostname: null,
1218        username: null
1219      }
1220      values.label = this._rdfImportDataSource._getRDFValue(resource, "label");
1221      values.hostname = this._rdfImportDataSource._getRDFValue(resource, "hostname");
1222      values.username = this._rdfImportDataSource._getRDFValue(resource, "username");
1223      values.smtp = this._getMatchingSMTP(values.label, values.hostname, values.username);
1224      values.smtp = values.smtp ? values.smtp : "import_" + smtp;
1225      relevantSMTPs[smtp] = values;
1226      Log.debug("import: translate relevant SMTP from previous '" + smtp + "' to current '" + relevantSMTPs[smtp].smtp + "'");
1227    }
1228    return relevantSMTPs;
1229  },
1230
1231  _storeMappedSMTPs: function (relevantSMTPs) {
1232    for (var smtp in relevantSMTPs) {
1233      if (relevantSMTPs[smtp].smtp == "import_" + smtp) {
1234        var resource = this._rdfService
1235          .GetResource(this._rdfDataSource._rdfNS + this._rdfDataSource._rdfNSSMTPservers + "/" + relevantSMTPs[smtp].smtp);
1236        this._rdfDataSource._setRDFValue(resource, "label", relevantSMTPs[smtp].label);
1237        this._rdfDataSource._setRDFValue(resource, "hostname", relevantSMTPs[smtp].hostname);
1238        this._rdfDataSource._setRDFValue(resource, "username", relevantSMTPs[smtp].username);
1239
1240        var position = this._rdfDataSource._smtpContainer.IndexOf(resource); // check for index in new recType
1241        if (position != -1) this._rdfDataSource._smtpContainer.InsertElementAt(resource, position, false);
1242        else this._rdfDataSource._smtpContainer.AppendElement(resource);
1243      }
1244    }
1245  },
1246
1247  import: function () {
1248    var filePicker = Components.classes["@mozilla.org/filepicker;1"]
1249      .createInstance(Components.interfaces.nsIFilePicker);
1250
1251    filePicker.init(get3PaneWindow(), "", Components.interfaces.nsIFilePicker.modeOpen);
1252    filePicker.appendFilter("RDF Files", "*.rdf");
1253    filePicker.appendFilters(Components.interfaces.nsIFilePicker.filterText | Components.interfaces.nsIFilePicker.filterAll);
1254
1255    if (this._pickerShow(filePicker) == Components.interfaces.nsIFilePicker.returnOK) {
1256      Log.debug("import: preparation:");
1257
1258      var importRdfDataFile = Components.classes["@mozilla.org/file/local;1"]
1259        .createInstance(Components.interfaces.nsIFile);
1260      var file = Components.classes["@mozilla.org/file/directory_service;1"]
1261        .getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
1262
1263      initWithFilePath_tryDelimiters(importRdfDataFile, file.path, this._rdfFileName + "_import");
1264      filePicker.file.copyTo(importRdfDataFile.parent, importRdfDataFile.leafName);
1265
1266      Log.debug("import: copied file from " + filePicker.file.path + " to " + importRdfDataFile.path + "'");
1267
1268      // init Datasources
1269      this._rdfImportDataSource = new rdfDatasource(this._currentWindow, importRdfDataFile.leafName, true);
1270
1271      // search matching IDs and SMTPs for anyones used in import-file
1272      var relevantIDs = this._translateRelevantIDs();
1273      var relevantSMTPs = this._translateRelevantSMTPs();
1274
1275      Log.debug("import: preparation done.");
1276
1277      for (let treeType of Array("email", "maillist", "newsgroup", "filter")) {
1278        // re-initialize importDataSource to point rdfService to the right Resources
1279        this._rdfImportDataSource = new rdfDatasource(this._currentWindow, importRdfDataFile.leafName, true);
1280        var container = this._rdfImportDataSource.getContainer(treeType)
1281        if (container.GetCount() == 0) continue;
1282        Log.debug("importing " + treeType + ": " + container.GetCount() + " datasets from " + this._rdfImportDataSource._rdfDataSource.URI);
1283        var enumerator = container.GetElements();
1284        // re-initialize dataSource to point rdfService to the right Resources
1285        this._rdfDataSource = new rdfDatasource(this._currentWindow, this._rdfFileName, true);
1286        var count = 0;
1287        while (enumerator.hasMoreElements()) {
1288          var resource = enumerator.getNext();
1289          count += 1;
1290          resource.QueryInterface(Components.interfaces.nsIRDFResource);
1291          //                     Log.debug(" " + count + " ");
1292          var name = this._rdfImportDataSource._getRDFValue(resource, "name")
1293          var email = this._rdfImportDataSource._getRDFValue(resource, "email")
1294          var fullName = this._rdfImportDataSource._getRDFValue(resource, "fullName")
1295          var id = this._rdfImportDataSource._getRDFValue(resource, "id")
1296          id = id ? relevantIDs[id].id : null
1297          var smtp = this._rdfImportDataSource._getRDFValue(resource, "smtp")
1298          smtp = (smtp && smtp != DEFAULT_SMTP_TAG) ? relevantSMTPs[smtp].smtp : smtp
1299          var localIdentityData = new identityData(this._currentWindow, email, fullName, id, smtp,
1300            new identityDataExtras(this._currentWindow, this._rdfImportDataSource, resource))
1301
1302          this._rdfDataSource.updateRDF(name, treeType, localIdentityData, false, false, null, null, true)
1303          var resource = this._rdfDataSource._getRDFResourceForVIdentity(name, treeType);
1304          if (id) this._rdfDataSource._setRDFValue(resource, "id", id); // localIdentityData can only store valid id's, this one might be a temporary invalid id
1305          if (smtp) this._rdfDataSource._setRDFValue(resource, "smtp", smtp); // localIdentityData can only store valid smtp's, this one might be a temporary invalid smtp
1306        }
1307      }
1308
1309      Log.debug("import: removing temporary file " + importRdfDataFile.path);
1310      this._rdfImportDataSource = null;
1311      importRdfDataFile.remove(false);
1312      Log.debug("import: import done.");
1313
1314      Log.debug("import: cleaning ID/SMTP storages:");
1315      this._rdfDataSource = new rdfDatasource(this._currentWindow, this._rdfFileName, true);
1316
1317      this._storeMappedIDs(relevantIDs);
1318      this._rdfDataSource.searchIdentityMismatch();
1319      this._storeMappedSMTPs(relevantSMTPs);
1320      this._rdfDataSource.searchSmtpMismatch();
1321
1322      this._rdfDataSource.refreshAccountInfo();
1323      this._rdfDataSource.clean();
1324      this._rdfDataSource = null;
1325      Log.debug("import: cleaning ID/SMTP storages done.");
1326      Log.debug("IMPORT DONE.");
1327    }
1328  },
1329 
1330  _pickerShow: function (fp) {
1331    let done = false;
1332    let rv, result;
1333    fp.open(result => {
1334      rv = result;
1335      done = true;
1336    });
1337    let thread = Components.classes["@mozilla.org/thread-manager;1"]
1338                          .getService().currentThread;
1339    while (!done) {
1340      thread.processNextEvent(true);
1341    }
1342    return rv;
1343  }
1344}
Note: See TracBrowser for help on using the repository browser.