diff --git a/mozilla/calendar/base/public/Makefile.in b/mozilla/calendar/base/public/Makefile.in index 5390c08a0ae..ff0c499ebae 100644 --- a/mozilla/calendar/base/public/Makefile.in +++ b/mozilla/calendar/base/public/Makefile.in @@ -81,6 +81,7 @@ XPIDLSRCS = calIAlarmService.idl \ calITransactionManager.idl \ calIOperation.idl \ calIFreeBusyProvider.idl \ + calICalendarSearchProvider.idl \ $(NULL) EXPORTS = calBaseCID.h diff --git a/mozilla/calendar/base/public/calICalendarSearchProvider.idl b/mozilla/calendar/base/public/calICalendarSearchProvider.idl new file mode 100644 index 00000000000..e29078b33c1 --- /dev/null +++ b/mozilla/calendar/base/public/calICalendarSearchProvider.idl @@ -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 + * + * 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); +}; diff --git a/mozilla/calendar/base/src/Makefile.in b/mozilla/calendar/base/src/Makefile.in index 68292c28c9c..aa743b2d3f0 100644 --- a/mozilla/calendar/base/src/Makefile.in +++ b/mozilla/calendar/base/src/Makefile.in @@ -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. diff --git a/mozilla/calendar/base/src/calCalendarSearchService.js b/mozilla/calendar/base/src/calCalendarSearchService.js new file mode 100644 index 00000000000..b922fa44476 --- /dev/null +++ b/mozilla/calendar/base/src/calCalendarSearchService.js @@ -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 + * + * 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); + } +}; diff --git a/mozilla/calendar/base/src/calItemModule.js b/mozilla/calendar/base/src/calItemModule.js index a6143ea7e29..99778a2fdce 100644 --- a/mozilla/calendar/base/src/calItemModule.js +++ b/mozilla/calendar/base/src/calItemModule.js @@ -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", diff --git a/mozilla/calendar/installer/windows/packages-static b/mozilla/calendar/installer/windows/packages-static index ef8010b763d..63f6cf2e1bb 100644 --- a/mozilla/calendar/installer/windows/packages-static +++ b/mozilla/calendar/installer/windows/packages-static @@ -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 diff --git a/mozilla/calendar/providers/wcap/calWcapCalendarModule.js b/mozilla/calendar/providers/wcap/calWcapCalendarModule.js index 1e8f14465cd..af88362df0c 100644 --- a/mozilla/calendar/providers/wcap/calWcapCalendarModule.js +++ b/mozilla/calendar/providers/wcap/calWcapCalendarModule.js @@ -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: diff --git a/mozilla/calendar/providers/wcap/calWcapSession.js b/mozilla/calendar/providers/wcap/calWcapSession.js index 4f847237674..3d9d699aacd 100644 --- a/mozilla/calendar/providers/wcap/calWcapSession.js +++ b/mozilla/calendar/providers/wcap/calWcapSession.js @@ -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 { diff --git a/mozilla/calendar/providers/wcap/calWcapUtils.js b/mozilla/calendar/providers/wcap/calWcapUtils.js index 1e99952a6f6..bcf10f61014 100644 --- a/mozilla/calendar/providers/wcap/calWcapUtils.js +++ b/mozilla/calendar/providers/wcap/calWcapUtils.js @@ -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) { diff --git a/mozilla/calendar/providers/wcap/public/calIWcapSession.idl b/mozilla/calendar/providers/wcap/public/calIWcapSession.idl index eddebeb9603..1487b4bf025 100755 --- a/mozilla/calendar/providers/wcap/public/calIWcapSession.idl +++ b/mozilla/calendar/providers/wcap/public/calIWcapSession.idl @@ -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); };