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

source: modules/vI_rdfDatasource.js

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

import fix, relevant for 0.10-upgrade

  • Property mode set to 100644
File size: 62.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
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//       Log.debug(" search relevant id: '" + id + "'");
434      var found = false;
435      var accounts = getAccountsArray();
436      var identity = null;
437      for (let acc = 0; acc < accounts.length; acc++) {
438        let account = accounts[acc];
439        let identities = getIdentitiesArray(account);
440        for (let i = 0; i < identities.length; i++) {
441          identity = identities[i];
442//           Log.debug(" compare id: '" + id + "' with '" + identity.key + "'");
443          if (id == identity.key) {
444//             Log.debug(" found!");
445            found = true;
446            break;
447          }
448        }
449        if (found) break;
450      }
451     
452      var resource = this._rdfService.GetResource(this._rdfNS + this._rdfNSIdentities + "/" + id);
453      var rdfIdentityName = this._getRDFValue(resource, "identityName");
454      var rdfEmail = this._getRDFValue(resource, "email");
455      var rdfFullName = this._getRDFValue(resource, "fullName")
456
457      if (!found || rdfIdentityName != identity.identityName && rdfEmail != identity.email) {
458//         Log.debug(" found mismatch on id: '" + id + "' label: " + rdfIdentityName);
459        mismatchIDs.push({
460          oldkey: id,
461          label: rdfIdentityName,
462          ext1: rdfEmail,
463          ext2: rdfFullName,
464          count: relevantIDs[id],
465          key: ""
466        })
467      }
468    }
469    if (mismatchIDs.length > 0) {
470      Log.debug(" found mismatches on id(s).");
471      get3PaneWindow().openDialog("chrome://v_identity/content/vI_rdfAccountMismatchDialog.xul", 0,
472        "chrome, dialog, modal, alwaysRaised, resizable=yes", "identity", mismatchIDs,
473        /* callback chance: */
474        this).focus();
475      return true;
476    } else {
477      Log.debug(" found no mismatch");
478      return false;
479    }
480  },
481
482  repairMismatch: function (type, mismatchItems) {
483    // type might be 'identity' or 'smtp' or 'smtpid' - dependent on trigger
484    for (var i = 0; i < mismatchItems.length; i++) {
485      if (mismatchItems[i].key)
486        Log.debug("repairAccountMismatch change " + mismatchItems[i].oldkey + " into " + mismatchItems[i].key);
487      else
488        Log.debug("repairAccountMismatch remove " + mismatchItems[i].oldkey);
489      // search relevant Identities
490      for (let treeType of Array("email", "maillist", "newsgroup", "filter")) {
491        var enumerator = this.getContainer(treeType).GetElements();
492        while (enumerator && enumerator.hasMoreElements()) {
493          var resource = enumerator.getNext();
494          resource.QueryInterface(Components.interfaces.nsIRDFResource);
495          // old smtp (stored in pre-0.10 rdf) and id have to match, set new id
496          if (type == 'smtpid') {
497            var smtp = mismatchItems[i].oldkey.split("-")[0];
498            var id = mismatchItems[i].oldkey.split("-")[1];
499            if (this._getRDFValue(resource, 'id') == id && this._getRDFValue(resource, 'smtp') == smtp) {
500              if (!mismatchItems[i].key) this._unsetRDFValue(resource, 'id', id)
501              else this._setRDFValue(resource, 'id', mismatchItems[i].key)
502            }
503          }
504          // 'identity' replacement
505          else if (type == 'identity') {
506            if (this._getRDFValue(resource, 'id') == mismatchItems[i].oldkey) {
507              if (!mismatchItems[i].key) this._unsetRDFValue(resource, 'id', mismatchItems[i].oldkey)
508              else this._setRDFValue(resource, 'id', mismatchItems[i].key)
509            }
510          }
511          // 'smtp' replacement
512          else if (type == 'smtp') {
513            if (this._getRDFValue(resource, 'smtp') == mismatchItems[i].oldkey) {
514              if (!mismatchItems[i].key) this._unsetRDFValue(resource, 'smtp', mismatchItems[i].oldkey)
515              else this._setRDFValue(resource, 'smtp', mismatchItems[i].key)
516            }
517          }
518        }
519      }
520    }
521  },
522
523  getRelevantSMTPs: function () {
524    var relevantSMTPs = new Object();
525    // search relevant SMTPs
526    for (let treeType of Array("email", "maillist", "newsgroup", "filter")) {
527      var enumerator = this.getContainer(treeType).GetElements();
528      while (enumerator && enumerator.hasMoreElements()) {
529        var resource = enumerator.getNext();
530        resource.QueryInterface(Components.interfaces.nsIRDFResource);
531        var smtp = this._getRDFValue(resource, "smtp")
532        if (smtp && smtp != DEFAULT_SMTP_TAG) {
533          if (!relevantSMTPs[smtp]) relevantSMTPs[smtp] = 1;
534          else relevantSMTPs[smtp] += 1;
535        }
536      }
537    }
538    return relevantSMTPs;
539  },
540
541  searchSmtpMismatch: function () {
542    Log.debug("searchSmtpMismatch");
543
544    var relevantSMTPs = this.getRelevantSMTPs();
545    var mismatchSMTPs = [];
546
547    for (var smtp in relevantSMTPs) {
548      var servers, smtpService = Components.classes["@mozilla.org/messengercompose/smtp;1"]
549        .getService(Components.interfaces.nsISmtpService);
550      // check for new https://hg.mozilla.org/comm-central/rev/fab9e5145cd4 smtpService
551      if (typeof (smtpService.servers) == "object") servers = smtpService.servers;
552      else servers = smtpService.smtpServers;
553
554      var found = false;
555      while (servers && servers.hasMoreElements()) {
556        var server = servers.getNext();
557        if (server instanceof Components.interfaces.nsISmtpServer &&
558          !server.redirectorType && smtp == server.key) {
559          found = true;
560          break;
561        }
562      }
563      var resource = this._rdfService.GetResource(this._rdfNS + this._rdfNSSMTPservers + "/" + smtp);
564      var rdfSMTPlabel = this._getRDFValue(resource, "label");
565      var rdfHostname = this._getRDFValue(resource, "hostname");
566      var rdfUsername = this._getRDFValue(resource, "username")
567      if (!found || rdfSMTPlabel != (server.description ? server.description : server.hostname) && rdfHostname != server.hostname)
568        mismatchSMTPs.push({
569          oldkey: smtp,
570          label: rdfSMTPlabel,
571          ext1: rdfHostname,
572          ext2: rdfUsername,
573          count: relevantSMTPs[smtp],
574          key: ""
575        })
576    }
577    if (mismatchSMTPs.length > 0) {
578      Log.debug(" found mismatches on smtp(s).");
579      get3PaneWindow().openDialog("chrome://v_identity/content/vI_rdfAccountMismatchDialog.xul", 0,
580        "chrome, dialog, modal, alwaysRaised, resizable=yes", "smtp", mismatchSMTPs,
581        /* callback: */
582        this).focus();
583      return true;
584    } else {
585      Log.debug(" found no mismatch");
586      return false;
587    }
588  },
589
590  storeAccountInfo: function () {
591    Log.debug("rdfDatasource storeAccountInfo");
592    var accounts = getAccountsArray();
593    for (let acc = 0; acc < accounts.length; acc++) {
594      let account = accounts[acc];
595      let identities = getIdentitiesArray(account);
596      for (let i = 0; i < identities.length; i++) {
597        let identity = identities[i];
598        //                 Log.debug("storeAccounts identity store id " + identity.key);
599
600        var resource = this._rdfService.GetResource(this._rdfNS + this._rdfNSIdentities + "/" + identity.key);
601        this._setRDFValue(resource, "identityName", identity.identityName);
602        this._setRDFValue(resource, "fullName", identity.fullName);
603        this._setRDFValue(resource, "email", identity.email);
604        if (identity.smtpServerKey)
605          this._setRDFValue(resource, "smtp", identity.smtpServerKey);
606        else
607          this._setRDFValue(resource, "smtp", DEFAULT_SMTP_TAG);
608       
609//         Log.debug("id:'" + identity.key +"', identityName='" + identity.identityName + "',
610//              fullName='" + identity.fullName + "', email='" + identity.email);
611
612        var position = this._identityContainer.IndexOf(resource); // check for index in new recType
613        if (position != -1) this._identityContainer.InsertElementAt(resource, position, false);
614        else this._identityContainer.AppendElement(resource);
615      }
616    }
617
618    function storeSmtp(server, parent) {
619      //             Log.debug("storeAccounts smtp store id " + server.key);
620      var resource = parent._rdfService.GetResource(parent._rdfNS + parent._rdfNSSMTPservers + "/" + server.key);
621      parent._setRDFValue(resource, "label", (server.description ? server.description : server.hostname));
622      parent._setRDFValue(resource, "hostname", server.hostname);
623      parent._setRDFValue(resource, "username", server.username);
624      var position = parent._smtpContainer.IndexOf(resource); // check for index in new recType
625      if (position != -1) parent._smtpContainer.InsertElementAt(resource, position, false);
626      else parent._smtpContainer.AppendElement(resource);
627    }
628
629    var servers, smtpService = Components.classes["@mozilla.org/messengercompose/smtp;1"]
630      .getService(Components.interfaces.nsISmtpService);
631    // check for new https://hg.mozilla.org/comm-central/rev/fab9e5145cd4 smtpService
632    if (typeof (smtpService.servers) == "object") servers = smtpService.servers;
633    else servers = smtpService.smtpServers;
634
635    while (servers && servers.hasMoreElements()) {
636      var server = servers.getNext();
637      if (server instanceof Components.interfaces.nsISmtpServer && !server.redirectorType) storeSmtp(server, this);
638    }
639
640    //         Log.debug("storeAccounts done");
641  },
642
643  export: function (rdfFileName) {
644    Log.debug("vI_rdfDatasource export: " + rdfFileName + "\n");
645    var filePicker = Components.classes["@mozilla.org/filepicker;1"]
646      .createInstance(Components.interfaces.nsIFilePicker);
647    filePicker.init(get3PaneWindow(), "", Components.interfaces.nsIFilePicker.modeSave);
648    filePicker.appendFilters(Components.interfaces.nsIFilePicker.filterAll | Components.interfaces.nsIFilePicker.filterText);
649    filePicker.appendFilter("RDF Files", "*.rdf");
650
651    if (this._pickerShow(filePicker) != Components.interfaces.nsIFilePicker.returnCancel) {
652      var rdfDataFile = Components.classes["@mozilla.org/file/local;1"]
653        .createInstance(Components.interfaces.nsIFile);
654      var file = Components.classes["@mozilla.org/file/directory_service;1"]
655        .getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
656
657      initWithFilePath_tryDelimiters(rdfDataFile, file.path, rdfFileName);
658      rdfDataFile.copyTo(filePicker.file.parent, filePicker.file.leafName);
659    }
660  },
661
662  _pickerShow: function (fp) {
663    let done = false;
664    let rv, result;
665    fp.open(result => {
666      rv = result;
667      done = true;
668    });
669    let thread = Components.classes["@mozilla.org/thread-manager;1"]
670                          .getService().currentThread;
671    while (!done) {
672      thread.processNextEvent(true);
673    }
674    return rv;
675  },
676 
677  _getRDFResourceForVIdentity: function (recDescription, recType) {
678    if (!this._rdfDataSource) return null;
679    if (!recDescription) {
680      Log.debug("_getRDFResourceForVIdentity: no Recipient given.");
681      return null;
682    }
683    var _rdfNSRecType = null
684    switch (recType) {
685    case "email":
686      _rdfNSRecType = this._rdfNSEmail;
687      break;
688    case "newsgroup":
689      _rdfNSRecType = this._rdfNSNewsgroup;
690      break;
691    case "maillist":
692      _rdfNSRecType = this._rdfNSMaillist;
693      break;
694    case "filter":
695      _rdfNSRecType = this._rdfNSFilter;
696      break;
697    }
698    return this._rdfService.GetResource(this._rdfNS + _rdfNSRecType + "/" + recDescription);
699
700
701  },
702
703  removeVIdentityFromRDF: function (resource, recType) {
704    //      Log.debug("removeVIdentityFromRDF " + resource.ValueUTF8);
705    this._unsetRDFValue(resource, "email", this._getRDFValue(resource, "email"))
706    this._unsetRDFValue(resource, "fullName", this._getRDFValue(resource, "fullName"))
707    this._unsetRDFValue(resource, "id", this._getRDFValue(resource, "id"))
708    this._unsetRDFValue(resource, "name", this._getRDFValue(resource, "name"))
709
710    let self = this;
711    var extras = new identityDataExtras(this._currentWindow, self, resource)
712    extras.loopThroughExtras(
713      function (extra) {
714        extra.value = self._unsetRDFValue(resource, extra.field, extra.value)
715      });
716
717    this.getContainer(recType).RemoveElement(resource, true);
718  },
719
720  _unsetRDFValue: function (resource, field, value) {
721    //      Log.debug("_unsetRDFValue " + this._rdfService  + " " + this._rdfDataSource);
722    var predicate = this._rdfService.GetResource(this._rdfNS + "rdf#" + field);
723    var name = this._rdfService.GetLiteral(value ? value : "");
724    var target = this._rdfDataSource.GetTarget(resource, predicate, true);
725    if (target instanceof Components.interfaces.nsIRDFLiteral) {
726      this._rdfDataSource.Unassert(resource, predicate, name, true);
727      return null;
728    } else return value;
729  },
730
731  // this will be used from rdfDataTree to get all RDF values, callFunction is vI.rdfDataTreeCollection.__addNewDatum
732  readAllEntriesFromRDF: function (addNewDatum, treeType, idData) {
733    //      Log.debug("readAllEntriesFromRDF " + this._rdfService  + " " + this._rdfDataSource + " " + this);
734    var enumerator = this.getContainer(treeType).GetElements();
735    while (enumerator && enumerator.hasMoreElements()) {
736      var resource = enumerator.getNext();
737      resource.QueryInterface(Components.interfaces.nsIRDFResource);
738      var name = this._getRDFValue(resource, "name")
739      var email = this._getRDFValue(resource, "email")
740      var fullName = this._getRDFValue(resource, "fullName")
741      var id = this._getRDFValue(resource, "id")
742      var used = this._getRDFValue(resource, "timeUsed")
743      var changed = this._getRDFValue(resource, "timeChanged")
744      let self = this;
745      var localIdentityData = new identityData(this._currentWindow, email, fullName, id,
746        new identityDataExtras(this._currentWindow, self, resource))
747      addNewDatum(resource, name, localIdentityData, idData, used, changed)
748    }
749  },
750
751  __getDescriptionAndType: function (recipient, recipientType) {
752    if (recipientType == "addr_newsgroups") {
753      return {
754        recDesc: recipient,
755        recType: "newsgroup"
756      }
757    } else if (this.__isMailingList(recipient)) {
758      Log.debug("__getDescriptionAndType: '" + recipient + "' is MailList");
759      return {
760        recDesc: this.__getMailListName(recipient),
761        recType: "maillist"
762      }
763    } else {
764      Log.debug("__getDescriptionAndType: '" + recipient + "' is no MailList");
765      var localIdentityData = new identityData(this._currentWindow, recipient, null, null, null, null, null);
766      return {
767        recDesc: localIdentityData.combinedName,
768        recType: "email"
769      }
770    }
771  },
772
773  // --------------------------------------------------------------------
774  // check if recipient is a mailing list.
775  // Similiar to Thunderbird, if there are muliple cards with the same displayName the mailinglist is preferred
776  // see also https://bugzilla.mozilla.org/show_bug.cgi?id=408575
777  __isMailingList: function (recipient) {
778    let abManager = Components.classes["@mozilla.org/abmanager;1"]
779      .getService(Components.interfaces.nsIAbManager);
780    let allAddressBooks = abManager.directories;
781    while (allAddressBooks.hasMoreElements()) {
782      let ab = allAddressBooks.getNext();
783      if (ab instanceof Components.interfaces.nsIAbDirectory && !ab.isRemote) {
784        let abdirectory = abManager.getDirectory(ab.URI +
785          "?(and(DisplayName,=," + encodeURIComponent(this.__getMailListName(recipient)) + ")(IsMailList,=,TRUE))");
786        if (abdirectory) {
787          try { // just try, sometimes there are no childCards at all...
788            let cards = abdirectory.childCards;
789            if (cards.hasMoreElements()) return true; // only interested if there is at least one element...
790          } catch (e) {}
791        }
792      }
793    }
794    return false;
795  },
796
797  // --------------------------------------------------------------------
798
799  __getMailListName: function (recipient) {
800    if (recipient.match(/<[^>]*>/) || recipient.match(/$/)) {
801      var mailListName = RegExp.leftContext + RegExp.rightContext
802      mailListName = mailListName.replace(/^\s+|\s+$/g, "")
803    }
804    return mailListName;
805  },
806
807  findMatchingFilter: function (recipient, recipientType) {
808    var recDescription = this.__getDescriptionAndType(recipient, recipientType).recDesc;
809    Log.debug("findMatchingFilter for " + recDescription);
810    var enumerator = this._filterContainer.GetElements();
811    while (enumerator && enumerator.hasMoreElements()) {
812      var resource = enumerator.getNext();
813      resource.QueryInterface(Components.interfaces.nsIRDFResource);
814      var filter = this._getRDFValue(resource, "name");
815
816      const filterType = {
817        None: 0,
818        RegExp: 1,
819        StrCmp: 2
820      }
821      var recentfilterType;
822
823      if (filter == "") continue;
824      if (/^\/(.*)\/$/.exec(filter)) {
825        Log.debug("findMatchingFilter with RegExp '" + filter.replace(/\\/g, "\\\\") + "'");
826        recentfilterType = filterType.RegExp;
827      } else {
828        Log.debug("findMatchingFilter, compare with '" + filter + "'");
829        recentfilterType = filterType.StrCmp;
830      }
831
832      switch (recentfilterType) {
833      case filterType.RegExp:
834        try {
835          /^\/(.*)\/$/.exec(filter);
836          if (recDescription.match(new RegExp(RegExp.$1, "i"))) {
837            Log.debug("findMatchingFilter found stored data.");
838            return this._readVIdentityFromRDF(resource);
839          }
840        } catch (vErr) {};
841        break;
842      case filterType.StrCmp:
843        if (recDescription.toLowerCase().indexOf(filter.toLowerCase()) != -1) {
844          Log.debug("findMatchingFilter found stored data.");
845          return this._readVIdentityFromRDF(resource);
846        }
847        break;
848      }
849    }
850    Log.debug("findMatchingFilter no match found.");
851    return null;
852  },
853
854  readVIdentityFromRDF: function (recipient, recipientType) {
855    var storedRecipient = this.__getDescriptionAndType(recipient, recipientType);
856    var email = this._rdfService.GetResource(this._rdfNS + "rdf#email");
857    var resource = this._getRDFResourceForVIdentity(storedRecipient.recDesc, storedRecipient.recType);
858    if (!resource) return null;
859    if (!this._rdfDataSource.hasArcOut(resource, email)) {
860      // no data available --> give up.
861      Log.debug("readVIdentityFromRDF no data found.");
862      return null;
863    }
864    Log.debug("readVIdentityFromRDF found stored data.");
865
866    return this._readVIdentityFromRDF(resource);
867  },
868
869  _readVIdentityFromRDF: function (resource) {
870    var email = this._getRDFValue(resource, "email")
871    var fullName = this._getRDFValue(resource, "fullName")
872    var id = this._getRDFValue(resource, "id")
873
874    let _date = new Date();
875    this._setRDFValue(resource, "timeUsed", _date.getTime());
876
877    Log.debug("email='" + email +
878      "' fullName='" + fullName + "' id='" + id + "'");
879
880    let self = this;
881    var localIdentityData = new identityData(this._currentWindow, email, fullName, id,
882      new identityDataExtras(this._currentWindow, self, resource))
883    return localIdentityData;
884  },
885
886  _getRDFValue: function (resource, field) {
887    //         Log.debug("_getRDFValue " + this._rdfService  + " " + this._rdfDataSource + " " + this);
888    var predicate = this._rdfService.GetResource(this._rdfNS + "rdf#" + field);
889    var target = this._rdfDataSource.GetTarget(resource, predicate, true);
890    if (target instanceof Components.interfaces.nsIRDFLiteral) return target.Value
891    else return null;
892  },
893
894  updateRDFFromVIdentity: function (identityData, recipientName, recipientType) {
895    var recipient = this.__getDescriptionAndType(recipientName, recipientType)
896    this.updateRDF(recipient.recDesc, recipient.recType, identityData,
897      vIprefs.get("storage_store_base_id"),
898      null, null, false);
899  },
900
901  removeRDF: function (recDescription, recType) {
902    var resource = this._getRDFResourceForVIdentity(recDescription, recType);
903    if (!resource) return null;
904    this.removeVIdentityFromRDF(resource, recType);
905    return resource;
906  },
907
908  updateRDF: function (recDescription, recType, localIdentityData, storeBaseID, prevRecDescription, prevRecType, updateAllExtras) {
909    //         Log.debug("(" + this._rdfNS + "): updateRDF recDescription=" + recDescription + " localIdentityData.email=" + localIdentityData.email);
910
911    //      if (!localIdentityData.email) {
912    //          Log.debug("updateRDF: no Sender-email for Recipient, aborting.");
913    //          return;
914    //      }
915    if (!recDescription || recDescription.length == 0) return;
916
917    if (!prevRecDescription) prevRecDescription = recDescription;
918    if (!prevRecType) prevRecType = recType;
919
920    var resource = this._getRDFResourceForVIdentity(prevRecDescription, prevRecType);
921    if (!resource) return;
922    //      Log.debug("updateRDF " + resource.ValueUTF8);
923
924    var position = this.getContainer(recType).IndexOf(resource); // check for index in new recType
925    this.removeVIdentityFromRDF(resource, prevRecType);
926
927    resource = this._getRDFResourceForVIdentity(recDescription, recType);
928
929    this._setRDFValue(resource, "email", localIdentityData.email);
930    this._setRDFValue(resource, "fullName", localIdentityData.fullName);
931    if (storeBaseID)
932      this._setRDFValue(resource, "id", localIdentityData.id.key);
933    else this._unsetRDFValue(resource, "id", this._getRDFValue(resource, "id"))
934    this._setRDFValue(resource, "name", recDescription);
935
936    if (localIdentityData.extras) {
937      let self = this;
938      localIdentityData.extras.loopThroughExtras(
939        function (extra) {
940          if (updateAllExtras || extra.active)
941            extra.value = self._setRDFValue(resource, extra.field, extra.value)
942        });
943      //           Log.debug("extras: " + localIdentityData.extras.status());
944    }
945
946    let _date = new Date();
947    this._setRDFValue(resource, "timeChanged", _date.getTime());
948
949    //      Log.debug("updateRDF add " + resource.ValueUTF8 + " at position " + position);
950    if (position != -1) this.getContainer(recType).InsertElementAt(resource, position, true);
951    else this.getContainer(recType).AppendElement(resource);
952  },
953
954  _setRDFValue: function (resource, field, value) {
955    //      Log.debug("_setRDFValue " + resource.ValueUTF8 + " " + field + " " + value);
956    if (!value) return value; // return if some value was not set.
957    //      Log.debug("_setRDFValue " + this._rdfService + " " + this._rdfDataSource);
958    var predicate = this._rdfService.GetResource(this._rdfNS + "rdf#" + field);
959    var name = this._rdfService.GetLiteral(value);
960    var target = this._rdfDataSource.GetTarget(resource, predicate, true);
961
962    if (target instanceof Components.interfaces.nsIRDFLiteral)
963      this._rdfDataSource.Change(resource, predicate, target, name);
964    else this._rdfDataSource.Assert(resource, predicate, name, true);
965    return value;
966  },
967
968  //  code adapted from http://xulsolutions.blogspot.com/2006/07/creating-uninstall-script-for.html
969  AccountManagerObserver: {
970    self: null,
971    _uninstall: false,
972    observe: function (subject, topic, data) {
973      if (topic == "am-smtpChanges" || topic == "am-acceptChanges") {
974        Log.debug("account/smtp changes observed");
975        this.self.searchIdentityMismatch();
976        this.self.refreshAccountInfo();
977      }
978    },
979    register: function (self) {
980      this.self = self;
981      Log.debug("register AccountManagerObserver");
982      var obsService = Components.classes["@mozilla.org/observer-service;1"].
983      getService(Components.interfaces.nsIObserverService)
984      obsService.addObserver(this, "am-smtpChanges", false);
985      obsService.addObserver(this, "am-acceptChanges", false);
986    },
987    unregister: function () {
988      Log.debug("unregister AccountManagerObserver");
989      var obsService = Components.classes["@mozilla.org/observer-service;1"].
990      getService(Components.interfaces.nsIObserverService)
991      try {
992        obsService.removeObserver(this, "am-smtpChanges");
993        obsService.removeObserver(this, "am-acceptChanges");
994      } catch (e) {};
995    }
996  }
997}
998
999
1000function rdfDatasourceAccess(currentWindow) {
1001  this._currentWindow = currentWindow;
1002  this._rdfDataSource = new rdfDatasource(this._currentWindow, "virtualIdentity_0.10.rdf", true);
1003  this.stringBundle = Services.strings.createBundle("chrome://v_identity/locale/v_identity.properties");
1004}
1005
1006rdfDatasourceAccess.prototype = {
1007  _currentWindow: null,
1008  _rdfDataSource: null,
1009  stringBundle: null,
1010
1011  clean: function () {
1012    this._rdfDataSource.clean();
1013  },
1014
1015  updateVIdentityFromStorage: function (recipientName, recipientType, currentIdentity, currentIdentityIsVid, isNotFirstInputElement) {
1016    var localIdentities = new identityCollection();
1017    localIdentities.addWithoutDuplicates(this._rdfDataSource.readVIdentityFromRDF(recipientName, recipientType));
1018    if (localIdentities.number == 1) Log.debug("using data from direct match");
1019    localIdentities.addWithoutDuplicates(this._rdfDataSource.findMatchingFilter(recipientName, recipientType));
1020
1021    var returnValue = {};
1022    returnValue.identityCollection = localIdentities;
1023    returnValue.result = "drop";
1024    if (localIdentities.number == 0) {
1025      Log.debug("updateVIdentityFromStorage no usable Storage-Data found.");
1026    } else {
1027      Log.debug("compare with current Identity");
1028      if (vIprefs.get("storage_getOneOnly") && // if requested to retrieve only storageID for first recipient entered
1029        isNotFirstInputElement && // and it is now not the first recipient entered
1030        !localIdentities.identityDataCollection[0].equalsIdentity(currentIdentity, false).equal) { // and this id is different than the current used one
1031        StorageNotification.info(this.stringBundle.GetStringFromName("vident.smartIdentity.vIStorageCollidingIdentity"));
1032        //                  returnValue.result = "drop";    // this is the default value
1033      }
1034      // only update fields if new Identity is different than old one.
1035      else {
1036        Log.debug("updateVIdentityFromStorage check if storage-data matches current Identity.");
1037        var compResult = localIdentities.identityDataCollection[0].equalsIdentity(currentIdentity, true);
1038        if (!compResult.equal) {
1039          var warning = this.__getWarning("replaceVIdentity", recipientName, compResult.compareMatrix);
1040          if (!currentIdentityIsVid ||
1041            !vIprefs.get("storage_warn_vI_replace") ||
1042            (this.__askWarning(warning) == "accept")) {
1043            returnValue.result = "accept";
1044          }
1045        } else {
1046          returnValue.result = "equal";
1047        }
1048      }
1049    }
1050    return returnValue;
1051  },
1052
1053  storeVIdentityToAllRecipients: function (identityData, recipients) {
1054    var multipleRecipients = (recipients.length > 1);
1055    var dontUpdateMultipleNoEqual = (vIprefs.get("storage_dont_update_multiple") && multipleRecipients)
1056    Log.debug("storeVIdentityToAllRecipients dontUpdateMultipleNoEqual='" + dontUpdateMultipleNoEqual + "'")
1057
1058    let returnValue = {
1059      update: "cancel"
1060    };
1061    for (var j = 0; j < recipients.length; j++) {
1062      returnValue = this.__updateStorageFromVIdentity(identityData, recipients[j].recipient, recipients[j].recipientType, dontUpdateMultipleNoEqual);
1063      if (returnValue.update != "accept") break;
1064    }
1065    return returnValue;
1066  },
1067
1068  getVIdentityFromAllRecipients: function (allIdentities, recipients) {
1069    if (!vIprefs.get("storage")) {
1070      Log.debug("Storage deactivated");
1071      return;
1072    }
1073    var initnumber = allIdentities.number;
1074    for (var j = 0; j < recipients.length; j++) {
1075      allIdentities.addWithoutDuplicates(this._rdfDataSource.readVIdentityFromRDF(recipients[j].recipient, recipients[j].recipientType));
1076      allIdentities.addWithoutDuplicates(this._rdfDataSource.findMatchingFilter(recipients[j].recipient, recipients[j].recipientType));
1077    }
1078    Log.debug("found " + (allIdentities.number - initnumber) + " address(es)")
1079  },
1080
1081  __updateStorageFromVIdentity: function (identityData, recipient, recipientType, dontUpdateMultipleNoEqual) {
1082    Log.debug("__updateStorageFromVIdentity.")
1083    var storageDataByType = this._rdfDataSource.readVIdentityFromRDF(recipient, recipientType);
1084    var storageDataByFilter = this._rdfDataSource.findMatchingFilter(recipient, recipientType);
1085
1086    // update (storing) of data by type is required if there is
1087    // no data stored by type (or different data stored) and no equal filter found
1088    var storageDataByTypeCompResult = storageDataByType ? storageDataByType.equalsIdentity(identityData, true) : null;
1089    var storageDataByTypeEqual = (storageDataByType && storageDataByTypeCompResult.equal);
1090    var storageDataByFilterEqual = (storageDataByFilter && storageDataByFilter.equalsIdentity(identityData, false).equal);
1091
1092    var doUpdate = "accept";
1093    if ((!storageDataByType && !storageDataByFilterEqual) ||
1094      (!storageDataByTypeEqual && !storageDataByFilterEqual && !dontUpdateMultipleNoEqual)) {
1095      Log.debug("__updateStorageFromVIdentity updating")
1096      if (storageDataByType && !storageDataByTypeEqual && vIprefs.get("storage_warn_update")) {
1097        Log.debug("__updateStorageFromVIdentity overwrite warning");
1098        doUpdate = this.__askWarning(this.__getWarning("updateStorage", recipient, storageDataByTypeCompResult.compareMatrix));
1099      }
1100    }
1101    if (doUpdate == "accept") this._rdfDataSource.updateRDFFromVIdentity(identityData, recipient, recipientType);
1102    return {
1103      update: doUpdate,
1104      storedIdentity: storageDataByType
1105    };
1106  },
1107
1108  __getWarning: function (warningCase, recipient, compareMatrix) {
1109    var warning = {
1110      title: null,
1111      recLabel: null,
1112      recipient: null,
1113      warning: null,
1114      css: null,
1115      query: null,
1116      class: null
1117    };
1118    warning.title = this.stringBundle.GetStringFromName("vident." + warningCase + ".title")
1119    warning.recLabel = this.stringBundle.GetStringFromName("vident." + warningCase + ".recipient") + ":";
1120    warning.recipient = recipient;
1121    warning.warning =
1122      "<table class='" + warningCase + "'><thead><tr><th class='col1'/>" +
1123      "<th class='col2'>" + this.stringBundle.GetStringFromName("vident." + warningCase + ".currentIdentity") + "</th>" +
1124      "<th class='col3'>" + this.stringBundle.GetStringFromName("vident." + warningCase + ".storedIdentity") + "</th>" +
1125      "</tr></thead>" +
1126      "<tbody>" + compareMatrix + "</tbody>" +
1127      "</table>"
1128    warning.css = "vI.DialogBrowser.css";
1129    warning.query = this.stringBundle.GetStringFromName("vident." + warningCase + ".query");
1130    warning.class = warningCase;
1131    return warning;
1132  },
1133
1134  __askWarning: function (warning) {
1135    var retVar = {
1136      returnValue: null
1137    };
1138    var answer = this._currentWindow.openDialog("chrome://v_identity/content/vI_Dialog.xul", "",
1139      "chrome, dialog, modal, alwaysRaised, resizable=yes",
1140      warning, retVar)
1141    Log.debug("retVar.returnValue=" + retVar.returnValue)
1142    return retVar.returnValue;
1143  },
1144}
1145
1146
1147// create with name of the file to import into
1148function rdfDatasourceImporter(currentWindow, rdfFileName, importNow = true) {
1149  this._currentWindow = currentWindow;
1150  this._rdfFileName = rdfFileName;
1151  if (importNow && this._rdfFileName) this.import();
1152}
1153
1154rdfDatasourceImporter.prototype = {
1155  _currentWindow: null,
1156  _rdfService: Components.classes["@mozilla.org/rdf/rdf-service;1"]
1157    .getService(Components.interfaces.nsIRDFService),
1158  _rdfDataSource: null,
1159  _rdfFileName: null,
1160  _rdfImportDataSource: null,
1161
1162  _getMatchingIdentity: function (name, email, fullName) {
1163    var accounts = getAccountsArray();
1164    for (let acc = 0; acc < accounts.length; acc++) {
1165      let account = accounts[acc];
1166      let identities = getIdentitiesArray(account);
1167      for (let i = 0; i < identities.length; i++) {
1168        let identity = identities[i];
1169        if (name == identity.identityName || (fullName == identity.fullName && email == identity.email)) return identity.key;
1170      }
1171    }
1172    return null;
1173  },
1174
1175  _getMatchingSMTP: function (label, hostname, username) {
1176    var servers, smtpService = Components.classes["@mozilla.org/messengercompose/smtp;1"]
1177      .getService(Components.interfaces.nsISmtpService);
1178    // check for new https://hg.mozilla.org/comm-central/rev/fab9e5145cd4 smtpService
1179    if (typeof (smtpService.servers) == "object") servers = smtpService.servers;
1180    else servers = smtpService.smtpServers;
1181
1182//     Log.debug("searching for label='" + label + "' hostname='" + hostname + "' username='" + username + "'");
1183    while (servers && servers.hasMoreElements()) {
1184      var server = servers.getNext();
1185      if (server instanceof Components.interfaces.nsISmtpServer && !server.redirectorType) {
1186//         Log.debug("comparing with for description='" + server.description + "' hostname='" +
1187//               server.hostname + "' username='" + server.username + "'");
1188        if (label == (server.description ? server.description : server.hostname) && (hostname == server.hostname && username == server.username))
1189          return server.key;
1190      }
1191    }
1192    return null;
1193  },
1194
1195  _translateRelevantIDs: function () {
1196    var relevantIDs = this._rdfImportDataSource.getRelevantIDs();
1197    for (var id in relevantIDs) {
1198      var resource = this._rdfService.GetResource(this._rdfImportDataSource._rdfNS + this._rdfImportDataSource._rdfNSIdentities + "/" + id);
1199      var values = {
1200        id: null,
1201        identityName: null,
1202        email: null,
1203        fullName: null
1204      }
1205      values.identityName = this._rdfImportDataSource._getRDFValue(resource, "identityName");
1206      values.email = this._rdfImportDataSource._getRDFValue(resource, "email");
1207      values.fullName = this._rdfImportDataSource._getRDFValue(resource, "fullName");
1208      values.id = this._getMatchingIdentity(values.identityName, values.email, values.fullName);
1209      values.id = values.id ? values.id : "import_" + id
1210      relevantIDs[id] = values;
1211      Log.debug("import: translate relevant ID from previous '" + id + "' to current '" + relevantIDs[id].id + "'");
1212    }
1213    return relevantIDs;
1214  },
1215
1216  _storeMappedIDs: function (relevantIDs) {
1217    for (var id in relevantIDs) {
1218      if (relevantIDs[id].id == "import_" + id) {
1219        var resource = this._rdfService
1220          .GetResource(this._rdfDataSource._rdfNS + this._rdfDataSource._rdfNSIdentities + "/" + relevantIDs[id].id);
1221        this._rdfDataSource._setRDFValue(resource, "identityName", relevantIDs[id].identityName);
1222        this._rdfDataSource._setRDFValue(resource, "fullName", relevantIDs[id].fullName);
1223        this._rdfDataSource._setRDFValue(resource, "email", relevantIDs[id].email);
1224
1225        var position = this._rdfDataSource._identityContainer.IndexOf(resource); // check for index in new recType
1226        if (position != -1) this._rdfDataSource._identityContainer.InsertElementAt(resource, position, false);
1227        else this._rdfDataSource._identityContainer.AppendElement(resource);
1228      }
1229    }
1230  },
1231
1232  //--------------------------------------------------------------------------------------------------------
1233  //only required for update from pre 0.10 versions
1234
1235  _translateRelevantSMTPs: function () {
1236    var relevantSMTPs = this._rdfImportDataSource.getRelevantSMTPs();
1237    for (var smtp in relevantSMTPs) {
1238      var resource = this._rdfService.GetResource(this._rdfImportDataSource._rdfNS + this._rdfImportDataSource._rdfNSSMTPservers + "/" + smtp);
1239      var values = {
1240        smtp: null,
1241        label: null,
1242        hostname: null,
1243        username: null
1244      }
1245      values.label = this._rdfImportDataSource._getRDFValue(resource, "label");
1246      values.hostname = this._rdfImportDataSource._getRDFValue(resource, "hostname");
1247      values.username = this._rdfImportDataSource._getRDFValue(resource, "username");
1248      values.smtp = this._getMatchingSMTP(values.label, values.hostname, values.username);
1249      values.smtp = values.smtp ? values.smtp : "import_" + smtp;
1250      relevantSMTPs[smtp] = values;
1251      Log.debug("import: translate relevant SMTP from previous '" + smtp + "' to current '" + relevantSMTPs[smtp].smtp + "'");
1252    }
1253    return relevantSMTPs;
1254  },
1255
1256  _storeMappedSMTPs: function (relevantSMTPs) {
1257    for (var smtp in relevantSMTPs) {
1258      if (relevantSMTPs[smtp].smtp == "import_" + smtp) {
1259        var resource = this._rdfService
1260          .GetResource(this._rdfDataSource._rdfNS + this._rdfDataSource._rdfNSSMTPservers + "/" + relevantSMTPs[smtp].smtp);
1261        this._rdfDataSource._setRDFValue(resource, "label", relevantSMTPs[smtp].label);
1262        this._rdfDataSource._setRDFValue(resource, "hostname", relevantSMTPs[smtp].hostname);
1263        this._rdfDataSource._setRDFValue(resource, "username", relevantSMTPs[smtp].username);
1264
1265        var position = this._rdfDataSource._smtpContainer.IndexOf(resource); // check for index in new recType
1266        if (position != -1) this._rdfDataSource._smtpContainer.InsertElementAt(resource, position, false);
1267        else this._rdfDataSource._smtpContainer.AppendElement(resource);
1268      }
1269    }
1270  },
1271
1272  _rdfNSSMTPservers: "vIAccounts/smtp",
1273
1274  _getSMTPIDCombinations: function () {
1275    var SMTPIDCombinations = new Object();
1276    var AccountManager = Components.classes["@mozilla.org/messenger/account-manager;1"]
1277              .getService(Components.interfaces.nsIMsgAccountManager);
1278    // search relevant SMTPs
1279    for (let treeType of Array("email", "maillist", "newsgroup", "filter")) {
1280      var enumerator = this._rdfDataSource.getContainer(treeType).GetElements();
1281      while (enumerator && enumerator.hasMoreElements()) {
1282        var resource = enumerator.getNext();
1283        resource.QueryInterface(Components.interfaces.nsIRDFResource);
1284        var smtp = this._rdfDataSource._getRDFValue(resource, "smtp")
1285        if (smtp) {
1286          var id = this._rdfDataSource._getRDFValue(resource, "id")
1287          if (id) {
1288            if (!SMTPIDCombinations[smtp + "-" + id]) SMTPIDCombinations[smtp + "-" + id] = 1;
1289            else SMTPIDCombinations[smtp + "-" + id] += 1;
1290          }
1291        }
1292      }
1293    }
1294    return SMTPIDCombinations;
1295  },
1296
1297  _searchSmtpIdMismatch: function () {
1298    Log.debug("searchSmtpIdMismatch (only relevant for pre-0.10 rdf files)");
1299    var AccountManager = Components.classes["@mozilla.org/messenger/account-manager;1"]
1300              .getService(Components.interfaces.nsIMsgAccountManager);
1301
1302    var relevantSMTPs = this._getSMTPIDCombinations();
1303    var SMTPIDCombinations = [];
1304
1305    for (var smtpid in relevantSMTPs) {
1306      var smtp = smtpid.split("-")[0];
1307      var id = smtpid.split("-")[1];
1308
1309      Log.debug("search combination smtp=" + smtp + " id=" + id + " smtp(id)=" + AccountManager.getIdentity(id).smtpServerKey);
1310     
1311      var id_smtp = AccountManager.getIdentity(id).smtpServerKey;
1312      if (!id_smtp)
1313        id_smtp = DEFAULT_SMTP_TAG;
1314     
1315      if (smtp == id_smtp)
1316          break;
1317
1318      var resource = this._rdfDataSource._rdfService.GetResource(this._rdfDataSource._rdfNS + this._rdfNSSMTPservers + "/" + smtp);
1319      var rdfSMTPlabel = this._rdfDataSource._getRDFValue(resource, "label");
1320
1321      var servers = MailServices.smtp.servers;
1322
1323      var smtpName;
1324      while (servers && servers.hasMoreElements()) {
1325        var server = servers.getNext();
1326        if (server instanceof Components.interfaces.nsISmtpServer &&
1327          !server.redirectorType && id_smtp == server.key) {
1328          smtpName = server.description ? server.description : server.hostname;
1329          break;
1330        }
1331      }
1332
1333      SMTPIDCombinations.push({
1334        oldkey: smtpid,
1335        label: rdfSMTPlabel,
1336        ext1: AccountManager.getIdentity(id).identityName,
1337        ext2: smtpName,
1338        count: relevantSMTPs[smtpid],
1339        key: ""
1340      })
1341    }
1342    if (SMTPIDCombinations.length > 0) {
1343      Log.debug(" found mismatches on smtpid(s).");
1344      get3PaneWindow().openDialog("chrome://v_identity/content/vI_rdfAccountMismatchDialog.xul", 0,
1345        "chrome, dialog, modal, alwaysRaised, resizable=yes", "smtpid", SMTPIDCombinations,
1346        /* callback: */
1347        this._rdfDataSource).focus();
1348      return true;
1349    } else {
1350      Log.debug(" found no mismatch");
1351      return false;
1352    }
1353  },
1354
1355  _removeSMTPEntries: function () {
1356    // search and remove all smtp-entries
1357    for (let treeType of Array("email", "maillist", "newsgroup", "filter")) {
1358      var enumerator = this._rdfDataSource.getContainer(treeType).GetElements();
1359      while (enumerator && enumerator.hasMoreElements()) {
1360        var resource = enumerator.getNext();
1361        this._rdfDataSource._unsetRDFValue(resource, 'smtp', this._rdfDataSource._getRDFValue(resource, 'smtp'))
1362      }
1363    }
1364  },
1365  //--------------------------------------------------------------------------------------------------------
1366 
1367  import: function () {
1368    var filePicker = Components.classes["@mozilla.org/filepicker;1"]
1369      .createInstance(Components.interfaces.nsIFilePicker);
1370
1371    filePicker.init(get3PaneWindow(), "", Components.interfaces.nsIFilePicker.modeOpen);
1372    filePicker.appendFilter("RDF Files", "*.rdf");
1373    filePicker.appendFilters(Components.interfaces.nsIFilePicker.filterText | Components.interfaces.nsIFilePicker.filterAll);
1374
1375    if (this._pickerShow(filePicker) == Components.interfaces.nsIFilePicker.returnOK)
1376      this._importFile(filePicker.file);
1377  },
1378
1379  importFileByName: function (fileName) {
1380    var newFile = Components.classes["@mozilla.org/file/local;1"]
1381      .createInstance(Components.interfaces.nsIFile);
1382
1383    var file = Components.classes["@mozilla.org/file/directory_service;1"]
1384      .getService(Components.interfaces.nsIProperties)
1385      .get("ProfD", Components.interfaces.nsIFile);
1386
1387    initWithFilePath_tryDelimiters(newFile, file.path, fileName);
1388
1389    this._importFile(newFile);
1390  },
1391
1392  _importFile: function (file) {
1393    if (!file.exists() || !file.isFile() || !file.isReadable()) {
1394      Log.debug("rdfDatasourceImporter _importFile: " + file.path + " not found / not readable");
1395      return;
1396    }
1397
1398    Log.debug("import: preparation:");
1399    var importRdfDataFile = Components.classes["@mozilla.org/file/local;1"]
1400      .createInstance(Components.interfaces.nsIFile);
1401    var tmpfile = Components.classes["@mozilla.org/file/directory_service;1"]
1402      .getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
1403
1404    initWithFilePath_tryDelimiters(importRdfDataFile, tmpfile.path, this._rdfFileName + "_import");
1405    file.copyTo(importRdfDataFile.parent, importRdfDataFile.leafName);
1406
1407    Log.debug("import: copied file from " + file.path + " to " + importRdfDataFile.path + "'");
1408
1409    // init Datasources
1410    this._rdfImportDataSource = new rdfDatasource(this._currentWindow, importRdfDataFile.leafName, true, true);
1411
1412    // search matching IDs for anyones used in import-file
1413    var relevantIDs = this._translateRelevantIDs();
1414    var relevantSMTPs = this._translateRelevantSMTPs();
1415
1416    Log.debug("import: preparation done.");
1417
1418    for (let treeType of Array("email", "maillist", "newsgroup", "filter")) {
1419      // re-initialize importDataSource to point rdfService to the right Resources
1420      this._rdfImportDataSource = new rdfDatasource(this._currentWindow, importRdfDataFile.leafName, true, true);
1421      var container = this._rdfImportDataSource.getContainer(treeType)
1422      if (container.GetCount() == 0) continue;
1423      Log.debug("importing " + treeType + ": " + container.GetCount() + " datasets from " + this._rdfImportDataSource._rdfDataSource.URI);
1424      var enumerator = container.GetElements();
1425      // re-initialize dataSource to point rdfService to the right Resources
1426      this._rdfDataSource = new rdfDatasource(this._currentWindow, this._rdfFileName, true);
1427      var count = 0;
1428      while (enumerator.hasMoreElements()) {
1429        var resource = enumerator.getNext();
1430        count += 1;
1431        resource.QueryInterface(Components.interfaces.nsIRDFResource);
1432        //                     Log.debug(" " + count + " ");
1433        var name = this._rdfImportDataSource._getRDFValue(resource, "name")
1434        var email = this._rdfImportDataSource._getRDFValue(resource, "email")
1435        var fullName = this._rdfImportDataSource._getRDFValue(resource, "fullName")
1436        var id = this._rdfImportDataSource._getRDFValue(resource, "id")
1437       
1438        id = id ? relevantIDs[id].id : null
1439    var smtp = this._rdfImportDataSource._getRDFValue(resource, "smtp")
1440        smtp = (smtp && smtp != DEFAULT_SMTP_TAG) ? relevantSMTPs[smtp].smtp : smtp
1441         
1442        var localIdentityData = new identityData(this._currentWindow, email, fullName, id,
1443          new identityDataExtras(this._currentWindow, this._rdfImportDataSource, resource))
1444
1445        this._rdfDataSource.updateRDF(name, treeType, localIdentityData, false, null, null, true)
1446        var resource = this._rdfDataSource._getRDFResourceForVIdentity(name, treeType);
1447        if (id) this._rdfDataSource._setRDFValue(resource, "id", id); // localIdentityData can only store valid id's, this one might be a temporary invalid id
1448        if (smtp) this._rdfDataSource._setRDFValue(resource, "smtp", smtp); // localIdentityData can only store valid smtp's, this one might be a temporary invalid smtp
1449      }
1450    }
1451
1452    Log.debug("import: removing temporary file " + importRdfDataFile.path);
1453    this._rdfImportDataSource = null;
1454    importRdfDataFile.remove(false);
1455    Log.debug("import: import done.");
1456
1457    Log.debug("import: cleaning ID storages:");
1458   
1459    this._storeMappedIDs(relevantIDs);
1460    this._rdfDataSource.searchIdentityMismatch();
1461    this._storeMappedSMTPs(relevantSMTPs);
1462    this._rdfDataSource.searchSmtpMismatch();
1463
1464    // extension from version 0.10 on does not use any extra SMTP information anymore
1465    // and uses the SMTP-server from base identity instead.
1466    // check if any collisions between previously stored SMTP and base identity exists and solve this.
1467    Log.debug("import: search SMTP-ID mismatches");
1468    this._searchSmtpIdMismatch();
1469   
1470    this._removeSMTPEntries();
1471
1472    this._rdfDataSource.refreshAccountInfo();
1473    this._rdfDataSource.clean();
1474    this._rdfDataSource = null;
1475    Log.debug("import: cleaning ID storages done.");
1476    Log.debug("IMPORT DONE.");
1477  },
1478 
1479  _pickerShow: function (fp) {
1480    let done = false;
1481    let rv, result;
1482    fp.open(result => {
1483      rv = result;
1484      done = true;
1485    });
1486    let thread = Components.classes["@mozilla.org/thread-manager;1"]
1487                          .getService().currentThread;
1488    while (!done) {
1489      thread.processNextEvent(true);
1490    }
1491    return rv;
1492  }
1493}
Note: See TracBrowser for help on using the repository browser.