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

source: modules/vI_rdfDatasource.js @ cadf2f

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

decreased debugging

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