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

source: modules/vI_rdfDatasource.js @ 7c85ef

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

refer to window if opening dialogs

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