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

source: modules/vI_rdfDatasource.js @ ee0ffd

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

catch problems with file-path - still not really fixed

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