Apache Celix  2.3.0
An implementation of the OSGi specification adapted to C and C++
BundleContext.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #pragma once
21 
22 #include <memory>
23 #include <mutex>
24 #include <thread>
25 #include <cstdarg>
26 
27 #include "celix_bundle_context.h"
28 
31 #include "celix/TrackerBuilders.h"
32 #include "celix/Bundle.h"
33 #include "celix/Framework.h"
34 
35 #include "celix/dm/DependencyManager.h" //TODO, TBD include or forward declaration?
36 
37 namespace celix {
38 
52  class BundleContext {
53  public:
54  explicit BundleContext(celix_bundle_context_t* _cCtx) :
55  cCtx{_cCtx, [](celix_bundle_context_t*){/*nop*/}},
56  dm{std::make_shared<celix::dm::DependencyManager>(_cCtx)},
57  bnd{celix_bundleContext_getBundle(_cCtx)} {}
58 
81  template<typename I, typename Implementer>
82  ServiceRegistrationBuilder<I> registerService(std::shared_ptr<Implementer> implementer, std::string_view name = {}) {
83  std::shared_ptr<I> svc = implementer; //note Implement should be derived from I
84  return ServiceRegistrationBuilder<I>{cCtx, std::move(svc), celix::typeName<I>(name)};
85  }
86 
97  template<typename I, typename Implementer>
98  ServiceRegistrationBuilder<I> registerUnmanagedService(Implementer* svc, std::string_view name = {}) {
99  auto unmanagedSvc = std::shared_ptr<I>{svc, [](I*){/*nop*/}};
100  return ServiceRegistrationBuilder<I>{cCtx, std::move(unmanagedSvc), celix::typeName<I>(name), true, false};
101  }
102 
103  //TODO registerServiceFactory<I>()
104 
131  template<typename I>
132  UseServiceBuilder<I> useService(std::string_view name = {}) {
133  return UseServiceBuilder<I>{cCtx, celix::typeName<I>(name), true};
134  }
135 
159  template<typename I>
160  UseServiceBuilder<I> useServices(std::string_view name = {}) {
161  return UseServiceBuilder<I>{cCtx, celix::typeName<I>(name), false};
162  }
163 
175  template<typename I>
176  long findService(std::string_view filter = {}, std::string_view versionRange = {}) {
177  return findServiceWithName(celix::typeName<I>(), filter, versionRange);
178  }
179 
189  long findServiceWithName(std::string_view name, std::string_view filter = {}, std::string_view versionRange = {}) {
192  opts.serviceName = name.empty() ? nullptr : name.data();
193  opts.filter = filter.empty() ? nullptr : filter.data();
194  opts.versionRange = versionRange.empty() ? nullptr : versionRange.data();
195  return celix_bundleContext_findServiceWithOptions(cCtx.get(), &opts);
196  }
197 
209  template<typename I>
210  std::vector<long> findServices(std::string_view filter = {}, std::string_view versionRange = {}) {
211  return findServicesWithName(celix::typeName<I>(), filter, versionRange);
212  }
213 
223  std::vector<long> findServicesWithName(std::string_view name, std::string_view filter = {}, std::string_view versionRange = {}) {
226  opts.serviceName = name.empty() ? nullptr : name.data();
227  opts.filter = filter.empty() ? nullptr : filter.data();
228  opts.versionRange = versionRange.empty() ? nullptr : versionRange.data();
229 
230  std::vector<long> result{};
231  auto cList = celix_bundleContext_findServicesWithOptions(cCtx.get(), &opts);
232  for (int i = 0; i < celix_arrayList_size(cList); ++i) {
233  long svcId = celix_arrayList_getLong(cList, i);
234  result.push_back(svcId);
235  }
236  celix_arrayList_destroy(cList);
237  return result;
238  }
239 
260  template<typename I>
261  ServiceTrackerBuilder<I> trackServices(std::string_view name = {}) {
262  return ServiceTrackerBuilder<I>{cCtx, celix::typeName<I>(name)};
263  }
264 
272  return ServiceTrackerBuilder<void>{cCtx, {}};
273  }
274 
290  return BundleTrackerBuilder{cCtx};
291  }
292 
313  template<typename I>
314  MetaTrackerBuilder trackServiceTrackers(std::string_view name = {}) {
315  return MetaTrackerBuilder(cCtx, celix::typeName<I>(name));
316  }
317 
324  return MetaTrackerBuilder(cCtx, {});
325  }
326 
336  long installBundle(std::string_view bndLocation, bool autoStart = true) {
337  return celix_bundleContext_installBundle(cCtx.get(), bndLocation.data(), autoStart);
338  }
339 
349  bool uninstallBundle(long bndId) {
350  return celix_bundleContext_uninstallBundle(cCtx.get(), bndId);
351  }
352 
361  bool startBundle(long bndId) {
362  return celix_bundleContext_startBundle(cCtx.get(), bndId);
363  }
364 
373  bool stopBundle(long bndId) {
374  return celix_bundleContext_stopBundle(cCtx.get(), bndId);
375  }
376 
383  [[nodiscard]] std::vector<long> listBundleIds() const {
384  return listBundlesInternal(true);
385  }
386 
393  [[nodiscard]] std::vector<long> listInstalledBundleIds() {
394  return listBundlesInternal(false);
395  }
396 
408  [[nodiscard]] std::string getConfigProperty(std::string_view name, std::string_view defaultValue) const {
409  return std::string{celix_bundleContext_getProperty(cCtx.get(), name.data(), defaultValue.data())};
410  }
411 
424  [[nodiscard]] long getConfigPropertyAsLong(std::string_view name, long defaultValue) const {
425  return celix_bundleContext_getPropertyAsLong(cCtx.get(), name.data(), defaultValue);
426  }
427 
440  [[nodiscard]] double getConfigPropertyAsDouble(std::string_view name, double defaultValue) const {
441  return celix_bundleContext_getPropertyAsDouble(cCtx.get(), name.data(), defaultValue);
442  }
443 
458  [[nodiscard]] long getConfigPropertyAsBool(std::string_view name, bool defaultValue) const {
459  return celix_bundleContext_getPropertyAsBool(cCtx.get(), name.data(), defaultValue);
460  }
461 
465  [[nodiscard]] const Bundle& getBundle() const {
466  return bnd;
467  }
468 
472  [[nodiscard]] long getBundleId() const {
473  return bnd.getId();
474  }
475 
479  [[nodiscard]] std::shared_ptr<Framework> getFramework() const {
480  auto* cFw = celix_bundleContext_getFramework(cCtx.get());
481  auto fwCtx = std::make_shared<celix::BundleContext>(celix_framework_getFrameworkContext(cFw));
482  return std::make_shared<Framework>(fwCtx, cFw);
483  }
484 
488  [[nodiscard]] std::shared_ptr<dm::DependencyManager> getDependencyManager() const {
489  return dm;
490  }
491 
498  [[nodiscard]] celix_bundle_context_t* getCBundleContext() const {
499  return cCtx.get();
500  }
501 
507  void logTrace(const char* format...) {
508  va_list args;
509  va_start(args, format);
510  celix_bundleContext_vlog(cCtx.get(), CELIX_LOG_LEVEL_TRACE, format, args);
511  va_end(args);
512  }
513 
519  void logDebug(const char* format...) {
520  va_list args;
521  va_start(args, format);
522  celix_bundleContext_vlog(cCtx.get(), CELIX_LOG_LEVEL_DEBUG, format, args);
523  va_end(args);
524  }
525 
531  void logInfo(const char* format...) {
532  va_list args;
533  va_start(args, format);
534  celix_bundleContext_vlog(cCtx.get(), CELIX_LOG_LEVEL_INFO, format, args);
535  va_end(args);
536  }
537 
543  void logWarn(const char* format...) {
544  va_list args;
545  va_start(args, format);
546  celix_bundleContext_vlog(cCtx.get(), CELIX_LOG_LEVEL_WARNING, format, args);
547  va_end(args);
548  }
549 
555  void logError(const char* format...) {
556  va_list args;
557  va_start(args, format);
558  celix_bundleContext_vlog(cCtx.get(), CELIX_LOG_LEVEL_ERROR, format, args);
559  va_end(args);
560  }
561 
567  void logFatal(const char* format...) {
568  va_list args;
569  va_start(args, format);
570  celix_bundleContext_vlog(cCtx.get(), CELIX_LOG_LEVEL_FATAL, format, args);
571  va_end(args);
572  }
573 
577  void waitForEvents() const {
579  }
580 
584  void waitIfAbleForEvents() const {
585  auto* fw = celix_bundleContext_getFramework(cCtx.get());
588  }
589  }
590 
594  void waitForAllEvents() const {
595  auto* fw = celix_bundleContext_getFramework(cCtx.get());
597  }
598 
602  void waitIfAbleForAllEvents() const {
603  auto* fw = celix_bundleContext_getFramework(cCtx.get());
606  }
607  }
608  private:
609  [[nodiscard]] std::vector<long> listBundlesInternal(bool activeOnly) const {
610  std::vector<long> result{};
611  auto* ids = activeOnly ?
614  result.reserve(celix_arrayList_size(ids));
615  for (int i = 0; i < celix_arrayList_size(ids); ++i) {
616  result.push_back(celix_arrayList_getLong(ids, i));
617  }
618  celix_arrayList_destroy(ids);
619  return result;
620  }
621 
622  const std::shared_ptr<celix_bundle_context_t> cCtx;
623  const std::shared_ptr<celix::dm::DependencyManager> dm;
624  const Bundle bnd;
625  };
626 }
627 
628 
celix_bundleContext_uninstallBundle
bool celix_bundleContext_uninstallBundle(celix_bundle_context_t *ctx, long bndId)
Uninstall the bundle with the provided bundle id. If needed the bundle will be stopped first....
celix::BundleContext::getConfigPropertyAsDouble
double getConfigPropertyAsDouble(std::string_view name, double defaultValue) const
Gets the config property for the provided name and returns it as a double.
Definition: BundleContext.h:440
Bundle.h
celix::BundleContext
The bundle context is used to interact with the Celix framework.
Definition: BundleContext.h:52
celix::BundleContext::findServiceWithName
long findServiceWithName(std::string_view name, std::string_view filter={}, std::string_view versionRange={})
Finds the highest ranking service using the provided service name and the optional (LDAP) filter and ...
Definition: BundleContext.h:189
celix::BundleContext::trackServices
ServiceTrackerBuilder< I > trackServices(std::string_view name={})
Track services in the Celix framework using a fluent builder API.
Definition: BundleContext.h:261
celix::UseServiceBuilder
Fluent builder API to use a service or services.
Definition: UseServiceBuilder.h:50
celix::BundleContext::trackAnyServices
ServiceTrackerBuilder< void > trackAnyServices()
Track services in the Celix framework using a fluent builder API.
Definition: BundleContext.h:271
celix
Definition: Bundle.h:26
celix::BundleContext::getConfigPropertyAsLong
long getConfigPropertyAsLong(std::string_view name, long defaultValue) const
Gets the config property for the provided name and returns it as a long.
Definition: BundleContext.h:424
celix_bundleContext_getProperty
const char * celix_bundleContext_getProperty(celix_bundle_context_t *ctx, const char *key, const char *defaultVal)
Gets the config property - or environment variable if the config property does not exist - for the pr...
celix::BundleContext::getConfigProperty
std::string getConfigProperty(std::string_view name, std::string_view defaultValue) const
Gets the config property for the provided name.
Definition: BundleContext.h:408
celix::BundleContext::waitIfAbleForAllEvents
void waitIfAbleForAllEvents() const
Wait (if not on the Celix event thread) until all Celix events (for all bundles) are completed.
Definition: BundleContext.h:602
celix::BundleContext::logInfo
void logInfo(const char *format...)
Logs a message to the Celix framework logger using the INFO log level.
Definition: BundleContext.h:531
celix::BundleContext::trackBundles
BundleTrackerBuilder trackBundles()
Track bundles in the Celix framework using a fluent builder API.
Definition: BundleContext.h:289
celix_bundleContext_findServiceWithOptions
long celix_bundleContext_findServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts)
Finds the highest ranking service and returns the service id.
celix_bundleContext_waitForEvents
void celix_bundleContext_waitForEvents(celix_bundle_context_t *ctx)
Wait until all Celix event for this bundle are completed.
celix::BundleContext::getBundleId
long getBundleId() const
Get the bundle id for the bundle of this bundle context.
Definition: BundleContext.h:472
celix::ServiceRegistrationBuilder
Fluent builder API to build a new service registration for a service.
Definition: ServiceRegistrationBuilder.h:38
celix::BundleContext::getBundle
const Bundle & getBundle() const
Get the bundle of this bundle context.
Definition: BundleContext.h:465
celix::BundleContext::registerService
ServiceRegistrationBuilder< I > registerService(std::shared_ptr< Implementer > implementer, std::string_view name={})
Register a service in the Celix framework using a fluent builder API.
Definition: BundleContext.h:82
celix::ServiceTrackerBuilder
Fluent builder API to track services.
Definition: TrackerBuilders.h:38
celix_bundleContext_stopBundle
bool celix_bundleContext_stopBundle(celix_bundle_context_t *ctx, long bndId)
Stop the bundle with the provided bundle id. Will silently ignore bundle ids < 0.
celix::BundleContext::useService
UseServiceBuilder< I > useService(std::string_view name={})
Use a service registered in the Celix framework using a fluent builder API.
Definition: BundleContext.h:132
celix::BundleContext::getCBundleContext
celix_bundle_context_t * getCBundleContext() const
Get the C bundle context.
Definition: BundleContext.h:498
celix::BundleContext::findService
long findService(std::string_view filter={}, std::string_view versionRange={})
Finds the highest ranking service using the optional provided (LDAP) filter and version range.
Definition: BundleContext.h:176
celix_bundleContext_startBundle
bool celix_bundleContext_startBundle(celix_bundle_context_t *ctx, long bndId)
Start the bundle with the provided bundle id. Will silently ignore bundle ids < 0.
celix_bundleContext_findServicesWithOptions
celix_array_list_t * celix_bundleContext_findServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts)
Finds the services conform the provider filter options and returns a list of the found service ids.
celix::BundleContext::trackAnyServiceTrackers
MetaTrackerBuilder trackAnyServiceTrackers()
Track service trackers in the Celix framework using a fluent builder API.
Definition: BundleContext.h:323
TrackerBuilders.h
celix_bundleContext_getPropertyAsBool
bool celix_bundleContext_getPropertyAsBool(celix_bundle_context_t *ctx, const char *key, bool defaultValue)
Gets the config property as converts it to bool. If the property is not a valid bool,...
celix::BundleContext::waitIfAbleForEvents
void waitIfAbleForEvents() const
Wait (if not on the Celix event thread) until all Celix events for this bundle are completed.
Definition: BundleContext.h:584
celix::MetaTrackerBuilder
Fluent builder API to track service trackers.
Definition: TrackerBuilders.h:306
celix::BundleContext::registerUnmanagedService
ServiceRegistrationBuilder< I > registerUnmanagedService(Implementer *svc, std::string_view name={})
Register a (unmanaged) service in the Celix framework using a fluent builder API.
Definition: BundleContext.h:98
celix_bundleContext_getPropertyAsDouble
double celix_bundleContext_getPropertyAsDouble(celix_bundle_context_t *ctx, const char *key, double defaultValue)
Gets the config property as converts it to double. If the property is not a valid double,...
celix::BundleContext::startBundle
bool startBundle(long bndId)
Start the bundle with the provided bundle id.
Definition: BundleContext.h:361
celix::BundleContext::logDebug
void logDebug(const char *format...)
Logs a message to the Celix framework logger using the DEBUG log level.
Definition: BundleContext.h:519
celix::BundleContext::waitForAllEvents
void waitForAllEvents() const
Wait until all Celix events (for all bundles) are completed.
Definition: BundleContext.h:594
celix::BundleContext::logError
void logError(const char *format...)
Logs a message to the Celix framework logger using the ERROR log level.
Definition: BundleContext.h:555
celix::BundleContext::uninstallBundle
bool uninstallBundle(long bndId)
Uninstall the bundle with the provided bundle id.
Definition: BundleContext.h:349
celix::BundleContext::installBundle
long installBundle(std::string_view bndLocation, bool autoStart=true)
Install and optional start a bundle.
Definition: BundleContext.h:336
celix::BundleContext::BundleContext
BundleContext(celix_bundle_context_t *_cCtx)
Definition: BundleContext.h:54
celix_bundleContext_installBundle
long celix_bundleContext_installBundle(celix_bundle_context_t *ctx, const char *bundleLoc, bool autoStart)
Install and optional start a bundle. Will silently ignore bundle ids < 0.
celix_bundleContext_getFramework
celix_framework_t * celix_bundleContext_getFramework(const celix_bundle_context_t *ctx)
celix::BundleContext::listInstalledBundleIds
std::vector< long > listInstalledBundleIds()
List the installed bundle ids. The bundle ids does not include the framework bundle (bundle id CELIX_...
Definition: BundleContext.h:393
Framework.h
celix_bundleContext_listInstalledBundles
celix_array_list_t * celix_bundleContext_listInstalledBundles(celix_bundle_context_t *ctx)
List the installed bundle ids. The bundle ids does not include the framework bundle (bundle id CELIX_...
celix::BundleContext::useServices
UseServiceBuilder< I > useServices(std::string_view name={})
Use services registered in the Celix framework using a fluent builder API.
Definition: BundleContext.h:160
celix::Bundle
An installed bundle in the Celix framework.
Definition: Bundle.h:47
celix::BundleContext::waitForEvents
void waitForEvents() const
Wait until all Celix events for this bundle are completed.
Definition: BundleContext.h:577
celix::BundleContext::getDependencyManager
std::shared_ptr< dm::DependencyManager > getDependencyManager() const
Get the Celix dependency manager for this bundle context.
Definition: BundleContext.h:488
celix_service_filter_options
Service filter options which can be used to query for certain services.
Definition: celix_bundle_context.h:321
celix_bundleContext_vlog
void celix_bundleContext_vlog(const celix_bundle_context_t *ctx, celix_log_level_e level, const char *format, va_list formatArgs)
Logs a message to Celix framework logger with the provided log level.
celix::BundleContext::logFatal
void logFatal(const char *format...)
Logs a message to the Celix framework logger using the FATAL log level.
Definition: BundleContext.h:567
celix_framework_waitForEmptyEventQueue
void celix_framework_waitForEmptyEventQueue(celix_framework_t *fw)
Wait until the framework event queue is empty.
celix::BundleContext::getConfigPropertyAsBool
long getConfigPropertyAsBool(std::string_view name, bool defaultValue) const
Gets the config property for the provided name and returns it as a bool.
Definition: BundleContext.h:458
DependencyManager.h
celix_bundleContext_getPropertyAsLong
long celix_bundleContext_getPropertyAsLong(celix_bundle_context_t *ctx, const char *key, long defaultValue)
Gets the config property as converts it to long. If the property is not a valid long,...
celix::BundleContext::findServicesWithName
std::vector< long > findServicesWithName(std::string_view name, std::string_view filter={}, std::string_view versionRange={})
Finds all service matching the provided service name and the optional (LDAP) filter and version range...
Definition: BundleContext.h:223
celix::BundleContext::trackServiceTrackers
MetaTrackerBuilder trackServiceTrackers(std::string_view name={})
Track service trackers in the Celix framework using a fluent builder API.
Definition: BundleContext.h:314
celix_framework_getFrameworkContext
celix_bundle_context_t * celix_framework_getFrameworkContext(const celix_framework_t *fw)
Returns the framework bundle context. This is the same as a 'normal' bundle context and can be used t...
celix::BundleContext::logTrace
void logTrace(const char *format...)
Logs a message to the Celix framework logger using the TRACE log level.
Definition: BundleContext.h:507
celix::Bundle::getId
long getId() const
get the bundle id.
Definition: Bundle.h:55
UseServiceBuilder.h
celix::BundleContext::stopBundle
bool stopBundle(long bndId)
Stop the bundle with the provided bundle id.
Definition: BundleContext.h:373
celix_framework_isCurrentThreadTheEventLoop
bool celix_framework_isCurrentThreadTheEventLoop(celix_framework_t *fw)
Returns whether the current thread is the Celix framework event loop thread.
celix::BundleContext::findServices
std::vector< long > findServices(std::string_view filter={}, std::string_view versionRange={})
Finds all services matching the optional provided (LDAP) filter and version range.
Definition: BundleContext.h:210
celix::BundleContext::listBundleIds
std::vector< long > listBundleIds() const
List the installed and started bundle ids. The bundle ids does not include the framework bundle (bund...
Definition: BundleContext.h:383
celix::BundleContext::logWarn
void logWarn(const char *format...)
Logs a message to the Celix framework logger using the WARNING log level.
Definition: BundleContext.h:543
celix_bundle_context.h
celix::BundleContext::getFramework
std::shared_ptr< Framework > getFramework() const
Get the Celix framework for this bundle context.
Definition: BundleContext.h:479
celix_bundleContext_getBundle
celix_bundle_t * celix_bundleContext_getBundle(const celix_bundle_context_t *ctx)
Returns the bundle for this bundle context.
ServiceRegistrationBuilder.h
celix_bundleContext_listBundles
celix_array_list_t * celix_bundleContext_listBundles(celix_bundle_context_t *ctx)
List the installed and started bundle ids. The bundle ids does not include the framework bundle (bund...
celix::BundleTrackerBuilder
Fluent builder API to track bundles.
Definition: TrackerBuilders.h:233