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

source: modules/vI_rdfDatasource.js @ 12751c

ng_0.9 0.10
Last change on this file since 12751c was 2bdd22, checked in by rene <rene@…>, 4 years ago

fixed broken rdf-import (again)

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