Bug 370146 API enhancement: Searching for calendars; r=philipp

git-svn-id: svn://10.0.0.236/trunk@238583 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
daniel.boelzle%sun.com 2007-11-06 17:24:18 +00:00
parent 61c30201a9
commit 209b07d631
10 changed files with 266 additions and 50 deletions

View File

@ -81,6 +81,7 @@ XPIDLSRCS = calIAlarmService.idl \
calITransactionManager.idl \
calIOperation.idl \
calIFreeBusyProvider.idl \
calICalendarSearchProvider.idl \
$(NULL)
EXPORTS = calBaseCID.h

View File

@ -0,0 +1,92 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 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 Sun Microsystems code.
*
* The Initial Developer of the Original Code is
* Sun Microsystems, Inc.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Daniel Boelzle <daniel.boelzle@sun.com>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface calIOperation;
interface calIGenericOperationListener;
[scriptable, uuid(306DA1C9-DB54-4ef3-B27E-FEA709F638FF)]
interface calICalendarSearchProvider : nsISupports
{
/**
* Specifies whether the search string should exactly match.
*/
const unsigned long HINT_EXACT_MATCH = 1;
/* ...possibly more to come... */
/**
* Searches for calendars matching the specified search string.
* It's up to the search provider what properties of a calendar
* it takes into account for the search. The passed hints serve
* for optimization purposes. Callers need to keep in mind that
* providers may not be able to implement all of the stated hints
* passed, thus are required to filter further if necessary.
* Results are notified to the passed listener interface.
*
* @param aString search string to match
* @param aHints search hints
* @param aMaxResults maximum number of results
* (0 denotes provider specific maximum)
* @param aListener called with an array of calICalendar objects
* @return optional operation handle to track the operation
*/
calIOperation searchForCalendars(in AUTF8String aString,
in unsigned long aHints,
in unsigned long aMaxResults,
in calIGenericOperationListener aListener);
};
/**
* This service acts as a central access point for calendar lookup.
* A search request will be multiplexed to all added search providers.
* Adding a search provider is transient.
*/
[scriptable, uuid(2F2055CA-F558-4dc8-A1D4-11384A00E85C)]
interface calICalendarSearchService : calICalendarSearchProvider
{
/**
* Adds a new search provider.
*/
void addProvider(in calICalendarSearchProvider aProvider);
/**
* Removes a search provider.
*/
void removeProvider(in calICalendarSearchProvider aProvider);
};

View File

@ -100,6 +100,7 @@ EXTRA_SCRIPTS = \
calWeekTitleService.js \
calTransactionManager.js \
calFreeBusyService.js \
calCalendarSearchService.js \
$(NULL)
# Use NSINSTALL to make the directory, as there's no mtime to preserve.

View File

@ -0,0 +1,139 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 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 Sun Microsystems code.
*
* The Initial Developer of the Original Code is
* Sun Microsystems, Inc.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Daniel Boelzle <daniel.boelzle@sun.com>
*
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
function calCalendarSearchListener(numOperations, finalListener) {
this.mFinalListener = finalListener;
this.mNumOperations = numOperations;
this.mResults = [];
var this_ = this;
function cancelFunc() { // operation group has been cancelled
this_.notifyResult(null);
}
this.opGroup = new calOperationGroup(cancelFunc);
}
calCalendarSearchListener.prototype = {
mFinalListener: null,
mNumOperations: 0,
opGroup: null,
notifyResult: function calCalendarSearchListener_notifyResult(result) {
var listener = this.mFinalListener
if (listener) {
if (!this.opGroup.isPending) {
this.mFinalListener = null;
}
listener.onResult(this.opGroup, result);
}
},
// calIGenericOperationListener:
onResult: function calCalendarSearchListener_onResult(aOperation, aResult) {
if (this.mFinalListener) {
if (!aOperation || !aOperation.isPending) {
--this.mNumOperations;
if (this.mNumOperations == 0) {
this.opGroup.notifyCompleted();
}
}
if (aResult) {
this.notifyResult(aResult);
}
}
}
};
const calCalendarSearchService_ifaces = [ Components.interfaces.nsISupports,
Components.interfaces.calICalendarSearchProvider,
Components.interfaces.calICalendarSearchService,
Components.interfaces.nsIClassInfo ];
function calCalendarSearchService() {
this.wrappedJSObject = this;
this.mProviders = new calInterfaceBag(Components.interfaces.calICalendarSearchProvider);
}
calCalendarSearchService.prototype = {
mProviders: null,
QueryInterface: function calCalendarSearchService_QueryInterface(aIID) {
ensureIID(calCalendarSearchService_ifaces, aIID);
return this;
},
// nsIClassInfo:
getInterfaces: function calCalendarSearchService_getInterfaces(count) {
count.value = calCalendarSearchService_ifaces.length;
return calCalendarSearchService_ifaces;
},
getHelperForLanguage: function calCalendarSearchService_getHelperForLanguage(language) {
return null;
},
contractID: "@mozilla.org/calendar/calendarsearch-service;1",
classDescription: "Calendar Search Service",
classID: Components.ID("{F5F743CD-8997-428e-BC1B-644E73F61203}"),
implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
flags: 0,
// calICalendarSearchProvider:
searchForCalendars: function calCalendarSearchService_searchForCalendars(aString,
aHints,
aMaxResults,
aListener) {
var groupListener = new calCalendarSearchListener(this.mProviders.size, aListener);
function searchForCalendars_(provider) {
try {
groupListener.opGroup.add(provider.searchForCalendars(aString,
aHints,
aMaxResults,
groupListener));
} catch (exc) {
Components.utils.reportError(exc);
groupListener.onResult(null, []); // dummy to adopt mNumOperations
}
}
this.mProviders.forEach(searchForCalendars_);
return groupListener.opGroup;
},
// calICalendarSearchService:
addProvider: function calCalendarSearchService_addProvider(aProvider) {
this.mProviders.add(aProvider);
},
removeProvider: function calCalendarSearchService_removeProvider(aProvider) {
this.mProviders.remove(aProvider);
}
};

