Fix
bug 591744 - All calendars and events lost after restart [Error: Timezone Service not initialized]. r=nomisvai
--- a/calendar/base/src/calTimezoneService.js
+++ b/calendar/base/src/calTimezoneService.js
@@ -157,144 +157,127 @@ calTimezoneService.prototype = {
let ret = Components.classes["@mozilla.org/storage/statement-wrapper;1"]
.createInstance(Components.interfaces.mozIStorageStatementWrapper);
ret.initialize(statement);
return ret;
},
// nsIStartupService
startup: function startup(aCompleteListener) {
- this.initialize(aCompleteListener);
+ this.ensureInitialized(aCompleteListener);
},
shutdown: function shutdown(aCompleteListener) {
Services.prefs.removeObserver("calendar.timezone.local", this);
try {
this.mDb.close();
this.mDb = null;
} catch (e) {
cal.ERROR("Error closing timezone database: " + e);
}
aCompleteListener.onResult(null, Components.results.NS_OK);
},
- ensureInitialized: function() {
+ ensureInitialized: function(aCompleteListener) {
if (!this.mSelectByTzid) {
- cal.ERROR("Calling Timezone Service before its initialized!\nStack: " + cal.STACK(10));
- throw Components.results.NS_ERROR_NOT_INITIALIZED;
+ this.initialize(aCompleteListener);
}
},
_initDB: function _initDB(sqlTzFile) {
try {
- sqlTzFile.append("timezones.sqlite");
cal.LOG("[calTimezoneService] using " + sqlTzFile.path);
let dbService = Components.classes["@mozilla.org/storage/service;1"]
.getService(Components.interfaces.mozIStorageService);
this.mDb = dbService.openDatabase(sqlTzFile);
- this.mSelectByTzid = this.createStatement("SELECT * FROM tz_data WHERE tzid = :tzid LIMIT 1");
+ if (this.mDb) {
+ this.mSelectByTzid = this.createStatement("SELECT * FROM tz_data WHERE tzid = :tzid LIMIT 1");
- let selectVersion = this.createStatement("SELECT version FROM tz_version LIMIT 1");
- try {
- if (selectVersion.step()) {
- this.mVersion = selectVersion.row.version;
+ let selectVersion = this.createStatement("SELECT version FROM tz_version LIMIT 1");
+ try {
+ if (selectVersion.step()) {
+ this.mVersion = selectVersion.row.version;
+ }
+ } finally {
+ selectVersion.reset();
}
- } finally {
- selectVersion.reset();
+ cal.LOG("[calTimezoneService] timezones version: " + this.mVersion);
+ return true;
}
- cal.LOG("[calTimezoneService] timezones version: " + this.mVersion);
-
} catch (exc) {
- let msg = cal.calGetString("calendar", "missingCalendarTimezonesError");
- cal.ERROR(msg);
- showError(msg);
+ cal.ERROR("Error setting up timezone database: " + exc);
}
+ return false;
},
initialize: function calTimezoneService_initialize(aCompleteListener) {
- // This function contains a lot of async calls. Please make sure you
- // return this function in each control path.
- function done() {
- aCompleteListener.onResult(null, Components.results.NS_OK);
- }
+ // Helper function to convert an nsIURI to a nsIFile
+ function toFile(uriSpec) {
+ let uri = cal.makeURL(uriSpec);
- // Helper function to convert an nsIURI to a nsIFile
- function toFile(uri) {
if (uri.schemeIs("file")) {
let handler = cal.getIOService().getProtocolHandler("file")
.QueryInterface(Components.interfaces.nsIFileProtocolHandler);
return handler.getFileFromURLSpec(uri.spec);
+ } else if (uri.schemeIs("resource")) {
+ let handler = cal.getIOService().getProtocolHandler("resource")
+ .QueryInterface(Components.interfaces.nsIResProtocolHandler);
+ let newUriSpec;
+ try {
+ newUriSpec = handler.resolveURI(uri);
+ } catch (e) {
+ // Possibly the resource location is not registered, return
+ // null to indicate error
+ return null;
+ }
+
+ // Otherwise let this function convert the new uri spec to a file
+ return toFile(newUriSpec);
} else {
- cal.ERROR("Unknown timezones.sqlite location: " + uri.spec);
+ cal.ERROR("Unknown timezones.sqlite location: " + uriSpec);
}
return null;
}
let self = this;
- const kCalendarTimezonesXpiId = "calendar-timezones@mozilla.org";
- AddonManager.getAddonByID(kCalendarTimezonesXpiId, function getTimezoneExt(aAddon) {
- if (aAddon) {
- // The addon was found, extract the timezone stuff
- let sqlTzFile = toFile(aAddon.getResourceURI(''));
- let bundleURL = "chrome://calendar-timezones/locale/timezones.properties";
-
- self._initDB(sqlTzFile);
- g_stringBundle = cal.calGetStringBundle(bundleURL);
- return done();
- } else {
- // No addon found. Possibly we have the timezone data
- // bundled.
- if (cal.isSunbird()) {
- // Sunbird doesn't bundle the timezone extension
- let msg = cal.calGetString("calendar", "missingCalendarTimezonesError");
- cal.ERROR(msg);
- showError(msg);
- return done();
- } else {
- const kLightningXpiId = "{e2fda1a4-762b-4020-b5ad-a41df1933103}";
- AddonManager.getAddonByID(kLightningXpiId, function getLightningExt(aAddon) {
- let bundleURL;
- let sqlTzFile;
- if (aAddon) {
- sqlTzFile = toFile(aAddon.getResourceURI(''));
- bundleURL = "chrome://lightning/locale/timezones.properties";
- } else {
- // No Lightning? Possibly we're running a unit test.
- let dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
- .getService(Components.interfaces.nsIProperties);
- sqlTzFile = dirSvc.get("CurProcD", Components.interfaces.nsILocalFile);
- sqlTzFile.append("extensions");
- sqlTzFile.append(kCalendarTimezonesXpiId);
- cal.WARN("### USING " + sqlTzFile.path);
- self._initDB(sqlTzFile);
-
- let bundleFile = sqlTzFile.clone();
- bundleFile.append("chrome");
- bundleFile.append("calendar-timezones-en-US.jar");
-
- bundleURL = "jar:" + getIOService().newFileURI(bundleFile).spec + "!/locale/en-US/timezones.properties";
- }
-
- self._initDB(sqlTzFile);
- g_stringBundle = cal.calGetStringBundle(bundleURL);
- return done();
- });
-
- // Async calls made, no further action
- return null;
- }
+ function tryTzUri(uriSpec) {
+ let canInit = false;
+ let sqlTzFile = toFile(uriSpec);
+ if (sqlTzFile) {
+ canInit = self._initDB(sqlTzFile);
}
- // If this line is reached, then you've forgotten to return
- // somewhere above. Please check!
- cal.ERROR("Missing return statements in calTimezoneService.js!");
- return null;
- });
+ return canInit;
+ }
+
+ // First, lets try getting the file from our timezone extension
+ let canInit = tryTzUri("resource://calendar-timezones/timezones.sqlite");
+ let bundleURL = "chrome://calendar-timezones/locale/timezones.properties";
+
+ if (!canInit) {
+ // If that fails, we might have the file bundled
+ canInit = tryTzUri("resource://calendar/timezones.sqlite");
+ bundleURL = "chrome://calendar/locale/timezones.properties"
+ }
+
+ if (canInit) {
+ // Seems like a success, make the bundle url global
+ g_stringBundle = cal.calGetStringBundle(bundleURL);
+ } else {
+ // Otherwise, we have to give up. Show an error and fail hard!
+ let msg = cal.calGetString("calendar", "missingCalendarTimezonesError");
+ cal.ERROR(msg);
+ showError(msg);
+ }
+
+ if (aCompleteListener) {
+ aCompleteListener.onResult(null, Components.results.NS_OK);
+ }
},
// calITimezoneProvider:
getTimezone: function calTimezoneService_getTimezone(tzid) {
this.ensureInitialized();
if (tzid.indexOf("/mozilla.org/") == 0) {
// We know that our former tzids look like "/mozilla.org/<dtstamp>/continent/..."
// The ending of the mozilla prefix is the index of that slash before the
--- a/calendar/lightning/locales/jar.mn
+++ b/calendar/lightning/locales/jar.mn
@@ -1,7 +1,6 @@
#filter substitution
lightning-@AB_CD@.jar:
% locale lightning @AB_CD@ %locale/@AB_CD@/lightning/
locale/@AB_CD@/lightning/lightning.dtd (%chrome/lightning/lightning.dtd)
locale/@AB_CD@/lightning/lightning.properties (%chrome/lightning/lightning.properties)
- locale/@AB_CD@/lightning/timezones.properties (%chrome/calendar/timezones.properties)
--- a/calendar/locales/jar.mn
+++ b/calendar/locales/jar.mn
@@ -15,16 +15,17 @@ calendar-@AB_CD@.jar:
locale/@AB_CD@/calendar/calendar-subscriptions-dialog.dtd (%chrome/calendar/calendar-subscriptions-dialog.dtd)
locale/@AB_CD@/calendar/categories.properties (%chrome/calendar/categories.properties)
locale/@AB_CD@/calendar/dateFormat.properties (%chrome/calendar/dateFormat.properties)
locale/@AB_CD@/calendar/global.dtd (%chrome/calendar/global.dtd)
locale/@AB_CD@/calendar/menuOverlay.dtd (%chrome/calendar/menuOverlay.dtd)
locale/@AB_CD@/calendar/migration.dtd (%chrome/calendar/migration.dtd)
locale/@AB_CD@/calendar/migration.properties (%chrome/calendar/migration.properties)
locale/@AB_CD@/calendar/provider-uninstall.dtd (%chrome/calendar/provider-uninstall.dtd)
+ locale/@AB_CD@/calendar/timezones.properties (%chrome/calendar/timezones.properties)
locale/@AB_CD@/calendar/wcap.properties (%chrome/calendar/providers/wcap/wcap.properties)
locale/@AB_CD@/calendar/preferences/advanced.dtd (%chrome/calendar/preferences/advanced.dtd)
locale/@AB_CD@/calendar/preferences/alarms.dtd (%chrome/calendar/preferences/alarms.dtd)
locale/@AB_CD@/calendar/preferences/categories.dtd (%chrome/calendar/preferences/categories.dtd)
* locale/@AB_CD@/calendar/preferences/connection.dtd (%chrome/calendar/preferences/connection.dtd)
locale/@AB_CD@/calendar/preferences/general.dtd (%chrome/calendar/preferences/general.dtd)
locale/@AB_CD@/calendar/preferences/preferences.dtd (%chrome/calendar/preferences/preferences.dtd)
locale/@AB_CD@/calendar/preferences/timezones.dtd (%chrome/calendar/preferences/timezones.dtd)
--- a/calendar/timezones/install.rdf
+++ b/calendar/timezones/install.rdf
@@ -67,16 +67,17 @@
<!-- Seamonkey -->
<em:id>{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}</em:id>
<em:minVersion>2.0</em:minVersion>
<em:maxVersion>@SEAMONKEY_VERSION@</em:maxVersion>
</Description>
</em:targetApplication>
<em:name>Timezone Definitions for Mozilla Calendar</em:name>
+ <em:unpack>true</em:unpack>
<em:description>Timezone definitions required by Sunbird and Lightning</em:description>
<em:creator>Mozilla Calendar Project</em:creator>
<em:iconURL>chrome://calendar-timezones/skin/addon-icon32.png</em:iconURL>
#if 0
<em:homepageURL>https://addons.mozilla.org/en-US/thunderbird/addon/xxx todo</em:homepageURL>
#endif
</Description>
</RDF>
--- a/calendar/timezones/jar.mn
+++ b/calendar/timezones/jar.mn
@@ -1,5 +1,6 @@
#filter substitution
calendar-timezones.jar:
+% resource calendar-timezones .
% skin calendar-timezones classic/1.0 %skin/
skin/addon-icon32.png (addon-icon32.png)