mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 340949, revised/more IDL, separated session from calendar instances
This commit is contained in:
parent
0e74500a29
commit
a96ab64df4
@ -37,9 +37,10 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
function calWcapCalendar() {
|
||||
function calWcapCalendar( calId, session ) {
|
||||
this.wrappedJSObject = this;
|
||||
this.m_observers = [];
|
||||
this.m_calId = calId;
|
||||
this.m_session = session;
|
||||
}
|
||||
calWcapCalendar.prototype = {
|
||||
m_ifaces: [ Components.interfaces.calIWcapCalendar,
|
||||
@ -99,15 +100,9 @@ calWcapCalendar.prototype = {
|
||||
toString:
|
||||
function()
|
||||
{
|
||||
var str;
|
||||
if (this.m_session == null) {
|
||||
str = "no session";
|
||||
}
|
||||
else {
|
||||
str = this.session.toString();
|
||||
if (this.m_calId != null && this.m_calId != this.userId)
|
||||
str += (", calId=" + this.m_calId);
|
||||
}
|
||||
var str = this.session.toString();
|
||||
if (this.calId != this.session.userId)
|
||||
str += (", calId=" + this.calId);
|
||||
return str;
|
||||
},
|
||||
log:
|
||||
@ -149,65 +144,31 @@ calWcapCalendar.prototype = {
|
||||
get readOnly() { return (this.m_bReadOnly || !this.isOwnedCalendar); },
|
||||
set readOnly( bReadOnly ) { this.m_bReadOnly = bReadOnly; },
|
||||
|
||||
m_uri: null,
|
||||
get uri() { return this.m_uri },
|
||||
set uri( thatUri )
|
||||
{
|
||||
if (this.m_uri == null || thatUri == null ||
|
||||
!this.m_uri.equals(thatUri))
|
||||
{
|
||||
if (this.m_session != null) {
|
||||
this.m_session.logout();
|
||||
this.m_session = null;
|
||||
}
|
||||
this.m_uri = null;
|
||||
this.m_calId = null;
|
||||
if (thatUri != null) {
|
||||
this.m_uri = thatUri.clone();
|
||||
this.m_calId = decodeURIComponent( thatUri.username );
|
||||
if (this.m_calId == "") {
|
||||
this.m_calId = null;
|
||||
}
|
||||
}
|
||||
this.refresh();
|
||||
}
|
||||
// xxx todo: will potentially vanish from calICalendar:
|
||||
get uri() { return this.session.uri; },
|
||||
set uri( thatUri ) {
|
||||
this.session.uri = thatUri;
|
||||
this.m_calProps = null;
|
||||
},
|
||||
|
||||
m_observers: null,
|
||||
notifyObservers:
|
||||
function( func, args )
|
||||
{
|
||||
this.m_observers.forEach(
|
||||
function( obj ) {
|
||||
try {
|
||||
obj[func].apply( obj, args );
|
||||
}
|
||||
catch (exc) {
|
||||
// don't call notifyError() here:
|
||||
Components.utils.reportError( exc );
|
||||
}
|
||||
} );
|
||||
function( func, args ) {
|
||||
this.session.notifyObservers( func, args );
|
||||
},
|
||||
|
||||
addObserver:
|
||||
function( observer )
|
||||
{
|
||||
if (this.m_observers.indexOf( observer ) == -1) {
|
||||
this.m_observers.push( observer );
|
||||
}
|
||||
function( observer ) {
|
||||
this.session.addObserver( observer );
|
||||
},
|
||||
|
||||
removeObserver:
|
||||
function( observer )
|
||||
{
|
||||
this.m_observers = this.m_observers.filter(
|
||||
function(x) { return x != observer; } );
|
||||
function( observer ) {
|
||||
this.session.removeObserver( observer );
|
||||
},
|
||||
|
||||
// xxx todo: batch currently not used
|
||||
startBatch: function() { this.notifyObservers( "onStartBatch", [] ); },
|
||||
endBatch: function() { this.notifyObservers( "onEndBatch", [] ); },
|
||||
|
||||
// xxx todo: rework like in
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=257428
|
||||
m_bSuppressAlarms: true /* xxx todo:
|
||||
off for now until all problems are solved */,
|
||||
get suppressAlarms() {
|
||||
@ -218,345 +179,85 @@ calWcapCalendar.prototype = {
|
||||
},
|
||||
|
||||
get canRefresh() { return false; },
|
||||
|
||||
refresh:
|
||||
function()
|
||||
{
|
||||
refresh: function() {
|
||||
// no-op
|
||||
this.log("refresh()");
|
||||
},
|
||||
|
||||
getCommandUrl:
|
||||
function( wcapCommand )
|
||||
{
|
||||
if (this.uri == null)
|
||||
throw new Error("no URI!");
|
||||
var session = this.session;
|
||||
// ensure established session, so userId is set;
|
||||
// (calId defaults to userId) if not set:
|
||||
session.getSessionId();
|
||||
return (session.uri.spec + wcapCommand +
|
||||
".wcap?appid=mozilla-lightning");
|
||||
},
|
||||
|
||||
issueRequest:
|
||||
function( url, issueFunc, dataConvFunc, receiverFunc )
|
||||
{
|
||||
var sessionId = this.session.getSessionId();
|
||||
|
||||
var this_ = this;
|
||||
issueFunc(
|
||||
url + ("&id=" + sessionId),
|
||||
function( data ) {
|
||||
var wcapResponse = new WcapResponse();
|
||||
try {
|
||||
try {
|
||||
wcapResponse.data = dataConvFunc(
|
||||
data, wcapResponse );
|
||||
}
|
||||
catch (exc) {
|
||||
if (exc == Components.interfaces.
|
||||
calIWcapErrors.WCAP_LOGIN_FAILED) /* timeout */ {
|
||||
// getting a new session will throw any exception in
|
||||
// this block, thus it is notified into receiverFunc
|
||||
this_.session.getSessionId(
|
||||
sessionId /* (old) timed-out session */ );
|
||||
// try again:
|
||||
this_.issueRequest(
|
||||
url, issueFunc, dataConvFunc, receiverFunc );
|
||||
return;
|
||||
}
|
||||
throw exc; // rethrow
|
||||
}
|
||||
}
|
||||
catch (exc) {
|
||||
// setting the request's exception will rethrow exception
|
||||
// when request's data is retrieved.
|
||||
wcapResponse.exception = exc;
|
||||
}
|
||||
receiverFunc( wcapResponse );
|
||||
} );
|
||||
},
|
||||
issueAsyncRequest:
|
||||
function( url, dataConvFunc, receiverFunc )
|
||||
{
|
||||
this.issueRequest(
|
||||
url, issueAsyncRequest, dataConvFunc, receiverFunc );
|
||||
},
|
||||
issueSyncRequest:
|
||||
function( url, dataConvFunc, receiverFunc )
|
||||
{
|
||||
var ret = null;
|
||||
this.issueRequest(
|
||||
url, issueSyncRequest,
|
||||
dataConvFunc,
|
||||
function( wcapResponse ) {
|
||||
if (receiverFunc) {
|
||||
receiverFunc( wcapResponse );
|
||||
}
|
||||
ret = wcapResponse.data; // may throw
|
||||
} );
|
||||
return ret;
|
||||
},
|
||||
|
||||
m_session: null,
|
||||
get session() {
|
||||
if (this.m_session == null) {
|
||||
this.m_session = getSession( this.uri );
|
||||
}
|
||||
return this.m_session;
|
||||
},
|
||||
|
||||
// calIWcapCalendar:
|
||||
|
||||
getWcapErrorString:
|
||||
function( rc )
|
||||
{
|
||||
return wcapErrorToString(rc);
|
||||
},
|
||||
m_session: null,
|
||||
get session() { return this.m_session; },
|
||||
|
||||
// xxx todo: which userId is used when for offline scheduling?
|
||||
// if not logged in, no calId/userId is known... => UI
|
||||
m_calId: null,
|
||||
get calId() {
|
||||
var userId = this.userId; // assure being logged in
|
||||
var userId = this.session.userId; // assure being logged in
|
||||
return this.m_calId || userId;
|
||||
},
|
||||
// xxx todo: for now to make subscriptions context menu work,
|
||||
// will vanish when UI has been revised and every subscribed
|
||||
// calendar has its own calICalendar object...
|
||||
// poking calId, so default calendar will then behave
|
||||
// like a subscribed one...
|
||||
set calId( id ) {
|
||||
this.log( "setting calId to " + id );
|
||||
this.m_calId = id;
|
||||
},
|
||||
get userId() { return this.session.userId; },
|
||||
|
||||
get description() {
|
||||
var ar = this.getCalendarProperties("X-NSCP-CALPROPS-DESCRIPTION", {});
|
||||
if (ar.length < 1) {
|
||||
return this.calId; // fallback
|
||||
}
|
||||
return ar[0];
|
||||
},
|
||||
|
||||
get isOwnedCalendar() {
|
||||
return (this.calId == this.userId ||
|
||||
this.calId.indexOf(this.userId + ":") == 0);
|
||||
},
|
||||
|
||||
createCalendar:
|
||||
function( calId, name, bAllowDoubleBooking, bSetCalProps, bAddToSubscribed )
|
||||
{
|
||||
try {
|
||||
var url = this.getCommandUrl( "createcalendar" );
|
||||
url += ("&allowdoublebook=" + (bAllowDoubleBooking ? "1" : "0"));
|
||||
url += ("&set_calprops=" + (bSetCalProps ? "1" : "0"));
|
||||
url += ("&subscribe=" + (bAddToSubscribed ? "1" : "0"));
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
// xxx todo: name undocumented!
|
||||
url += ("&name=" + encodeURIComponent(name));
|
||||
// xxx todo: what about categories param???
|
||||
this.issueSyncRequest( url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
return (this.userId + ":" + calId);
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
},
|
||||
|
||||
deleteCalendar:
|
||||
function( calId, bRemoveFromSubscribed )
|
||||
{
|
||||
try {
|
||||
var url = this.getCommandUrl( "deletecalendar" );
|
||||
url += ("&unsubscribe=" + (bRemoveFromSubscribed ? "1" : "0"));
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
this.issueSyncRequest( url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
},
|
||||
|
||||
getCalIds:
|
||||
function( out_count, bGetOwnedCals )
|
||||
{
|
||||
try {
|
||||
var url = this.getCommandUrl(
|
||||
bGetOwnedCals ? "list" : "list_subscribed" );
|
||||
var ret = [];
|
||||
var xml = this.issueSyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
var nodeList = xml.getElementsByTagName(
|
||||
bGetOwnedCals ? "X-S1CS-CALPROPS-OWNED-CALENDAR"
|
||||
: "X-S1CS-CALPROPS-SUBSCRIBED-CALENDAR" );
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
ret.push( nodeList.item(i).textContent );
|
||||
}
|
||||
out_count.value = ret.length;
|
||||
return ret;
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
},
|
||||
|
||||
getOwnedCalendars:
|
||||
function( out_count )
|
||||
{
|
||||
return this.getCalIds( out_count, true );
|
||||
},
|
||||
|
||||
getSubscribedCalendars:
|
||||
function( out_count )
|
||||
{
|
||||
return this.getCalIds( out_count, false );
|
||||
},
|
||||
|
||||
modifyCalendarSubscriptions:
|
||||
function( calIds, bSubscribe )
|
||||
{
|
||||
try {
|
||||
var url = this.getCommandUrl(
|
||||
bSubscribe ? "subscribe_calendars" : "unsubscribe_calendars" );
|
||||
var calId = "";
|
||||
for ( var i = 0; i < calIds.length; ++i ) {
|
||||
if (i > 0)
|
||||
calId += ";";
|
||||
calId += encodeURIComponent(calIds[i]);
|
||||
}
|
||||
url += ("&calid=" + calId);
|
||||
this.issueSyncRequest( url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
},
|
||||
|
||||
subscribeToCalendars:
|
||||
function( count, calIds )
|
||||
{
|
||||
this.modifyCalendarSubscriptions( calIds, true );
|
||||
},
|
||||
|
||||
unsubscribeFromCalendars:
|
||||
function( count, calIds )
|
||||
{
|
||||
this.modifyCalendarSubscriptions( calIds, false );
|
||||
},
|
||||
|
||||
getFreeBusyTimes_resp:
|
||||
function( wcapResponse, calId, iListener, requestId )
|
||||
{
|
||||
try {
|
||||
var xml = wcapResponse.data; // first statement, may throw
|
||||
if (iListener != null) {
|
||||
var ret = [];
|
||||
var nodeList = xml.getElementsByTagName("FB");
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
var item = nodeList.item(i);
|
||||
var str = item.textContent;
|
||||
var slash = str.indexOf( '/' );
|
||||
var start = new CalDateTime();
|
||||
start.icalString = str.substr( 0, slash );
|
||||
var end = new CalDateTime();
|
||||
end.icalString = str.substr( slash + 1 );
|
||||
var entry = {
|
||||
isBusyEntry:
|
||||
(item.attributes.getNamedItem("FBTYPE").nodeValue
|
||||
== "BUSY"),
|
||||
dtRangeStart: start,
|
||||
dtRangeEnd: end
|
||||
};
|
||||
ret.push( entry );
|
||||
}
|
||||
iListener.onGetFreeBusyTimes(
|
||||
Components.results.NS_OK,
|
||||
requestId, calId, ret.length, ret );
|
||||
}
|
||||
if (LOG_LEVEL > 0) {
|
||||
this.log( "getFreeBusyTimes_resp() calId=" + calId + ", " +
|
||||
getWcapRequestStatusString(xml) );
|
||||
}
|
||||
}
|
||||
catch (exc) {
|
||||
const calIWcapErrors = Components.interfaces.calIWcapErrors;
|
||||
switch (exc) {
|
||||
case calIWcapErrors.WCAP_NO_ERRNO: // workaround
|
||||
case calIWcapErrors.WCAP_ACCESS_DENIED_TO_CALENDAR:
|
||||
case calIWcapErrors.WCAP_CALENDAR_DOES_NOT_EXIST:
|
||||
this.log( "getFreeBusyTimes_resp() ignored: " +
|
||||
errorToString(exc) ); // no error
|
||||
break;
|
||||
default:
|
||||
this.notifyError( exc );
|
||||
break;
|
||||
}
|
||||
if (iListener != null)
|
||||
iListener.onGetFreeBusyTimes( exc, requestId, calId, 0, [] );
|
||||
}
|
||||
},
|
||||
|
||||
getFreeBusyTimes:
|
||||
function( calId, rangeStart, rangeEnd, bBusyOnly, iListener,
|
||||
bAsync, requestId )
|
||||
{
|
||||
try {
|
||||
// assure DATETIMEs:
|
||||
if (rangeStart != null && rangeStart.isDate) {
|
||||
rangeStart = rangeStart.clone();
|
||||
rangeStart.isDate = false;
|
||||
}
|
||||
if (rangeEnd != null && rangeEnd.isDate) {
|
||||
rangeEnd = rangeEnd.clone();
|
||||
rangeEnd.isDate = false;
|
||||
}
|
||||
var zRangeStart = getIcalUTC(rangeStart);
|
||||
var zRangeEnd = getIcalUTC(rangeEnd);
|
||||
this.log( "getFreeBusyTimes():\n\trangeStart=" + zRangeStart +
|
||||
",\n\trangeEnd=" + zRangeEnd );
|
||||
|
||||
var url = this.getCommandUrl( "get_freebusy" );
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
url += ("&busyonly=" + (bBusyOnly ? "1" : "0"));
|
||||
url += ("&dtstart=" + zRangeStart);
|
||||
url += ("&dtend=" + zRangeEnd);
|
||||
url += "&fmt-out=text%2Fxml";
|
||||
|
||||
var this_ = this;
|
||||
function resp( wcapResponse ) {
|
||||
this_.getFreeBusyTimes_resp(
|
||||
wcapResponse, calId, iListener, requestId );
|
||||
}
|
||||
if (bAsync)
|
||||
this.issueAsyncRequest( url, stringToXml, resp );
|
||||
else
|
||||
this.issueSyncRequest( url, stringToXml, resp );
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
if (iListener != null)
|
||||
iListener.onGetFreeBusyTimes( exc, requestId, calId, 0, [] );
|
||||
throw exc;
|
||||
}
|
||||
var userId = this.session.userId;
|
||||
return (this.calId == userId ||
|
||||
this.calId.indexOf(userId + ":") == 0);
|
||||
},
|
||||
|
||||
m_calProps: null,
|
||||
m_calPropsCalid: null,
|
||||
getCalendarProperties:
|
||||
function( propName, calId, out_count )
|
||||
function( propName, out_count )
|
||||
{
|
||||
this.getCalProps_(false /* !async: waits for response */);
|
||||
var ret = [];
|
||||
if (this.m_calProps != null) {
|
||||
var nodeList = this.m_calProps.getElementsByTagName(propName);
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
ret.push( trimString(nodeList.item(i).textContent) );
|
||||
}
|
||||
}
|
||||
out_count.value = ret.length;
|
||||
return ret;
|
||||
},
|
||||
getCalProps_:
|
||||
function( bAsync )
|
||||
{
|
||||
try {
|
||||
if (calId.length == 0) {
|
||||
calId = this.calId;
|
||||
if (this.m_calProps == null) {
|
||||
var url = this.session.getCommandUrl( "get_calprops" );
|
||||
url += ("&calid=" + encodeURIComponent(this.calId));
|
||||
url += "&fmt-out=text%2Fxml";
|
||||
var this_ = this;
|
||||
function resp( wcapResponse ) {
|
||||
try {
|
||||
// first statement, may throw:
|
||||
var xml = wcapResponse.data;
|
||||
if (this_.m_calProps == null)
|
||||
this_.m_calProps = xml;
|
||||
}
|
||||
catch (exc) {
|
||||
this_.notifyError( exc );
|
||||
}
|
||||
}
|
||||
if (bAsync)
|
||||
this.session.issueAsyncRequest( url, stringToXml, resp );
|
||||
else
|
||||
this.session.issueSyncRequest( url, stringToXml, resp );
|
||||
}
|
||||
if (this.m_calPropsCalid != calId) {
|
||||
var url = this.getCommandUrl( "get_calprops" );
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
this.m_calProps = this.issueSyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
this.m_calPropsCalid = calId;
|
||||
}
|
||||
var ret = [];
|
||||
var nodeList = this.m_calProps.getElementsByTagName( propName );
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
ret.push( nodeList.item(i).textContent );
|
||||
}
|
||||
out_count.value = ret.length;
|
||||
return ret;
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
@ -565,13 +266,12 @@ calWcapCalendar.prototype = {
|
||||
},
|
||||
|
||||
get defaultTimezone() {
|
||||
var tzid = this.getCalendarProperties("X-NSCP-CALPROPS-TZID", "", {});
|
||||
var tzid = this.getCalendarProperties("X-NSCP-CALPROPS-TZID", {});
|
||||
if (tzid.length < 1) {
|
||||
return "UTC"; // fallback
|
||||
}
|
||||
return tzid[0];
|
||||
},
|
||||
|
||||
// set defaultTimezone( tzid ) {
|
||||
// if (this.readOnly)
|
||||
// throw Components.interfaces.calIErrors.CAL_IS_READONLY;
|
||||
@ -590,6 +290,6 @@ calWcapCalendar.prototype = {
|
||||
}
|
||||
else // is ok (supported):
|
||||
return tzid;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -194,8 +194,8 @@ calWcapCalendar.prototype.getRecurrenceParams = function(
|
||||
calWcapCalendar.prototype.getStoreUrl = function( item )
|
||||
{
|
||||
var bIsEvent = isEvent(item);
|
||||
var url = this.getCommandUrl( bIsEvent ? "storeevents"
|
||||
: "storetodos" );
|
||||
var url = this.session.getCommandUrl( bIsEvent ? "storeevents"
|
||||
: "storetodos" );
|
||||
url += "&fetch=1&compressed=1&recurring=1";
|
||||
url += ("&calid=" + encodeURIComponent(this.calId));
|
||||
|
||||
@ -292,7 +292,7 @@ calWcapCalendar.prototype.getStoreUrl = function( item )
|
||||
forceRSVP = true;
|
||||
}
|
||||
else {
|
||||
var userId = this.userId;
|
||||
var userId = this.session.userId;
|
||||
if (userId == null)
|
||||
userId = this.calId; // fallback
|
||||
var i = 0;
|
||||
@ -478,7 +478,7 @@ calWcapCalendar.prototype.adoptItem = function( item, iListener )
|
||||
url += "&storetype=1";
|
||||
|
||||
var this_ = this;
|
||||
this.issueAsyncRequest(
|
||||
this.session.issueAsyncRequest(
|
||||
url + "&fmt-out=text%2Fcalendar", stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.adoptItem_resp( wcapResponse, iListener );
|
||||
@ -573,7 +573,7 @@ calWcapCalendar.prototype.modifyItem = function(
|
||||
}
|
||||
|
||||
var this_ = this;
|
||||
this.issueAsyncRequest(
|
||||
this.session.issueAsyncRequest(
|
||||
url + "&fmt-out=text%2Fcalendar", stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.modifyItem_resp( wcapResponse,
|
||||
@ -634,7 +634,7 @@ calWcapCalendar.prototype.deleteItem = function( item, iListener )
|
||||
if (item.id == null)
|
||||
throw new Error("no item id!");
|
||||
|
||||
var url = this.getCommandUrl(
|
||||
var url = this.session.getCommandUrl(
|
||||
isEvent(item) ? "deleteevents_by_id" : "deletetodos_by_id" );
|
||||
url += ("&calid=" + encodeURIComponent(this.calId));
|
||||
url += ("&uid=" + item.id);
|
||||
@ -653,7 +653,7 @@ calWcapCalendar.prototype.deleteItem = function( item, iListener )
|
||||
}
|
||||
|
||||
var this_ = this;
|
||||
this.issueAsyncRequest(
|
||||
this.session.issueAsyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", stringToXml,
|
||||
function( wcapResponse ) {
|
||||
this_.deleteItem_resp( wcapResponse, item, iListener );
|
||||
@ -885,14 +885,14 @@ calWcapCalendar.prototype.getItem = function( id, iListener )
|
||||
params += ("&uid=" + id);
|
||||
try {
|
||||
// most common: event
|
||||
this.issueSyncRequest(
|
||||
this.getCommandUrl( "fetchevents_by_id" ) + params,
|
||||
this.session.issueSyncRequest(
|
||||
this.session.getCommandUrl( "fetchevents_by_id" ) + params,
|
||||
stringToIcal, syncResponseFunc );
|
||||
}
|
||||
catch (exc) {
|
||||
// try again, may be a task:
|
||||
this.issueSyncRequest(
|
||||
this.getCommandUrl( "fetchtodos_by_id" ) + params,
|
||||
this.session.issueSyncRequest(
|
||||
this.session.getCommandUrl( "fetchtodos_by_id" ) + params,
|
||||
stringToIcal, syncResponseFunc );
|
||||
}
|
||||
}
|
||||
@ -960,7 +960,7 @@ calWcapCalendar.prototype.getItems = function(
|
||||
",\n\trangeStart=" + zRangeStart +
|
||||
",\n\trangeEnd=" + zRangeEnd );
|
||||
try {
|
||||
var url = this.getCommandUrl( "fetchcomponents_by_range" );
|
||||
var url = this.session.getCommandUrl( "fetchcomponents_by_range" );
|
||||
url += ("&calid=" + encodeURIComponent(this.calId));
|
||||
url += "&compressed=1&recurring=1";
|
||||
|
||||
@ -998,7 +998,7 @@ calWcapCalendar.prototype.getItems = function(
|
||||
url += ("&dtend=" + zRangeEnd);
|
||||
|
||||
var this_ = this;
|
||||
this.issueAsyncRequest(
|
||||
this.session.issueAsyncRequest(
|
||||
url + "&fmt-out=text%2Fcalendar", stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.getItems_resp( wcapResponse,
|
||||
@ -1160,10 +1160,10 @@ calWcapCalendar.prototype.syncChangesTo = function(
|
||||
if (dtFrom == null) {
|
||||
this.log( "syncChangesTo(): doing initial sync." );
|
||||
syncState.acquire();
|
||||
var url = this.getCommandUrl( "fetchcomponents_by_range" );
|
||||
var url = this.session.getCommandUrl( "fetchcomponents_by_range" );
|
||||
url += ("&compressed=1&recurring=1&calid=" +
|
||||
encodeURIComponent(this.calId));
|
||||
this.issueAsyncRequest(
|
||||
this.session.issueAsyncRequest(
|
||||
url + "&fmt-out=text%2Fcalendar", stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.syncChangesTo_resp(
|
||||
@ -1186,8 +1186,8 @@ calWcapCalendar.prototype.syncChangesTo = function(
|
||||
encodeURIComponent(this.calId));
|
||||
params += ("&fmt-out=text%2Fcalendar&dtstart=" + zdtFrom);
|
||||
syncState.acquire();
|
||||
this.issueAsyncRequest(
|
||||
this.getCommandUrl( "fetchcomponents_by_lastmod" ) + params,
|
||||
this.session.issueAsyncRequest(
|
||||
this.session.getCommandUrl("fetchcomponents_by_lastmod")+params,
|
||||
stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.syncChangesTo_resp(
|
||||
@ -1215,8 +1215,8 @@ calWcapCalendar.prototype.syncChangesTo = function(
|
||||
var deleteItemListener = new FinishListener(
|
||||
Components.interfaces.calIOperationListener.DELETE, syncState );
|
||||
syncState.acquire();
|
||||
this.issueAsyncRequest(
|
||||
this.getCommandUrl( "fetch_deletedcomponents" ) + params,
|
||||
this.session.issueAsyncRequest(
|
||||
this.session.getCommandUrl("fetch_deletedcomponents") + params,
|
||||
stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.syncChangesTo_resp(
|
||||
|
@ -45,6 +45,12 @@ var calWcapCalendarModule = {
|
||||
classID: Components.ID("{CF4D93E5-AF79-451a-95F3-109055B32EF0}")
|
||||
},
|
||||
|
||||
WcapSessionInfo: {
|
||||
classDescription: "Sun Java System Calendar Server WCAP Session",
|
||||
contractID: "@mozilla.org/calendar/session;1?type=wcap",
|
||||
classID: Components.ID("{CBF803FD-4469-4999-AE39-367AF1C7B077}")
|
||||
},
|
||||
|
||||
registerSelf:
|
||||
function( compMgr, fileSpec, location, type )
|
||||
{
|
||||
@ -55,6 +61,11 @@ var calWcapCalendarModule = {
|
||||
this.WcapCalendarInfo.classDescription,
|
||||
this.WcapCalendarInfo.contractID,
|
||||
fileSpec, location, type );
|
||||
compMgr.registerFactoryLocation(
|
||||
this.WcapSessionInfo.classID,
|
||||
this.WcapSessionInfo.classDescription,
|
||||
this.WcapSessionInfo.contractID,
|
||||
fileSpec, location, type );
|
||||
},
|
||||
|
||||
m_scriptsLoaded: false,
|
||||
@ -95,12 +106,16 @@ var calWcapCalendarModule = {
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
var cal;
|
||||
switch (CACHE) {
|
||||
case "memory":
|
||||
case "storage":
|
||||
cal = new calWcapCachedCalendar();
|
||||
break;
|
||||
// unsupported until fixed:
|
||||
// case "memory":
|
||||
// case "storage":
|
||||
// cal = new calWcapCachedCalendar();
|
||||
// break;
|
||||
default:
|
||||
cal = new calWcapCalendar();
|
||||
cal = new calWcapCalendar(
|
||||
null /* calId: indicates default calendar */,
|
||||
new calWcapSession() );
|
||||
cal.session.defaultCalendar = cal;
|
||||
break;
|
||||
}
|
||||
return cal.QueryInterface( iid );
|
||||
|
@ -147,6 +147,7 @@ function issueAsyncRequest( url, receiverFunc )
|
||||
logMessage( "issueAsyncRequest( \"" + url + "\" )", "opening channel." );
|
||||
var channel = getIoService().newChannel(
|
||||
url, "" /* charset */, null /* baseURI */ );
|
||||
channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
|
||||
loader.init( channel, reader, null /* context */, 0 /* segment size */ );
|
||||
}
|
||||
|
||||
@ -180,6 +181,7 @@ function issueSyncRequest( url, receiverFunc, bLogging )
|
||||
}
|
||||
var channel = getIoService().newChannel(
|
||||
url, "" /* charset */, null /* baseURI */ );
|
||||
channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
|
||||
var stream = channel.open();
|
||||
if (bLogging && LOG_LEVEL > 1) {
|
||||
logMessage( "issueSyncRequest( \"" + url + "\" )",
|
||||
|
@ -41,36 +41,75 @@
|
||||
var g_serverTimeDiffs = {};
|
||||
var g_allSupportedTimezones = {};
|
||||
|
||||
function calWcapSession( thatUri ) {
|
||||
function calWcapSession() {
|
||||
this.wrappedJSObject = this;
|
||||
// sensible default for user id login:
|
||||
var username = decodeURIComponent( thatUri.username );
|
||||
if (username != "") {
|
||||
var nColon = username.indexOf(':');
|
||||
this.m_userId = (nColon >= 0 ? username.substr(0, nColon) : username);
|
||||
}
|
||||
this.m_uri = thatUri.clone();
|
||||
this.m_uri.userPass = "";
|
||||
|
||||
this.m_observers = [];
|
||||
this.m_calIdToCalendar = {};
|
||||
// listen for shutdown, being logged out:
|
||||
// network:offline-about-to-go-offline will be fired for
|
||||
// XPCOM shutdown, too.
|
||||
// xxx todo: alternatively, add shutdown notifications to cal manager
|
||||
// xxx todo: how to simplify this for multiple topics?
|
||||
var observerService = Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService);
|
||||
.getService(Components.interfaces.nsIObserverService);
|
||||
observerService.addObserver( this, "quit-application",
|
||||
false /* don't hold weakly: xxx todo */ );
|
||||
observerService.addObserver( this, "network:offline-about-to-go-offline",
|
||||
false /* don't hold weakly: xxx todo */ );
|
||||
}
|
||||
calWcapSession.prototype = {
|
||||
m_uri: null,
|
||||
m_sessionId: null,
|
||||
m_userId: null,
|
||||
m_bNoLoginsAnymore: false,
|
||||
m_ifaces: [ Components.interfaces.calIWcapSession,
|
||||
Components.interfaces.nsIInterfaceRequestor,
|
||||
Components.interfaces.nsIClassInfo,
|
||||
Components.interfaces.nsISupports ],
|
||||
|
||||
get uri() { return this.m_uri; },
|
||||
// nsISupports:
|
||||
QueryInterface:
|
||||
function( iid )
|
||||
{
|
||||
for each ( var iface in this.m_ifaces ) {
|
||||
if (iid.equals( iface ))
|
||||
return this;
|
||||
}
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIClassInfo:
|
||||
getInterfaces:
|
||||
function( count )
|
||||
{
|
||||
count.value = this.m_ifaces.length;
|
||||
return this.m_ifaces;
|
||||
},
|
||||
get classDescription() {
|
||||
return calWcapCalendarModule.WcapSessionInfo.classDescription;
|
||||
},
|
||||
get contractID() {
|
||||
return calWcapCalendarModule.WcapSessionInfo.contractID;
|
||||
},
|
||||
get classID() {
|
||||
return calWcapCalendarModule.WcapSessionInfo.classID;
|
||||
},
|
||||
getHelperForLanguage: function( language ) { return null; },
|
||||
implementationLanguage:
|
||||
Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
|
||||
flags: 0,
|
||||
|
||||
// nsIInterfaceRequestor:
|
||||
getInterface:
|
||||
function( iid, instance )
|
||||
{
|
||||
if (iid.equals(Components.interfaces.nsIAuthPrompt)) {
|
||||
// use the window watcher service to get a nsIAuthPrompt impl
|
||||
return getWindowWatcher().getNewAuthPrompter(null);
|
||||
}
|
||||
else if (iid.equals(Components.interfaces.nsIPrompt)) {
|
||||
// use the window watcher service to get a nsIPrompt impl
|
||||
return getWindowWatcher().getNewPrompter(null);
|
||||
}
|
||||
Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return null;
|
||||
},
|
||||
|
||||
toString:
|
||||
function( msg )
|
||||
@ -92,17 +131,51 @@ calWcapSession.prototype = {
|
||||
{
|
||||
return logMessage( this.toString(), msg );
|
||||
},
|
||||
|
||||
// nsISupports:
|
||||
QueryInterface:
|
||||
function( iid )
|
||||
logError:
|
||||
function( err, context )
|
||||
{
|
||||
if (iid.equals(Components.interfaces.nsIObserver) ||
|
||||
iid.equals(Components.interfaces.nsISupports)) {
|
||||
return this;
|
||||
var str = ("error: " + errorToString(err));
|
||||
Components.utils.reportError( this.log( str, context ) );
|
||||
return str;
|
||||
},
|
||||
notifyError:
|
||||
function( err )
|
||||
{
|
||||
debugger;
|
||||
var str = this.logError( err );
|
||||
this.notifyObservers( "onError",
|
||||
[err instanceof Error ? -1 : err, str] );
|
||||
},
|
||||
|
||||
m_observers: null,
|
||||
notifyObservers:
|
||||
function( func, args )
|
||||
{
|
||||
this.m_observers.forEach(
|
||||
function( obj ) {
|
||||
try {
|
||||
obj[func].apply( obj, args );
|
||||
}
|
||||
catch (exc) {
|
||||
// don't call notifyError() here:
|
||||
Components.utils.reportError( exc );
|
||||
}
|
||||
} );
|
||||
},
|
||||
|
||||
addObserver:
|
||||
function( observer )
|
||||
{
|
||||
if (this.m_observers.indexOf( observer ) == -1) {
|
||||
this.m_observers.push( observer );
|
||||
}
|
||||
else
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
removeObserver:
|
||||
function( observer )
|
||||
{
|
||||
this.m_observers = this.m_observers.filter(
|
||||
function(x) { return x != observer; } );
|
||||
},
|
||||
|
||||
// nsIObserver:
|
||||
@ -125,8 +198,6 @@ calWcapSession.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
get userId() { return this.m_userId; },
|
||||
|
||||
getSupportedTimezones:
|
||||
function( bRefresh )
|
||||
{
|
||||
@ -219,6 +290,9 @@ calWcapSession.prototype = {
|
||||
return realm;
|
||||
},
|
||||
|
||||
m_sessionId: null,
|
||||
m_bNoLoginsAnymore: false,
|
||||
|
||||
getSessionId:
|
||||
function( timedOutSessionId )
|
||||
{
|
||||
@ -267,6 +341,11 @@ calWcapSession.prototype = {
|
||||
|
||||
this.getSupportedTimezones( true /* refresh */ );
|
||||
this.getServerTimeDiff( true /* refresh */ );
|
||||
// preread calprops for subscribed calendars:
|
||||
var cals = this.getSubscribedCalendars({});
|
||||
for each ( cal in cals ) {
|
||||
cal.getCalProps_(true /* async */);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (exc) {
|
||||
@ -289,7 +368,7 @@ calWcapSession.prototype = {
|
||||
Components.classes["@mozilla.org/passwordmanager;1"]
|
||||
.getService(Components.interfaces.nsIPasswordManager);
|
||||
|
||||
var outUser = { value: this.m_userId };
|
||||
var outUser = { value: this.userId };
|
||||
var outPW = { value: null };
|
||||
|
||||
var enumerator = passwordManager.enumerator;
|
||||
@ -332,7 +411,7 @@ calWcapSession.prototype = {
|
||||
else {
|
||||
this.log( "password entry found for user " + outUser.value );
|
||||
try {
|
||||
this.login( loginUri, outUser.value, outPW.value );
|
||||
this.login_( loginUri, outUser.value, outPW.value );
|
||||
}
|
||||
catch (exc) { // ignore silently
|
||||
}
|
||||
@ -370,8 +449,8 @@ calWcapSession.prototype = {
|
||||
// user/pw has been found previously,
|
||||
// but no login was possible,
|
||||
// try again using http here:
|
||||
this.login( loginUri,
|
||||
outUser.value, outPW.value );
|
||||
this.login_( loginUri,
|
||||
outUser.value, outPW.value );
|
||||
if (this.m_sessionId != null)
|
||||
return this.m_sessionId;
|
||||
}
|
||||
@ -416,7 +495,7 @@ calWcapSession.prototype = {
|
||||
savePW ))
|
||||
{
|
||||
try {
|
||||
this.login( loginUri, outUser.value, outPW.value );
|
||||
this.login_( loginUri, outUser.value, outPW.value );
|
||||
}
|
||||
catch (exc) {
|
||||
Components.utils.reportError( exc );
|
||||
@ -439,6 +518,34 @@ calWcapSession.prototype = {
|
||||
|
||||
return this.m_sessionId;
|
||||
},
|
||||
login_:
|
||||
function( loginUri, user, pw )
|
||||
{
|
||||
if (this.m_sessionId != null) {
|
||||
this.logout();
|
||||
}
|
||||
// currently, xml parsing at an early stage during process startup
|
||||
// does not work reliably, so use libical parsing for now:
|
||||
var str = issueSyncRequest(
|
||||
loginUri.spec + "login.wcap?fmt-out=text%2Fcalendar&user=" +
|
||||
encodeURIComponent(user) + "&password=" + encodeURIComponent(pw),
|
||||
null /* receiverFunc */, false /* no logging */ );
|
||||
var icalRootComp = getIcsService().parseICS( str );
|
||||
checkWcapIcalErrno( icalRootComp );
|
||||
var prop = icalRootComp.getFirstProperty( "X-NSCP-WCAP-SESSION-ID" );
|
||||
if (prop == null)
|
||||
throw new Error("missing X-NSCP-WCAP-SESSION-ID!");
|
||||
this.m_sessionId = prop.value;
|
||||
|
||||
// var xml = issueSyncXMLRequest(
|
||||
// loginUri.spec + "login.wcap?fmt-out=text%2Fxml&user=" +
|
||||
// encodeURIComponent(user) + "&password=" + encodeURIComponent(pw) );
|
||||
// checkWcapXmlErrno( xml );
|
||||
// this.m_sessionId = xml.getElementsByTagName(
|
||||
// "X-NSCP-WCAP-SESSION-ID" ).item(0).textContent;
|
||||
this.m_userId = user;
|
||||
this.log( "WCAP login succeeded." );
|
||||
},
|
||||
|
||||
getServerInfo:
|
||||
function( uri )
|
||||
@ -496,33 +603,112 @@ calWcapSession.prototype = {
|
||||
"loginDialog.text", loginTextVars, loginTextVars.length );
|
||||
},
|
||||
|
||||
login:
|
||||
function( loginUri, user, pw )
|
||||
getCommandUrl:
|
||||
function( wcapCommand )
|
||||
{
|
||||
if (this.m_sessionId != null) {
|
||||
this.logout();
|
||||
}
|
||||
// currently, xml parsing at an early stage during process startup
|
||||
// does not work reliably, so use libical parsing for now:
|
||||
var str = issueSyncRequest(
|
||||
loginUri.spec + "login.wcap?fmt-out=text%2Fcalendar&user=" +
|
||||
encodeURIComponent(user) + "&password=" + encodeURIComponent(pw),
|
||||
null /* receiverFunc */, false /* no logging */ );
|
||||
var icalRootComp = getIcsService().parseICS( str );
|
||||
checkWcapIcalErrno( icalRootComp );
|
||||
var prop = icalRootComp.getFirstProperty( "X-NSCP-WCAP-SESSION-ID" );
|
||||
if (prop == null)
|
||||
throw new Error("missing X-NSCP-WCAP-SESSION-ID!");
|
||||
this.m_sessionId = prop.value;
|
||||
if (this.uri == null)
|
||||
throw new Error("no URI!");
|
||||
// ensure established session, so userId is set;
|
||||
// (calId defaults to userId) if not set:
|
||||
this.getSessionId();
|
||||
return (this.uri.spec + wcapCommand + ".wcap?appid=mozilla-lightning");
|
||||
},
|
||||
|
||||
issueRequest:
|
||||
function( url, issueFunc, dataConvFunc, receiverFunc )
|
||||
{
|
||||
var sessionId = this.getSessionId();
|
||||
|
||||
// var xml = issueSyncXMLRequest(
|
||||
// loginUri.spec + "login.wcap?fmt-out=text%2Fxml&user=" +
|
||||
// encodeURIComponent(user) + "&password=" + encodeURIComponent(pw) );
|
||||
// checkWcapXmlErrno( xml );
|
||||
// this.m_sessionId = xml.getElementsByTagName(
|
||||
// "X-NSCP-WCAP-SESSION-ID" ).item(0).textContent;
|
||||
this.m_userId = user;
|
||||
this.log( "WCAP login succeeded." );
|
||||
var this_ = this;
|
||||
issueFunc(
|
||||
url + ("&id=" + sessionId),
|
||||
function( data ) {
|
||||
var wcapResponse = new WcapResponse();
|
||||
try {
|
||||
try {
|
||||
wcapResponse.data = dataConvFunc(
|
||||
data, wcapResponse );
|
||||
}
|
||||
catch (exc) {
|
||||
if (exc == Components.interfaces.
|
||||
calIWcapErrors.WCAP_LOGIN_FAILED) /* timeout */ {
|
||||
// getting a new session will throw any exception in
|
||||
// this block, thus it is notified into receiverFunc
|
||||
this_.getSessionId(
|
||||
sessionId /* (old) timed-out session */ );
|
||||
// try again:
|
||||
this_.issueRequest(
|
||||
url, issueFunc, dataConvFunc, receiverFunc );
|
||||
return;
|
||||
}
|
||||
throw exc; // rethrow
|
||||
}
|
||||
}
|
||||
catch (exc) {
|
||||
// setting the request's exception will rethrow exception
|
||||
// when request's data is retrieved.
|
||||
wcapResponse.exception = exc;
|
||||
}
|
||||
receiverFunc( wcapResponse );
|
||||
} );
|
||||
},
|
||||
|
||||
issueAsyncRequest:
|
||||
function( url, dataConvFunc, receiverFunc )
|
||||
{
|
||||
this.issueRequest(
|
||||
url, issueAsyncRequest, dataConvFunc, receiverFunc );
|
||||
},
|
||||
|
||||
issueSyncRequest:
|
||||
function( url, dataConvFunc, receiverFunc )
|
||||
{
|
||||
var ret = null;
|
||||
this.issueRequest(
|
||||
url, issueSyncRequest,
|
||||
dataConvFunc,
|
||||
function( wcapResponse ) {
|
||||
if (receiverFunc) {
|
||||
receiverFunc( wcapResponse );
|
||||
}
|
||||
ret = wcapResponse.data; // may throw
|
||||
} );
|
||||
return ret;
|
||||
},
|
||||
|
||||
// calIWcapSession:
|
||||
|
||||
m_uri: null,
|
||||
get uri() { return this.m_uri; },
|
||||
set uri( thatUri )
|
||||
{
|
||||
if (this.m_uri == null || thatUri == null ||
|
||||
!this.m_uri.equals(thatUri))
|
||||
{
|
||||
this.logout();
|
||||
this.m_uri = null;
|
||||
if (thatUri != null) {
|
||||
// sensible default for user id login:
|
||||
var username = decodeURIComponent( thatUri.username );
|
||||
if (username != "") {
|
||||
var nColon = username.indexOf(':');
|
||||
this.m_userId =
|
||||
(nColon >= 0 ? username.substr(0, nColon) : username);
|
||||
}
|
||||
this.m_uri = thatUri.clone();
|
||||
this.m_uri.userPass = "";
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
m_userId: null,
|
||||
get userId() { return this.m_userId; },
|
||||
|
||||
login:
|
||||
function()
|
||||
{
|
||||
this.logout(); // assure being logged out
|
||||
this.getSessionId();
|
||||
},
|
||||
|
||||
logout:
|
||||
@ -544,18 +730,278 @@ calWcapSession.prototype = {
|
||||
Components.utils.reportError( exc );
|
||||
}
|
||||
this.m_sessionId = null;
|
||||
this.m_userId = null;
|
||||
}
|
||||
this.m_userId = null;
|
||||
// ask next time we log in:
|
||||
var this_ = this;
|
||||
g_httpHosts = g_httpHosts.filter(
|
||||
function(hostEntry) {
|
||||
return (hostEntry.m_host != this_.uri.hostPort); } );
|
||||
this.m_bNoLoginsAnymore = false;
|
||||
},
|
||||
|
||||
getWcapErrorString:
|
||||
function( rc )
|
||||
{
|
||||
return wcapErrorToString(rc);
|
||||
},
|
||||
|
||||
get defaultCalendar() {
|
||||
return this.getCalendarByCalId(this.userId);
|
||||
},
|
||||
set defaultCalendar(cal) {
|
||||
this.m_defaultCalendar = cal;
|
||||
},
|
||||
|
||||
m_defaultCalendar: null,
|
||||
m_calIdToCalendar: {},
|
||||
getCalendarByCalId:
|
||||
function( calId )
|
||||
{
|
||||
if (calId == null || this.userId == calId) {
|
||||
if (this.m_defaultCalendar == null)
|
||||
this.m_defaultCalendar = new calWcapCalendar(this.userId);
|
||||
return this.m_defaultCalendar;
|
||||
}
|
||||
else {
|
||||
var key = encodeURIComponent(calId);
|
||||
var ret = this.m_calIdToCalendar[key];
|
||||
if (!ret) {
|
||||
ret = new calWcapCalendar( calId, this );
|
||||
this.m_calIdToCalendar[key] = ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
},
|
||||
|
||||
getCalendars:
|
||||
function( out_count, bGetOwnedCals )
|
||||
{
|
||||
var list = this.getUserPreferences(
|
||||
bGetOwnedCals ? "X-NSCP-WCAP-PREF-icsCalendarOwned"
|
||||
: "X-NSCP-WCAP-PREF-icsSubscribed", {} );
|
||||
var ret = [];
|
||||
for each( var item in list ) {
|
||||
var ar = item.split(',');
|
||||
// ',', '$' are not encoded. ',' can be handled here. WTF.
|
||||
for each ( a in ar ) {
|
||||
var dollar = a.indexOf('$');
|
||||
if (dollar >= 0) {
|
||||
ret.push(
|
||||
this.getCalendarByCalId( a.substring(0, dollar) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
out_count.value = ret.length;
|
||||
return ret;
|
||||
},
|
||||
getOwnedCalendars:
|
||||
function( out_count )
|
||||
{
|
||||
return this.getCalendars( out_count, true );
|
||||
},
|
||||
getSubscribedCalendars:
|
||||
function( out_count )
|
||||
{
|
||||
return this.getCalendars( out_count, false );
|
||||
},
|
||||
|
||||
createCalendar:
|
||||
function( calId, name, bAllowDoubleBooking, bSetCalProps, bAddToSubscribed )
|
||||
{
|
||||
try {
|
||||
var url = this.getCommandUrl( "createcalendar" );
|
||||
url += ("&allowdoublebook=" + (bAllowDoubleBooking ? "1" : "0"));
|
||||
url += ("&set_calprops=" + (bSetCalProps ? "1" : "0"));
|
||||
url += ("&subscribe=" + (bAddToSubscribed ? "1" : "0"));
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
// xxx todo: name undocumented!
|
||||
url += ("&name=" + encodeURIComponent(name));
|
||||
// xxx todo: what about categories param???
|
||||
this.issueSyncRequest( url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
this.m_userPrefs = null; // reread prefs
|
||||
return this.getCalendarByCalId( this.userId + ":" + calId );
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
},
|
||||
|
||||
deleteCalendar:
|
||||
function( calId, bRemoveFromSubscribed )
|
||||
{
|
||||
try {
|
||||
var url = this.getCommandUrl( "deletecalendar" );
|
||||
url += ("&unsubscribe=" + (bRemoveFromSubscribed ? "1" : "0"));
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
this.issueSyncRequest( url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
this.m_userPrefs = null; // reread prefs
|
||||
this.m_calIdToCalendar[encodeURIComponent(calId)] = null;
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
},
|
||||
|
||||
modifyCalendarSubscriptions:
|
||||
function( calIds, bSubscribe )
|
||||
{
|
||||
try {
|
||||
var url = this.getCommandUrl(
|
||||
bSubscribe ? "subscribe_calendars" : "unsubscribe_calendars" );
|
||||
var calId = "";
|
||||
for ( var i = 0; i < calIds.length; ++i ) {
|
||||
if (i > 0)
|
||||
calId += ";";
|
||||
calId += encodeURIComponent(calIds[i]);
|
||||
}
|
||||
url += ("&calid=" + calId);
|
||||
this.issueSyncRequest( url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
this.m_userPrefs = null; // reread prefs
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
},
|
||||
|
||||
subscribeToCalendars:
|
||||
function( count, calIds )
|
||||
{
|
||||
this.modifyCalendarSubscriptions( calIds, true );
|
||||
},
|
||||
|
||||
unsubscribeFromCalendars:
|
||||
function( count, calIds )
|
||||
{
|
||||
this.modifyCalendarSubscriptions( calIds, false );
|
||||
},
|
||||
|
||||
m_userPrefs: null,
|
||||
getUserPreferences:
|
||||
function( prefName, out_count )
|
||||
{
|
||||
try {
|
||||
if (this.m_userPrefs == null) {
|
||||
var url = this.getCommandUrl( "get_userprefs" );
|
||||
url += ("&userid=" + encodeURIComponent(this.userId));
|
||||
this.m_userPrefs = this.issueSyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
}
|
||||
var ret = [];
|
||||
var nodeList = this.m_userPrefs.getElementsByTagName(prefName);
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
ret.push( trimString(nodeList.item(i).textContent) );
|
||||
}
|
||||
out_count.value = ret.length;
|
||||
return ret;
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
},
|
||||
|
||||
getFreeBusyTimes_resp:
|
||||
function( wcapResponse, calId, iListener, requestId )
|
||||
{
|
||||
try {
|
||||
var xml = wcapResponse.data; // first statement, may throw
|
||||
if (iListener != null) {
|
||||
var ret = [];
|
||||
var nodeList = xml.getElementsByTagName("FB");
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
var item = nodeList.item(i);
|
||||
var str = item.textContent;
|
||||
var slash = str.indexOf( '/' );
|
||||
var start = new CalDateTime();
|
||||
start.icalString = str.substr( 0, slash );
|
||||
var end = new CalDateTime();
|
||||
end.icalString = str.substr( slash + 1 );
|
||||
var entry = {
|
||||
isBusyEntry:
|
||||
(item.attributes.getNamedItem("FBTYPE").nodeValue
|
||||
== "BUSY"),
|
||||
dtRangeStart: start,
|
||||
dtRangeEnd: end
|
||||
};
|
||||
ret.push( entry );
|
||||
}
|
||||
iListener.onGetFreeBusyTimes(
|
||||
Components.results.NS_OK,
|
||||
requestId, calId, ret.length, ret );
|
||||
}
|
||||
if (LOG_LEVEL > 0) {
|
||||
this.log( "getFreeBusyTimes_resp() calId=" + calId + ", " +
|
||||
getWcapRequestStatusString(xml) );
|
||||
}
|
||||
}
|
||||
catch (exc) {
|
||||
const calIWcapErrors = Components.interfaces.calIWcapErrors;
|
||||
switch (exc) {
|
||||
case calIWcapErrors.WCAP_NO_ERRNO: // workaround
|
||||
case calIWcapErrors.WCAP_ACCESS_DENIED_TO_CALENDAR:
|
||||
case calIWcapErrors.WCAP_CALENDAR_DOES_NOT_EXIST:
|
||||
this.log( "getFreeBusyTimes_resp() ignored: " +
|
||||
errorToString(exc) ); // no error
|
||||
break;
|
||||
default:
|
||||
this.notifyError( exc );
|
||||
break;
|
||||
}
|
||||
if (iListener != null)
|
||||
iListener.onGetFreeBusyTimes( exc, requestId, calId, 0, [] );
|
||||
}
|
||||
},
|
||||
|
||||
getFreeBusyTimes:
|
||||
function( calId, rangeStart, rangeEnd, bBusyOnly, iListener,
|
||||
bAsync, requestId )
|
||||
{
|
||||
try {
|
||||
// assure DATETIMEs:
|
||||
if (rangeStart != null && rangeStart.isDate) {
|
||||
rangeStart = rangeStart.clone();
|
||||
rangeStart.isDate = false;
|
||||
}
|
||||
if (rangeEnd != null && rangeEnd.isDate) {
|
||||
rangeEnd = rangeEnd.clone();
|
||||
rangeEnd.isDate = false;
|
||||
}
|
||||
var zRangeStart = getIcalUTC(rangeStart);
|
||||
var zRangeEnd = getIcalUTC(rangeEnd);
|
||||
this.log( "getFreeBusyTimes():\n\trangeStart=" + zRangeStart +
|
||||
",\n\trangeEnd=" + zRangeEnd );
|
||||
|
||||
var url = this.getCommandUrl( "get_freebusy" );
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
url += ("&busyonly=" + (bBusyOnly ? "1" : "0"));
|
||||
url += ("&dtstart=" + zRangeStart);
|
||||
url += ("&dtend=" + zRangeEnd);
|
||||
url += "&fmt-out=text%2Fxml";
|
||||
|
||||
var this_ = this;
|
||||
function resp( wcapResponse ) {
|
||||
this_.getFreeBusyTimes_resp(
|
||||
wcapResponse, calId, iListener, requestId );
|
||||
}
|
||||
if (bAsync)
|
||||
this.issueAsyncRequest( url, stringToXml, resp );
|
||||
else
|
||||
this.issueSyncRequest( url, stringToXml, resp );
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
if (iListener != null)
|
||||
iListener.onGetFreeBusyTimes( exc, requestId, calId, 0, [] );
|
||||
throw exc;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
g_httpHosts = [];
|
||||
var g_httpHosts = [];
|
||||
function confirmUnsecureLogin( uri )
|
||||
{
|
||||
var host = uri.hostPort;
|
||||
@ -575,15 +1021,3 @@ function confirmUnsecureLogin( uri )
|
||||
return bConfirmed;
|
||||
}
|
||||
|
||||
g_sessions = {};
|
||||
function getSession( uri )
|
||||
{
|
||||
var session = g_sessions[uri.spec];
|
||||
if (!session) {
|
||||
logMessage( "getSession()", "entering session for uri=" + uri.spec );
|
||||
var session = new calWcapSession( uri );
|
||||
g_sessions[uri.spec] = session;
|
||||
}
|
||||
return session;
|
||||
}
|
||||
|
||||
|
@ -299,6 +299,11 @@ function forEachIcalComponent( icalRootComp, componentType, func, maxResult )
|
||||
}
|
||||
}
|
||||
|
||||
function trimString( str )
|
||||
{
|
||||
return str.replace( /(^\s+|\s+$)/g, "" );
|
||||
}
|
||||
|
||||
function getTime()
|
||||
{
|
||||
var ret = new CalDateTime();
|
||||
|
@ -51,6 +51,7 @@ XPIDLSRCS = calIWcapCalendar.idl \
|
||||
calIWcapErrors.idl \
|
||||
calIWcapFreeBusyEntry.idl \
|
||||
calIWcapFreeBusyListener.idl \
|
||||
calIWcapSession.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -38,9 +38,8 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "calICalendar.idl"
|
||||
#include "calIWcapFreeBusyListener.idl"
|
||||
#include "calIDateTime.idl"
|
||||
#include "calIICSService.idl"
|
||||
interface calIWcapSession;
|
||||
|
||||
/** Adds WCAP specific capabilities.
|
||||
*/
|
||||
@ -48,164 +47,46 @@
|
||||
interface calIWcapCalendar : calICalendar
|
||||
{
|
||||
/**
|
||||
* Current userId; if the user is not logged in, a dialog will prompt for.
|
||||
* User session this calendar instance belongs to.
|
||||
*/
|
||||
readonly attribute string userId;
|
||||
readonly attribute calIWcapSession session;
|
||||
|
||||
/**
|
||||
* Calendar description.
|
||||
*/
|
||||
readonly attribute string description;
|
||||
|
||||
/**
|
||||
* Current calId the calendar instance acts on; defaults to userId.
|
||||
*/
|
||||
attribute string calId;
|
||||
/*readonly xxx todo*/ attribute string calId;
|
||||
|
||||
/**
|
||||
* Whether the currently selected calendar belongs to user.
|
||||
*/
|
||||
readonly attribute boolean isOwnedCalendar;
|
||||
|
||||
// /**
|
||||
// * 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 for specified calId.
|
||||
* Gets calendar properties.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param propName property name (e.g. X-S1CS-CALPROPS-COMMON-NAME)
|
||||
* @param calId a calid, "mailto:rfc822addr" or
|
||||
* empty string (=> current user's calId)
|
||||
* @return array of property values
|
||||
*/
|
||||
void getCalendarProperties(
|
||||
in string propName,
|
||||
in string calId,
|
||||
out unsigned long count,
|
||||
[array, size_is(count), retval] out string properties );
|
||||
|
||||
/**
|
||||
* Gets a text for an error code.
|
||||
*
|
||||
* @param rc error code defined in calIWcapErrors
|
||||
* @return error string
|
||||
* @exception NS_ERROR_INVALID_ARG
|
||||
*/
|
||||
string getWcapErrorString( in unsigned long rc );
|
||||
|
||||
/**
|
||||
* Creates a new calendar for user.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param calId calendar's calId (portion);
|
||||
* without user's id, e.g. "test-cal".
|
||||
* valid characters for the calId parameter are:
|
||||
* - Alphabet characters (A-Z, a-z)
|
||||
* - Numeric characters (0-9)
|
||||
* - Three special characters
|
||||
* - Dash (-)
|
||||
* - Underscore (_)
|
||||
* - Period (.)
|
||||
* @param name calendar's name, e.g. "My Work Cal"
|
||||
* @param bAllowDoubleBooking whether double booking (events/todos) is
|
||||
* allowed
|
||||
* @param bSetCalProps whether properties of the new calendar are set
|
||||
* @param bAddToSubscribed allows a user to specify if the newly
|
||||
* created calendar should be added to the
|
||||
* user’s subscribed calendar list
|
||||
* @return calId of created calendar
|
||||
*/
|
||||
string createCalendar(
|
||||
in string calId,
|
||||
in string name,
|
||||
in boolean bAllowDoubleBooking,
|
||||
in boolean bSetCalProps,
|
||||
in boolean bAddToSubscribed );
|
||||
|
||||
/**
|
||||
* Deletes a calendar.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param calId full calId (incl. "<user>:")
|
||||
* @param bRemoveFromSubscribed whether calendar ought to be removed
|
||||
* from subscription list
|
||||
*/
|
||||
void deleteCalendar(
|
||||
in string calId,
|
||||
in boolean bRemoveFromSubscribed );
|
||||
|
||||
/**
|
||||
* Gets own calendars.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @return owned calendars (string array of "calId1$Description1", ...)
|
||||
*/
|
||||
void getOwnedCalendars(
|
||||
out unsigned long count,
|
||||
[array, size_is(count), retval] out string ownCalendars );
|
||||
|
||||
/**
|
||||
* Gets subscribed calendars.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @return subscribed calendars (string array of "calId1$Description1",...)
|
||||
*/
|
||||
void getSubscribedCalendars(
|
||||
out unsigned long count,
|
||||
[array, size_is(count), retval] out string subscribedCalendars );
|
||||
|
||||
/**
|
||||
* Subscribe to calendar(s).
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param count number of calIds
|
||||
* @param calIds array of calIds (calid or "mailto:rfc822addr")
|
||||
*/
|
||||
void subscribeToCalendars(
|
||||
in unsigned long count,
|
||||
[array, size_is(count)] in string calIds );
|
||||
|
||||
/**
|
||||
* Unsubscribe from calendar(s).
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param count number of calIds
|
||||
* @param calIds array of calIds (calid or "mailto:rfc822addr")
|
||||
*/
|
||||
void unsubscribeFromCalendars(
|
||||
in unsigned long count,
|
||||
[array, size_is(count)] in string calIds );
|
||||
|
||||
/**
|
||||
* Gets free-busy entries for calid.
|
||||
* Results are notifies to passed listener instance.
|
||||
* An error is notified to all registered calIObservers and
|
||||
* to calIWcapFreeBusyListener::onGetFreeBusyTimes with rc != NS_OK.
|
||||
* Additionally, when an error occurs within getFreeBusyTimes,
|
||||
* the error is also thrown.
|
||||
*
|
||||
* @param calId a calid or "mailto:rfc822addr"
|
||||
* @param dtRangeStart start time of free-busy search
|
||||
* @param dtRangeEnd end time of free-busy search
|
||||
* @param bBusyOnly whether to return busy entries only
|
||||
* @param iListener listener receiving results
|
||||
* @param bAsync whether the listener receives results asynchronously
|
||||
* @param requestId request id to distinguish asynchronous requests
|
||||
*/
|
||||
void getFreeBusyTimes(
|
||||
in string calId,
|
||||
in calIDateTime dtRangeStart,
|
||||
in calIDateTime dtRangeEnd,
|
||||
in boolean bBusyOnly,
|
||||
in calIWcapFreeBusyListener iListener,
|
||||
in boolean bAsync,
|
||||
in unsigned long requestId );
|
||||
|
||||
/** xxx todo: to be moved to calIOperationListener?
|
||||
*/
|
||||
const unsigned long SYNC = 5;
|
||||
|
||||
/* xxx todo: additional filters sensible for calICalendar, too?
|
||||
claiming bits 24-30 for now.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Scope: Attendee
|
||||
* The event or todo is an invitation from another
|
||||
@ -249,7 +130,13 @@ interface calIWcapCalendar : calICalendar
|
||||
* 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? */
|
||||
/** xxx todo: to be moved to calIOperationListener?
|
||||
*/
|
||||
const unsigned long SYNC = 5;
|
||||
|
||||
/**
|
||||
* Syncs in changes since time <code>dtFrom</code>.
|
||||
* The passed <code>iListener</code> receives a
|
||||
|
@ -38,6 +38,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "calIWcapFreeBusyEntry.idl"
|
||||
#include "calIWcapCalendar.idl"
|
||||
|
||||
[scriptable, uuid(4498E0D0-04EC-43a3-92E0-560667696CF3)]
|
||||
interface calIWcapFreeBusyListener : nsISupports
|
||||
|
228
calendar/providers/wcap/public/calIWcapSession.idl
Executable file
228
calendar/providers/wcap/public/calIWcapSession.idl
Executable file
@ -0,0 +1,228 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
|
||||
* Portions created by Sun Microsystems are Copyright (C) 2006 Sun
|
||||
* Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Original Author: Daniel Boelzle (daniel.boelzle@sun.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "calIWcapCalendar.idl"
|
||||
#include "calIWcapFreeBusyListener.idl"
|
||||
|
||||
/**
|
||||
* WCAP session.
|
||||
*/
|
||||
[scriptable, uuid(477B4534-C297-40a1-ADF2-5A7E2A81816A)]
|
||||
interface calIWcapSession : nsISupports
|
||||
{
|
||||
/**
|
||||
* Setting this URI causes the session to be disconnected.
|
||||
*/
|
||||
attribute nsIURI uri;
|
||||
|
||||
/**
|
||||
* User that has established this session.
|
||||
* Reading this attribute prompts for login if the session has not yet
|
||||
* been established.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*/
|
||||
readonly attribute string userId;
|
||||
|
||||
/**
|
||||
* Explicitly performs a session establishment.
|
||||
* Commonly not needed, because any attempt to get a calendar instance
|
||||
* will establish a session automatically.
|
||||
* If the user is alread logged in, she will be logged out before.
|
||||
* UI will prompt for a userId and password.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*/
|
||||
void login();
|
||||
|
||||
/**
|
||||
* Explicitly performs a session logout.
|
||||
* Commonly not needed, because the user will be logged out upon
|
||||
* "network:offline-about-to-go-offline" and "quit-application"
|
||||
* automatically.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*/
|
||||
void logout();
|
||||
|
||||
/**
|
||||
* Gets a text for an error code.
|
||||
*
|
||||
* @param rc error code defined in calIWcapErrors
|
||||
* @return error string
|
||||
* @exception NS_ERROR_INVALID_ARG
|
||||
*/
|
||||
string getWcapErrorString( in unsigned long rc );
|
||||
|
||||
/**
|
||||
* The user's default calendar.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*/
|
||||
readonly attribute calIWcapCalendar defaultCalendar;
|
||||
|
||||
/**
|
||||
* Gets a calendar instance for the passed calId using this session.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param calId full calId (incl. "<user>:")
|
||||
* @return calendar instance
|
||||
*/
|
||||
calIWcapCalendar getCalendarByCalId( in string calId );
|
||||
|
||||
/**
|
||||
* Gets calendars where the user is the primary owner
|
||||
* (including default calendar).
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @return array of owned calendars
|
||||
*/
|
||||
void getOwnedCalendars(
|
||||
out unsigned long count,
|
||||
[array, size_is(count), retval] out calIWcapCalendar ownedCals );
|
||||
|
||||
/**
|
||||
* Gets subscribed calendars (may include calendars where the user
|
||||
* is the primary owner).
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @return array of subscribed calendars
|
||||
*/
|
||||
void getSubscribedCalendars(
|
||||
out unsigned long count,
|
||||
[array, size_is(count), retval] out calIWcapCalendar subscribedCals );
|
||||
|
||||
/**
|
||||
* Creates a new calendar for the session's user.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param calId calendar's calId (portion);
|
||||
* without user's id, e.g. "test-cal".
|
||||
* valid characters for the calId parameter are:
|
||||
* - Alphabet characters (A-Z, a-z)
|
||||
* - Numeric characters (0-9)
|
||||
* - Three special characters
|
||||
* - Dash (-)
|
||||
* - Underscore (_)
|
||||
* - Period (.)
|
||||
* @param name calendar's name, e.g. "My Work Cal"
|
||||
* @param bAllowDoubleBooking whether double booking (events/todos) is
|
||||
* allowed
|
||||
* @param bSetCalProps whether properties of the new calendar are set
|
||||
* @param bAddToSubscribed allows a user to specify if the newly
|
||||
* created calendar should be added to the
|
||||
* user’s subscribed calendar list
|
||||
* @return created calendar
|
||||
*/
|
||||
calIWcapCalendar createCalendar(
|
||||
in string calId,
|
||||
in string name,
|
||||
in boolean bAllowDoubleBooking,
|
||||
in boolean bSetCalProps,
|
||||
in boolean bAddToSubscribed );
|
||||
|
||||
/**
|
||||
* Deletes a calendar.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param calId full calId (incl. "<user>:")
|
||||
* @param bRemoveFromSubscribed whether calendar ought to be removed
|
||||
* from subscription list
|
||||
*/
|
||||
void deleteCalendar(
|
||||
in string calId,
|
||||
in boolean bRemoveFromSubscribed );
|
||||
|
||||
/**
|
||||
* Subscribe to calendar(s).
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param count number of calIds
|
||||
* @param calIds array of calIds (calid or "mailto:rfc822addr")
|
||||
*/
|
||||
void subscribeToCalendars(
|
||||
in unsigned long count,
|
||||
[array, size_is(count)] in string calIds );
|
||||
|
||||
/**
|
||||
* Unsubscribe from calendar(s).
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param count number of calIds
|
||||
* @param calIds array of calIds (calid or "mailto:rfc822addr")
|
||||
*/
|
||||
void unsubscribeFromCalendars(
|
||||
in unsigned long count,
|
||||
[array, size_is(count)] in string calIds );
|
||||
|
||||
/**
|
||||
* Gets the user's preferences.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param prefName preference name
|
||||
* @return array of preference values
|
||||
*/
|
||||
void getUserPreferences(
|
||||
in string prefName,
|
||||
out unsigned long count,
|
||||
[array, size_is(count), retval] out string properties );
|
||||
|
||||
/* xxx todo freebusy: separate into own interface? */
|
||||
/**
|
||||
* Gets free-busy entries for calid.
|
||||
* Results are notifies to passed listener instance.
|
||||
* An error is notified to all registered calIObservers and
|
||||
* to calIWcapFreeBusyListener::onGetFreeBusyTimes with rc != NS_OK.
|
||||
* Additionally, when an error occurs within getFreeBusyTimes,
|
||||
* the error is also thrown.
|
||||
*
|
||||
* @param calId a calid or "mailto:rfc822addr"
|
||||
* @param dtRangeStart start time of free-busy search
|
||||
* @param dtRangeEnd end time of free-busy search
|
||||
* @param bBusyOnly whether to return busy entries only
|
||||
* @param iListener listener receiving results
|
||||
* @param bAsync whether the listener receives results asynchronously
|
||||
* @param requestId request id to distinguish asynchronous requests
|
||||
*/
|
||||
void getFreeBusyTimes(
|
||||
in string calId,
|
||||
in calIDateTime dtRangeStart,
|
||||
in calIDateTime dtRangeEnd,
|
||||
in boolean bBusyOnly,
|
||||
in calIWcapFreeBusyListener iListener,
|
||||
in boolean bAsync,
|
||||
in unsigned long requestId );
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user