From 1d983c15e6d984be24d15586ed85b7b37cf1f5d4 Mon Sep 17 00:00:00 2001 From: "daniel.boelzle%sun.com" Date: Tue, 17 Oct 2006 10:18:34 +0000 Subject: [PATCH] Bug 340949: read-only finetuning, fix for orphaned but still subscribed users, better timezone matching, misc git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_8_BRANCH@213744 18797224-902f-48f8-a5cc-f745e15eee43 --- .../providers/wcap/calWcapCalendar.js | 68 ++++++++++++++---- .../providers/wcap/calWcapCalendarModule.js | 18 +++-- .../calendar/providers/wcap/calWcapErrors.js | 13 ++-- .../calendar/providers/wcap/calWcapRequest.js | 10 ++- .../calendar/providers/wcap/calWcapUtils.js | 17 +---- .../wcap/public/calIWcapCalendar.idl | 72 ++++++++++--------- .../wcap/public/calIWcapFreeBusyListener.idl | 2 + 7 files changed, 123 insertions(+), 77 deletions(-) diff --git a/mozilla/calendar/providers/wcap/calWcapCalendar.js b/mozilla/calendar/providers/wcap/calWcapCalendar.js index c4df3416d22..83372140f56 100644 --- a/mozilla/calendar/providers/wcap/calWcapCalendar.js +++ b/mozilla/calendar/providers/wcap/calWcapCalendar.js @@ -180,9 +180,27 @@ calWcapCalendar.prototype = { set superCalendar( cal ) { this.m_superCalendar = cal; }, m_bReadOnly: false, - get readOnly() { return (this.m_bReadOnly || !this.isOwnedCalendar); }, + get readOnly() { + return (this.m_bReadOnly || + // read-only if not logged in, this flag is tested quite + // early, so don't log in here if not logged in already... + !this.session.isLoggedIn || + // xxx todo: take permissions into account: + !this.isOwnedCalendar); + }, set readOnly( bReadOnly ) { this.m_bReadOnly = bReadOnly; }, + assureReadWrite: + function() + { + this.session.getSessionId(); // assure being logged in + if (this.readOnly) { + throw new Components.Exception( + "Calendar is read-only.", + Components.interfaces.calIErrors.CAL_IS_READONLY ); + } + }, + // xxx todo: will potentially vanish from calICalendar: get uri() { return this.session.uri; }, set uri( thatUri ) { @@ -248,10 +266,14 @@ calWcapCalendar.prototype = { get ownerId() { var ar = this.getCalendarProperties("X-NSCP-CALPROPS-PRIMARY-OWNER",{}); if (ar.length < 1 || ar[0].length == 0) { + var calId = this.calId; this.notifyError( - "cannot determine primary owner of calendar " + this.calId ); - // fallback to userId: - return this.session.userId; + "cannot determine primary owner of calendar " + calId ); + // fallback to calId prefix: + var nColon = calId.indexOf(":"); + if (nColon >= 0) + calId = calId.substring(0, nColon); + return calId; } return ar[0]; }, @@ -279,11 +301,7 @@ calWcapCalendar.prototype = { }, get isOwnedCalendar() { - if (!this.session.isLoggedIn) - return false; - var ownerId = this.ownerId; - return (this.calId == ownerId || - this.calId.indexOf(ownerId + ":") == 0); + return (this.ownerId == this.session.userId); }, getCalendarProperties: @@ -318,7 +336,16 @@ calWcapCalendar.prototype = { this_.m_calProps = xml; } catch (exc) { - this_.notifyError( exc ); + // patch to read-only here, because error notification + // call the readOnly attribute, thus we would run into + // endless recursion here: + this_.m_bReadOnly = true; +// this_.notifyError( exc ); + // just logging here, because user may have dangling + // users referred in his subscription list: + this_.logError( exc ); + // though we continue to try to get that calprops + // next time... } } if (bAsync) @@ -328,6 +355,9 @@ calWcapCalendar.prototype = { } } catch (exc) { + // patch to read-only here, because error notification call the + // readOnly attribute, thus we would run into endless recursion here + this.m_bReadOnly = true; this.notifyError( exc ); throw exc; } @@ -351,13 +381,23 @@ calWcapCalendar.prototype = { function( tzid ) { // check whether it is one of cs: - if (tzid.indexOf("/mozilla.org/20050126_1/") == 0 || - !this.session.isSupportedTimezone(tzid)) { + if (tzid.indexOf("/mozilla.org/") == 0) { + // cut mozilla prefix: assuming that the latter string portion + // semantically equals the demanded timezone + tzid = tzid.substring( // next slash after "/mozilla.org/" + tzid.indexOf("/", "/mozilla.org/".length) + 1 ); + } + if (!this.session.isSupportedTimezone(tzid)) { + // xxx todo: we could further on search for a matching region, + // e.g. CET (in TZNAME), but for now stick to + // user's default if not supported directly + var ret = this.defaultTimezone; // use calendar's default: - return this.defaultTimezone; + this.log( tzid + " not supported, falling back to default: " + ret); + return ret; } else // is ok (supported): return tzid; - } + } }; diff --git a/mozilla/calendar/providers/wcap/calWcapCalendarModule.js b/mozilla/calendar/providers/wcap/calWcapCalendarModule.js index b1a612a8040..197779376cc 100644 --- a/mozilla/calendar/providers/wcap/calWcapCalendarModule.js +++ b/mozilla/calendar/providers/wcap/calWcapCalendarModule.js @@ -37,6 +37,16 @@ * * ***** END LICENSE BLOCK ***** */ +var g_ioService = null; +function getIoService() +{ + if (g_ioService == null) { + g_ioService = Components.classes["@mozilla.org/network/io-service;1"] + .getService(Components.interfaces.nsIIOService); + } + return g_ioService; +} + // // init code for globals, prefs: // @@ -226,9 +236,7 @@ var calWcapCalendarModule = { // nsIModule: var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .createInstance(Components.interfaces.mozIJSSubScriptLoader); - var ioService = - Components.classes["@mozilla.org/network/io-service;1"] - .getService(Components.interfaces.nsIIOService); + var ioService = getIoService(); var baseDir = __LOCATION__.parent.parent; baseDir.append("js"); for each ( var script in scripts ) { @@ -241,10 +249,10 @@ var calWcapCalendarModule = { // nsIModule: this.m_scriptsLoaded = true; } - if (!cid.equals( calWcapCalendar.prototype.classID )) - throw Components.results.NS_ERROR_NO_INTERFACE; if (!iid.equals( Components.interfaces.nsIFactory )) throw Components.results.NS_ERROR_NOT_IMPLEMENTED; + if (!cid.equals( calWcapCalendar.prototype.classID )) + throw Components.results.NS_ERROR_NO_INTERFACE; return { // nsIFactory: lockFactory: function( lock ) {}, diff --git a/mozilla/calendar/providers/wcap/calWcapErrors.js b/mozilla/calendar/providers/wcap/calWcapErrors.js index 2bca796d978..52cd84ca237 100644 --- a/mozilla/calendar/providers/wcap/calWcapErrors.js +++ b/mozilla/calendar/providers/wcap/calWcapErrors.js @@ -108,10 +108,10 @@ const g_nsNetErrorCodes = [ function netErrorToString( rc ) { - if (getErrorModule(rc) == NS_ERROR_MODULE_NETWORK) { + if (!isNaN(rc) && getErrorModule(rc) == NS_ERROR_MODULE_NETWORK) { var i = 0; while (i < g_nsNetErrorCodes.length) { - // rc is kept unsigned, our generated code signed, + // however rc is kept unsigned, our generated code signed, // so == won't work here: if ((g_nsNetErrorCodes[i] ^ rc) == 0) return g_nsNetErrorCodes[i + 1]; @@ -249,6 +249,8 @@ const g_wcapErrorCodes = [ function wcapErrorToString( rc ) { + if (isNaN(rc)) + throw Components.results.NS_ERROR_INVALID_ARG; if (rc == Components.interfaces.calIWcapErrors.WCAP_NO_ERRNO) return "No WCAP errno (missing X-NSCP-WCAP-ERRNO)."; @@ -347,7 +349,10 @@ function errorToString( err ) return "NS_ERROR_NOT_IMPLEMENTED"; case Components.results.NS_ERROR_FAILURE: return "NS_ERROR_FAILURE"; - default: // probe for WCAP error: + default: + if (isNaN(err)) + return ("[" + err + "] Unknown error."); + // probe for WCAP error: try { return wcapErrorToString(err); } @@ -356,7 +361,7 @@ function errorToString( err ) return netErrorToString(err); } catch (exc) { - return ("[" + err + "] Unknown error."); + return ("[0x" + err.toString(16) + "] Unknown error."); } } } diff --git a/mozilla/calendar/providers/wcap/calWcapRequest.js b/mozilla/calendar/providers/wcap/calWcapRequest.js index 2c1b53a36ab..c4008f34f9e 100644 --- a/mozilla/calendar/providers/wcap/calWcapRequest.js +++ b/mozilla/calendar/providers/wcap/calWcapRequest.js @@ -60,8 +60,12 @@ WcapResponse.prototype = { m_exc: null, get data() { - if (this.m_exc != null) - throw this.m_exc; + if (this.m_exc != null) { + // clear exception, so it is not thrown again on sync requests: + var exc = this.m_exc; + this.m_exc = null; + throw exc; + } return this.m_data; }, set data(d) { @@ -223,7 +227,7 @@ function issueSyncRequest( url, receiverFunc, bLogging ) } else if (bLogging && LOG_LEVEL > 0) { logMessage( "issueSyncRequest( \"" + url + "\" )", - "failed: " + status ); + "failed: " + errorToString(status) ); } throw new Components.Exception( diff --git a/mozilla/calendar/providers/wcap/calWcapUtils.js b/mozilla/calendar/providers/wcap/calWcapUtils.js index a2924dff1a8..20df96c58d3 100644 --- a/mozilla/calendar/providers/wcap/calWcapUtils.js +++ b/mozilla/calendar/providers/wcap/calWcapUtils.js @@ -90,16 +90,6 @@ function getWindowWatcher() return g_windowWatcher; } -var g_ioService = null; -function getIoService() -{ - if (g_ioService == null) { - g_ioService = Components.classes["@mozilla.org/network/io-service;1"] - .getService(Components.interfaces.nsIIOService); - } - return g_ioService; -} - var g_icsService = null; function getIcsService() { @@ -170,17 +160,12 @@ function lockedExec( func ) try { ret = func(); } - catch (exc) { + finally { if (g_eventQueueService) g_eventQueueService.popThreadEventQueue(queue); else // we are on trunk using nsIThreadInternal g_threadManager.currentThread.popEventQueue(); - throw exc; } - if (g_eventQueueService) - g_eventQueueService.popThreadEventQueue(queue); - else // we are on trunk using nsIThreadInternal - g_threadManager.currentThread.popEventQueue(); return ret; } diff --git a/mozilla/calendar/providers/wcap/public/calIWcapCalendar.idl b/mozilla/calendar/providers/wcap/public/calIWcapCalendar.idl index d898fc51636..2ca8b3ada14 100644 --- a/mozilla/calendar/providers/wcap/public/calIWcapCalendar.idl +++ b/mozilla/calendar/providers/wcap/public/calIWcapCalendar.idl @@ -76,10 +76,10 @@ interface calIWcapCalendar : calICalendar */ readonly attribute string displayName; -// /** -// * Gets or sets this calendar's (calId) default timezone. -// */ -// attribute string defaultTimezone; + /** + * Gets or sets this calendar's (calId) default timezone. + */ + readonly attribute string defaultTimezone; /** * Gets calendar properties. @@ -107,27 +107,29 @@ interface calIWcapCalendar : calICalendar xxx todo: ITEM_FILTER_CLASS_OCCURRENCES is not filter, rename? */ + + /* xxx todo: limit to currently needed ones: NEEDS-ACTION */ - /** - * Scope: Attendee - * The event or todo is an invitation from another - * user and the current user has declined the invitation. - */ - const unsigned long ITEM_FILTER_REPLY_DECLINED = 1 << 24; +// /** +// * Scope: Attendee +// * The event or todo is an invitation from another +// * user and the current user has declined the invitation. +// */ +// const unsigned long ITEM_FILTER_REPLY_DECLINED = 1 << 24; - /** - * Scope: Attendee - * The event or todo is an invitation from another - * user and the current user has accepted the invitation. - */ - const unsigned long ITEM_FILTER_REPLY_ACCEPTED = 1 << 25; +// /** +// * Scope: Attendee +// * The event or todo is an invitation from another +// * user and the current user has accepted the invitation. +// */ +// const unsigned long ITEM_FILTER_REPLY_ACCEPTED = 1 << 25; - /** - * Scope: Organizer - * The event or todo is an invitation from the current - * user to other invitees, and all invitees have replied. - */ - const unsigned long ITEM_FILTER_REQUEST_COMPLETED = 1 << 26; +// /** +// * Scope: Organizer +// * The event or todo is an invitation from the current +// * user to other invitees, and all invitees have replied. +// */ +// const unsigned long ITEM_FILTER_REQUEST_COMPLETED = 1 << 26; /** * Scope: Attendee @@ -143,20 +145,20 @@ interface calIWcapCalendar : calICalendar */ const unsigned long ITEM_FILTER_REQUEST_NEEDSNOACTION = 1 << 28; - /** - * Scope: Organizer - * The event or todo is an invitation from the current - * user to other invitees, and is currently in the - * process of sending out invitations. - */ - const unsigned long ITEM_FILTER_REQUEST_PENDING = 1 << 29; +// /** +// * Scope: Organizer +// * The event or todo is an invitation from the current +// * user to other invitees, and is currently in the +// * process of sending out invitations. +// */ +// const unsigned long ITEM_FILTER_REQUEST_PENDING = 1 << 29; - /** - * Scope: Organizer - * The event or todo is an invitation from the current - * user to other invitees, and is currently awaiting. - */ - const unsigned long ITEM_FILTER_REQUEST_WAITFORREPLY = 1 << 30; +// /** +// * Scope: Organizer +// * The event or todo is an invitation from the current +// * user to other invitees, and is currently awaiting. +// */ +// const unsigned long ITEM_FILTER_REQUEST_WAITFORREPLY = 1 << 30; /* xxx todo sync feature: separate into own interface? */ diff --git a/mozilla/calendar/providers/wcap/public/calIWcapFreeBusyListener.idl b/mozilla/calendar/providers/wcap/public/calIWcapFreeBusyListener.idl index 24fae23efbf..72249525d8a 100644 --- a/mozilla/calendar/providers/wcap/public/calIWcapFreeBusyListener.idl +++ b/mozilla/calendar/providers/wcap/public/calIWcapFreeBusyListener.idl @@ -45,6 +45,8 @@ interface calIWcapFreeBusyListener : nsISupports { /** * Callback receiving free-busy entries. + * xxx todo: use array of calIPeriod when available and stick + * to busy entries only... * * @param rc result code, * e.g. NS_OK or calIWcapErrors.WCAP_CALENDAR_DOES_NOT_EXIST