View File

@ -112,6 +112,12 @@ const componentData =
constructor: "calFreeBusyService",
service: true},
{cid: Components.ID("{F5F743CD-8997-428e-BC1B-644E73F61203}"),
contractid: "@mozilla.org/calendar/calendarsearch-service;1",
script: "calCalendarSearchService.js",
constructor: "calCalendarSearchService",
service: true},
{cid: Components.ID("{4b7ae030-ed79-11d9-8cd6-0800200c9a66}"),
contractid: "@mozilla.org/calendar/alarm-monitor;1",
script: "calAlarmMonitor.js",

View File

@ -257,6 +257,7 @@ bin\js\calRecurrenceInfo.js
bin\js\calTodo.js
bin\js\calTransactionManager.js
bin\js\calFreeBusyService.js
bin\js\calCalendarSearchService.js
bin\js\calUtils.js
bin\js\calWeekPrinter.js
bin\js\calWeekTitleService.js

View File

@ -52,6 +52,7 @@ const calIItemBase = Components.interfaces.calIItemBase;
const calIOperationListener = Components.interfaces.calIOperationListener;
const calIFreeBusyProvider = Components.interfaces.calIFreeBusyProvider;
const calIFreeBusyInterval = Components.interfaces.calIFreeBusyInterval;
const calICalendarSearchProvider = Components.interfaces.calICalendarSearchProvider;
const calIErrors = Components.interfaces.calIErrors;
// ctors:

View File

@ -77,6 +77,7 @@ function calWcapSession(contextId, thatUri) {
calWcapSession.prototype = {
m_ifaces: [ calIWcapSession,
calIFreeBusyProvider,
calICalendarSearchProvider,
Components.interfaces.calICalendarManagerObserver,
Components.interfaces.nsIInterfaceRequestor,
Components.interfaces.nsIClassInfo,
@ -205,6 +206,7 @@ calWcapSession.prototype = {
if (timedOutSessionId) {
log("reconnecting due to session timeout...", this);
getFreeBusyService().removeProvider(this);
getCalendarSearchService().removeProvider(this);
}
var this_ = this;
@ -218,6 +220,7 @@ calWcapSession.prototype = {
else {
this_.m_sessionId = sessionId;
getFreeBusyService().addProvider(this_);
getCalendarSearchService().addProvider(this);
}
var queue = this_.m_loginQueue;
@ -428,6 +431,7 @@ calWcapSession.prototype = {
url = (this.sessionUri.spec + "logout.wcap?fmt-out=text%2Fxml&id=" + this.m_sessionId);
this.m_sessionId = null;
getFreeBusyService().removeProvider(this);
getCalendarSearchService().removeProvider(this);
}
this.m_credentials = null;
@ -661,7 +665,7 @@ calWcapSession.prototype = {
var listener = {
onResult: function search_onResult(request, result) {
try {
if (!request.success)
if (!Components.isSuccessCode(request.status))
throw request.status;
if (result.length < 1)
throw Components.results.NS_ERROR_UNEXPECTED;
@ -694,12 +698,7 @@ calWcapSession.prototype = {
if (!issuedSearchRequests[calId]) {
issuedSearchRequests[calId] = true;
this.searchForCalendars(
calId,
calIWcapSession.SEARCH_STRING_EXACT |
calIWcapSession.SEARCH_INCLUDE_CALID |
// else searching for secondary calendars doesn't work:
calIWcapSession.SEARCH_INCLUDE_OWNER,
20, listener);
calId, calICalendarSearchProvider.HINT_EXACT_MATCH, 20, listener);
}
}
}
@ -915,9 +914,10 @@ calWcapSession.prototype = {
out_count.value = ret.length;
return ret;
},
// calICalendarSearchProvider:
searchForCalendars:
function calWcapSession_searchForCalendars(searchString, searchOptions, maxResults, listener)
function calWcapSession_searchForCalendars(searchString, hints, maxResults, listener)
{
var this_ = this;
var request = new calWcapRequest(
@ -934,16 +934,12 @@ calWcapSession.prototype = {
var params = ("&fmt-out=text%2Fxml&search-string=" +
encodeURIComponent(searchString));
params += ("&searchOpts=" + (searchOptions & 3).toString(10));
if (maxResults > 0)
if (maxResults > 0) {
params += ("&maxResults=" + maxResults);
if (searchOptions & calIWcapSession.SEARCH_INCLUDE_CALID)
params += "&calid=1";
if (searchOptions & calIWcapSession.SEARCH_INCLUDE_NAME)
params += "&name=1";
if (searchOptions & calIWcapSession.SEARCH_INCLUDE_OWNER)
params += "&primaryOwner=1";
}
params += ("&name=1&calid=1&primaryOwner=1&searchOpts=" +
((hints & calICalendarSearchProvider.HINT_EXACT_MATCH) ? "3" : "0"));
this.issueNetworkRequest(
request,
function searchForCalendars_netResp(err, data) {
@ -1170,6 +1166,7 @@ calWcapSession.prototype = {
cal = this.belongsTo(cal);
if (cal && cal.isDefaultCalendar) {
getFreeBusyService().removeProvider(this);
getCalendarSearchService().removeProvider(this);
var registeredCalendars = this.getRegisteredCalendars();
for each (var regCal in registeredCalendars) {
try {

View File

@ -220,6 +220,16 @@ function getFreeBusyService() {
return g_fbService;
}
var g_calendarSearchService = null;
function getCalendarSearchService() {
if (!g_calendarSearchService) {
g_calendarSearchService =
Components.classes["@mozilla.org/calendar/calendarsearch-service;1"]
.getService(Components.interfaces.calICalendarSearchService);
}
return g_calendarSearchService;
}
var g_domParser = null;
function getDomParser() {
if (!g_domParser) {

View File

@ -68,37 +68,5 @@ interface calIWcapSession : nsISupports
* Gets the default calendar instance of this session.
*/
readonly attribute calIWcapCalendar defaultCalendar;
/**
* Specifies how to match the searchString.
*/
const unsigned long SEARCH_STRING_CONTAINS = 0;
const unsigned long SEARCH_STRING_BEGINS_WITH = 1;
const unsigned long SEARCH_STRING_ENDS_WITH = 2;
const unsigned long SEARCH_STRING_EXACT = 3;
/**
* Specifies what properties to include.
*/
const unsigned long SEARCH_INCLUDE_CALID = 1 << 2;
const unsigned long SEARCH_INCLUDE_NAME = 1 << 3;
const unsigned long SEARCH_INCLUDE_OWNER = 1 << 4;
/* xxx todo searching: separate into own interface? */
/**
* Searches for calendars matching the specified searchString.
* Results are notified to the passed listener instance as
* an array of calendar instances.
*
* @param searchString the search string to match
* @param searchOptions the search options
* @param maxResults maximum number of results
* (0 means default, e.g. 200 with respect to Sun calendar servers)
* @param listener listener called with an array of calIWcapCalendar objects
* @return optional object to track operation
*/
calIOperation searchForCalendars(in string searchString,
in unsigned long searchOptions,
in unsigned long maxResults,
in calIGenericOperationListener listener);
};