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

source: modules/vI_rdfDatasource.js @ 509348

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

code formatting (no code changes)

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