/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. =============================================================================*/ #ifndef CTKSERVICETRACKER_H #define CTKSERVICETRACKER_H #include #include "ctkPluginFrameworkExport.h" #include "ctkServiceReference.h" #include "ctkServiceTrackerCustomizer.h" #include "ctkLDAPSearchFilter.h" template class ctkTrackedService; template class ctkServiceTrackerPrivate; class ctkPluginContext; /** * \ingroup PluginFramework * * The ctkServiceTracker class simplifies using services from the * Framework's service registry. *

* A ctkServiceTracker object is constructed with search criteria and * a ctkServiceTrackerCustomizer object. A ctkServiceTracker * can use a ctkServiceTrackerCustomizer to customize the service * objects to be tracked. The ctkServiceTracker can then be opened to * begin tracking all services in the Framework's service registry that match * the specified search criteria. The ctkServiceTracker correctly * handles all of the details of listening to ctkServiceEvents and * getting and ungetting services. *

* The getServiceReferences method can be called to get references * to the services being tracked. The getService and * getServices methods can be called to get the service objects for * the tracked service. *

* The ctkServiceTracker class is thread-safe. It does not call a * ctkServiceTrackerCustomizer while holding any locks. * ctkServiceTrackerCustomizer implementations must also be * thread-safe. * * \tparam S The type of the service being tracked. The type must be an * assignable datatype. Further, if the * ctkServiceTracker(ctkPluginContext*, ctkServiceTrackerCustomizer*) * constructor is used, the type must have an associated interface id via * Q_DECLARE_INTERFACE. * \tparam T The type of the tracked object. The type must be an assignable * datatype, provide a boolean conversion function, and provide * a constructor and an assignment operator which can handle 0 as an argument. * \remarks This class is thread safe. */ template class ctkServiceTracker : protected ctkServiceTrackerCustomizer { public: ~ctkServiceTracker(); /** * Create a ctkServiceTracker on the specified * ctkServiceReference. * *

* The service referenced by the specified ctkServiceReference * will be tracked by this ctkServiceTracker. * * @param context The ctkPluginContext against which the tracking * is done. * @param reference The ctkServiceReference for the service to be * tracked. * @param customizer The customizer object to call when services are added, * modified, or removed in this ctkServiceTracker. If * customizer is null, then this * ctkServiceTracker will be used as the * ctkServiceTrackerCustomizer and this * ctkServiceTracker will call the * ctkServiceTrackerCustomizer methods on itself. */ ctkServiceTracker(ctkPluginContext* context, const ctkServiceReference& reference, ctkServiceTrackerCustomizer* customizer = 0); /** * Create a ctkServiceTracker on the specified class name. * *

* Services registered under the specified class name will be tracked by * this ctkServiceTracker. * * @param context The ctkPluginContext against which the tracking * is done. * @param clazz The class name of the services to be tracked. * @param customizer The customizer object to call when services are added, * modified, or removed in this ctkServiceTracker. If * customizer is null, then this * ctkServiceTracker will be used as the * ctkServiceTrackerCustomizer and this * ctkServiceTracker will call the * ctkServiceTrackerCustomizer methods on itself. */ ctkServiceTracker(ctkPluginContext* context, const QString& clazz, ctkServiceTrackerCustomizer* customizer = 0); /** * Create a ctkServiceTracker on the specified * ctkLDAPSearchFilter object. * *

* Services which match the specified ctkLDAPSearchFilter object will be * tracked by this ctkServiceTracker. * * @param context The ctkPluginContext against which the tracking * is done. * @param filter The ctkLDAPSearchFilter to select the services to be * tracked. * @param customizer The customizer object to call when services are added, * modified, or removed in this ctkServiceTracker. If * customizer is null, then this ctkServiceTracker will be * used as the ctkServiceTrackerCustomizer and this * ctkServiceTracker will call the * ctkServiceTrackerCustomizer methods on itself. */ ctkServiceTracker(ctkPluginContext* context, const ctkLDAPSearchFilter& filter, ctkServiceTrackerCustomizer* customizer = 0); /** * Create a ctkServiceTracker on the class template * argument S. * *

* Services registered under the interface name of the class template * argument S will be tracked by this ctkServiceTracker. * * @param context The ctkPluginContext against which the tracking * is done. * @param customizer The customizer object to call when services are added, * modified, or removed in this ctkServiceTracker. If * customizer is null, then this ctkServiceTracker will be * used as the ctkServiceTrackerCustomizer and this * ctkServiceTracker will call the * ctkServiceTrackerCustomizer methods on itself. */ ctkServiceTracker(ctkPluginContext* context, ctkServiceTrackerCustomizer* customizer = 0); /** * Open this ctkServiceTracker and begin tracking services. * *

* Services which match the search criteria specified when this * ctkServiceTracker was created are now tracked by this * ctkServiceTracker. * * @throws ctkIllegalStateException If the ctkPluginContext * with which this ctkServiceTracker was created is no * longer valid. */ virtual void open(); /** * Close this ctkServiceTracker. * *

* This method should be called when this ctkServiceTracker should * end the tracking of services. * *

* This implementation calls getServiceReferences() to get the list * of tracked services to remove. */ virtual void close(); /** * Wait for at least one service to be tracked by this * ctkServiceTracker. This method will also return when this * ctkServiceTracker is closed. * *

* It is strongly recommended that waitForService is not used * during the calling of the ctkPluginActivator methods. * ctkPluginActivator methods are expected to complete in a short * period of time. * *

* This implementation calls getService() to determine if a service * is being tracked. * * @param timeout The time interval in milliseconds to wait. If zero, the * method will wait indefinitely. * @return Returns the result of getService(). */ virtual T waitForService(unsigned long timeout); /** * Return a list of ctkServiceReferences for all services being * tracked by this ctkServiceTracker. * * @return List of ctkServiceReferences. */ virtual QList getServiceReferences() const; /** * Returns a ctkServiceReference for one of the services being * tracked by this ctkServiceTracker. * *

* If multiple services are being tracked, the service with the highest * ranking (as specified in its service.ranking property) is * returned. If there is a tie in ranking, the service with the lowest * service ID (as specified in its service.id property); that * is, the service that was registered first is returned. This is the same * algorithm used by ctkPluginContext::getServiceReference(). * *

* This implementation calls getServiceReferences() to get the list * of references for the tracked services. * * @return A ctkServiceReference for a tracked service. * @throws ctkServiceException if no services are being tracked. */ virtual ctkServiceReference getServiceReference() const; /** * Returns the service object for the specified * ctkServiceReference if the specified referenced service is * being tracked by this ctkServiceTracker. * * @param reference The reference to the desired service. * @return A service object or null if the service referenced * by the specified ctkServiceReference is not being * tracked. */ virtual T getService(const ctkServiceReference& reference) const; /** * Return a list of service objects for all services being tracked by this * ctkServiceTracker. * *

* This implementation calls getServiceReferences() to get the list * of references for the tracked services and then calls * getService(const ctkServiceReference&) for each reference to get the * tracked service object. * * @return A list of service objects or an empty list if no services * are being tracked. */ virtual QList getServices() const; /** * Returns a service object for one of the services being tracked by this * ctkServiceTracker. * *

* If any services are being tracked, this implementation returns the result * of calling getService(getServiceReference()). * * @return A service object or null if no services are being * tracked. */ virtual T getService() const; /** * Remove a service from this ctkServiceTracker. * * The specified service will be removed from this * ctkServiceTracker. If the specified service was being tracked * then the ctkServiceTrackerCustomizer::removedService method will * be called for that service. * * @param reference The reference to the service to be removed. */ virtual void remove(const ctkServiceReference& reference); /** * Return the number of services being tracked by this * ctkServiceTracker. * * @return The number of services being tracked. */ virtual int size() const; /** * Returns the tracking count for this ctkServiceTracker. * * The tracking count is initialized to 0 when this * ctkServiceTracker is opened. Every time a service is added, * modified or removed from this ctkServiceTracker, the tracking * count is incremented. * *

* The tracking count can be used to determine if this * ctkServiceTracker has added, modified or removed a service by * comparing a tracking count value previously collected with the current * tracking count value. If the value has not changed, then no service has * been added, modified or removed from this ctkServiceTracker * since the previous tracking count was collected. * * @return The tracking count for this ctkServiceTracker or -1 if * this ctkServiceTracker is not open. */ virtual int getTrackingCount() const; /** * Return a sorted QMap of the ctkServiceReferences and * service objects for all services being tracked by this * ctkServiceTracker. The map is sorted in natural order * of ctkServiceReference. That is, the last entry is the service * with the highest ranking and the lowest service id. * * @return A QMap with the ctkServiceReferences * and service objects for all services being tracked by this * ctkServiceTracker. If no services are being tracked, * then the returned map is empty. */ virtual QMap getTracked() const; /** * Return if this ctkServiceTracker is empty. * * @return true if this ctkServiceTracker is not tracking any * services. */ virtual bool isEmpty() const; protected: /** * Default implementation of the * ctkServiceTrackerCustomizer::addingService method. * *

* This method is only called when this ctkServiceTracker has been * constructed with a null ctkServiceTrackerCustomizer argument. * *

* This implementation returns the result of calling getService * on the ctkPluginContext with which this * ctkServiceTracker was created passing the specified * ctkServiceReference. *

* This method can be overridden in a subclass to customize the service * object to be tracked for the service being added. In that case, take care * not to rely on the default implementation of * \link removedService(const ctkServiceReference&, T service) removedService\endlink * to unget the service. * * @param reference The reference to the service being added to this * ctkServiceTracker. * @return The service object to be tracked for the service added to this * ctlServiceTracker. * @see ctkServiceTrackerCustomizer::addingService(const ctkServiceReference&) */ T addingService(const ctkServiceReference& reference); /** * Default implementation of the * ctkServiceTrackerCustomizer::modifiedService method. * *

* This method is only called when this ctkServiceTracker has been * constructed with a null ctkServiceTrackerCustomizer argument. * *

* This implementation does nothing. * * @param reference The reference to modified service. * @param service The service object for the modified service. * @see ctkServiceTrackerCustomizer::modifiedService(const ctkServiceReference&, QObject*) */ void modifiedService(const ctkServiceReference& reference, T service); /** * Default implementation of the * ctkServiceTrackerCustomizer::removedService method. * *

* This method is only called when this ctkServiceTracker has been * constructed with a null ctkServiceTrackerCustomizer argument. * *

* This implementation calls ungetService, on the * ctkPluginContext with which this ctkServiceTracker * was created, passing the specified ctkServiceReference. *

* This method can be overridden in a subclass. If the default * implementation of \link addingService(const ctkServiceReference&) addingService\endlink * method was used, this method must unget the service. * * @param reference The reference to removed service. * @param service The service object for the removed service. * @see ctkServiceTrackerCustomizer::removedService(const ServiceReference&, QObject*) */ void removedService(const ctkServiceReference& reference, T service); private: typedef ctkServiceTracker ServiceTracker; typedef ctkTrackedService TrackedService; typedef ctkServiceTrackerPrivate ServiceTrackerPrivate; typedef ctkServiceTrackerCustomizer ServiceTrackerCustomizer; friend class ctkTrackedService; friend class ctkServiceTrackerPrivate; inline ServiceTrackerPrivate* d_func() { return reinterpret_cast(qGetPtrHelper(d_ptr)); } inline const ServiceTrackerPrivate* d_func() const { return reinterpret_cast(qGetPtrHelper(d_ptr)); } const QScopedPointer d_ptr; }; #include "ctkServiceTracker.tpp" #endif // CTKSERVICETRACKER_H