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

source: chrome/content/v_identity/modules/vI_rdfDatasource.js @ 41266a

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

define "drop" as default returnValue

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