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

source: modules/vI_rdfDatasource.js @ 71a4b1

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

fix the delimiter issue (again:)

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