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

source: modules/vI_rdfDatasource.js @ 85fa10

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

removed everything related to smtp-storage

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