Repository: celix Updated Branches: refs/heads/feature/CELIX-426-cxx-api 8464f3d5c -> 4f4389256
CELIX-426: Update C++ implementation for update C api. Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/4f438925 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/4f438925 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/4f438925 Branch: refs/heads/feature/CELIX-426-cxx-api Commit: 4f43892563dba8fcf8279e33179d61b9ea6fc029 Parents: 8464f3d Author: Pepijn Noltes <[email protected]> Authored: Mon May 14 22:29:47 2018 +0200 Committer: Pepijn Noltes <[email protected]> Committed: Mon May 14 22:29:47 2018 +0200 ---------------------------------------------------------------------- .../src/ConsumerBundleActivator.cc | 4 +- .../src/ProviderBundleActivator.cc | 2 +- framework/CMakeLists.txt | 4 +- framework/gtest/src/cxx_BundleContext_tests.cc | 24 +- framework/include/celix/BundleContext.h | 106 ++- framework/include/celix/Framework.h | 6 +- framework/include/celix/dm/DependencyManager.h | 2 +- .../include/celix/impl/BundleContextImpl.h | 144 ++-- framework/include/celix/impl/BundleImpl.h | 1 + framework/include/celix/impl/FrameworkImpl.h | 11 +- framework/include/celix_bundle.h | 11 +- framework/include/celix_bundle_context.h | 9 +- framework/include/framework.h | 2 - framework/private/mock/framework_mock.c | 8 +- framework/src/BundleImpl.c | 765 ------------------ framework/src/bundle.c | 766 +++++++++++++++++++ framework/src/bundle_context.c | 4 + framework/src/framework.c | 5 +- framework/src/framework_private.h | 9 +- 19 files changed, 965 insertions(+), 918 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc b/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc index 3371cad..f12e714 100644 --- a/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc +++ b/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc @@ -30,8 +30,8 @@ namespace { public: BundleActivator(celix::BundleContext &_ctx) : ctx{_ctx} { this->trackerId = ctx.trackServices<example::ICalc>(example::ICalc::NAME, - [this](example::ICalc *, const celix::Properties &, const celix::Bundle&) { this->trackCount += 1; }, - [this](example::ICalc *, const celix::Properties &, const celix::Bundle&) { this->trackCount -= 1; }); + [this](example::ICalc *) { this->trackCount += 1; }, + [this](example::ICalc *) { this->trackCount -= 1; }); } virtual ~BundleActivator() { http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc ---------------------------------------------------------------------- diff --git a/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc b/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc index ca8cf8d..c83b4af 100644 --- a/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc +++ b/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc @@ -48,7 +48,7 @@ namespace { if (up) { celix::Properties props{}; props[celix::Constants::SERVICE_RANKING] = std::to_string(std::rand()); - long svcId = ctx.registerService(example::ICalc::NAME, &calc, example::ICalc::VERSION, std::move(props)); + long svcId = ctx.registerService<example::ICalc>(&calc, example::ICalc::NAME, std::move(props)); svcIds.push_back(svcId); } else { long svcId = svcIds.back(); http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index cdcd044..c32420f 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -24,7 +24,7 @@ if(WIN32) endif(WIN32) set(SOURCES - src/attribute.c src/BundleImpl.c src/bundle_archive.c src/bundle_cache.c + src/attribute.c src/bundle.c src/bundle_archive.c src/bundle_cache.c src/bundle_context.c src/bundle_revision.c src/capability.c src/celix_errorcodes.c src/filter.c src/framework.c src/manifest.c src/ioapi.c src/manifest_parser.c src/miniunz.c src/module.c @@ -148,7 +148,7 @@ if (ENABLE_TESTING AND FRAMEWORK_TESTS) private/mock/bundle_revision_mock.c private/mock/resolver_mock.c private/mock/version_mock.c - src/BundleImpl.c + src/bundle.c src/celix_errorcodes.c private/mock/celix_log_mock.c) target_link_libraries(bundle_test ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY} Celix::utils pthread) http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/gtest/src/cxx_BundleContext_tests.cc ---------------------------------------------------------------------- diff --git a/framework/gtest/src/cxx_BundleContext_tests.cc b/framework/gtest/src/cxx_BundleContext_tests.cc index a426d66..1777207 100644 --- a/framework/gtest/src/cxx_BundleContext_tests.cc +++ b/framework/gtest/src/cxx_BundleContext_tests.cc @@ -79,11 +79,11 @@ TEST_F(BundleContextTest, RegisterCServiceTest) { test_svc svc1{}; - long svcId = ctx.registerCService("test service", &svc1); + long svcId = ctx.registerCService(&svc1, "test service"); EXPECT_TRUE(svcId > 0); ctx.unregisterService(svcId); - long svcId2 = ctx.registerCService("test service", &svc1); + long svcId2 = ctx.registerCService(&svc1, "test service"); EXPECT_TRUE(svcId2 > 0); EXPECT_NE(svcId, svcId2); //new registration new id ctx.unregisterService(svcId2); @@ -98,11 +98,11 @@ TEST_F(BundleContextTest, RegisterServiceTest) { TestImpl svc1{}; - long svcId = ctx.registerService<ITestSvc>(ITestSvc::NAME, &svc1); + long svcId = ctx.registerService<ITestSvc>(&svc1, ITestSvc::NAME); EXPECT_TRUE(svcId > 0); ctx.unregisterService(svcId); - long svcId2 = ctx.registerService<ITestSvc>(ITestSvc::NAME, &svc1); + long svcId2 = ctx.registerService<ITestSvc>(&svc1, ITestSvc::NAME); EXPECT_TRUE(svcId2 > 0); EXPECT_NE(svcId, svcId2); //new registration new id ctx.unregisterService(svcId2); @@ -113,7 +113,7 @@ TEST_F(BundleContextTest, UseService) { TestImpl svc1{}; - long svcId = ctx.registerService<ITestSvc>(ITestSvc::NAME, &svc1); + long svcId = ctx.registerService<ITestSvc>(&svc1, ITestSvc::NAME); EXPECT_TRUE(svcId > 0); @@ -140,10 +140,10 @@ TEST_F(BundleContextTest, UseServices) { TestImpl svc{}; - long svcId1 = ctx.registerService<ITestSvc>("test service", &svc); + long svcId1 = ctx.registerService<ITestSvc>(&svc, "test service"); EXPECT_TRUE(svcId1 > 0); - long svcId2 = ctx.registerService<ITestSvc>("test service", &svc); + long svcId2 = ctx.registerService<ITestSvc>(&svc, "test service"); EXPECT_TRUE(svcId2 > 0); @@ -174,7 +174,7 @@ TEST_F(BundleContextTest, TrackService) { ITestSvc *svc4 = (ITestSvc*)0x400; //5 ranking - auto set = [&](ITestSvc *svc, const celix::Properties &, const celix::Bundle &) { + auto set = [&](ITestSvc *svc) { static int callCount = 0; callCount += 1; if (callCount == 1) { @@ -191,8 +191,8 @@ TEST_F(BundleContextTest, TrackService) { count = callCount; }; - long svcId1 = ctx.registerService("NA", svc1); - long svcId2 = ctx.registerService("NA", svc2); + long svcId1 = ctx.registerService(svc1, "NA"); + long svcId2 = ctx.registerService(svc2, "NA"); //starting tracker should lead to first set call long trackerId = ctx.trackService<ITestSvc>("NA", set); @@ -201,12 +201,12 @@ TEST_F(BundleContextTest, TrackService) { //register svc3 should lead to second set call celix::Properties props3{}; props3[OSGI_FRAMEWORK_SERVICE_RANKING] = "10"; - long svcId3 = ctx.registerService("NA", svc3, "", std::move(props3)); + long svcId3 = ctx.registerService(svc3, "NA", std::move(props3)); //register svc4 should lead to no set (lower ranking) celix::Properties props4{}; props4[OSGI_FRAMEWORK_SERVICE_RANKING] = "10"; - long svcId4 = ctx.registerService("NA", svc4, "", props4); + long svcId4 = ctx.registerService(svc4, "NA", props4); //unregister svc3 should lead to set (new highest ranking) ctx.unregisterService(svcId3); http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/BundleContext.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/BundleContext.h b/framework/include/celix/BundleContext.h index 9d9a274..1ff37a9 100644 --- a/framework/include/celix/BundleContext.h +++ b/framework/include/celix/BundleContext.h @@ -38,15 +38,40 @@ namespace celix { } template<typename I> + struct ServiceRegistrationOptions { + using type = I; + + ServiceRegistrationOptions(I& _svc, const std::string& _serviceName) : svc{_svc}, serviceName{_serviceName} {}; + + I& svc; + const std::string serviceName; + + celix::Properties properties{}; + std::string serviceVersion{}; + std::string serviceLanguage{celix::Constants::SERVICE_CXX_LANG}; + }; + + template<typename I> + struct ServiceFilterOptions { + using type = I; + + ServiceFilterOptions(const std::string &_serviceName) : serviceName{_serviceName} {}; + + std::string serviceName; + + std::string versionRange{}; + std::string filter{}; + std::string lang{celix::Constants::SERVICE_CXX_LANG}; + }; + + + template<typename I> struct ServiceUseOptions { - /* - * Service filter info - */ - const std::string &serviceName{}; //required - const std::string &versionRange{}; - const std::string &filter{}; - const std::string &lang{}; //default will be C++ + using type = I; + + ServiceUseOptions(const std::string &serviceName) : filter{ServiceFilterOptions<I>{serviceName}} {}; + ServiceFilterOptions<I> filter; /* * Callbacks @@ -58,13 +83,11 @@ namespace celix { template<typename I> struct ServiceTrackingOptions { - /* - * Service filter info - */ - const std::string &serviceName{}; //required - const std::string &versionRange{}; - const std::string &filter{}; - const std::string &lang{}; //default will be C++ + using type = I; + + ServiceTrackingOptions(const std::string serviceName) : filter{ServiceFilterOptions<I>{serviceName}} {}; + + ServiceFilterOptions<I> filter; std::function<void(I* svc)> set{}; std::function<void(I* svc)> add{}; @@ -105,20 +128,13 @@ namespace celix { virtual ~BundleContext(){}; template<typename I> - long registerService(const std::string &serviceName, I *svc, const std::string &version = "", Properties props = {}) noexcept { - return this->registerServiceInternal(serviceName, svc, version, celix::Constants::SERVICE_CXX_LANG, std::move(props)); - } + long registerService(I *svc, const std::string &serviceName, Properties props = {}) noexcept; template<typename I> - long registerCService(const std::string &serviceName, I *svc, const std::string &version = "", Properties props = {}) noexcept { - static_assert(std::is_pod<I>::value, "Service I must be a 'Plain Old Data' object"); - return this->registerServiceInternal(serviceName, svc, version, celix::Constants::SERVICE_C_LANG, std::move(props)); - } + long registerCService(I *svc, const std::string &serviceName, Properties props = {}) noexcept; template<typename I> - long registerServiceForLang(const std::string &serviceName, I *svc, const std::string &version = "", const std::string &lang = celix::Constants::SERVICE_C_LANG, Properties props = {}) noexcept { - return this->registerServiceInternal(serviceName, svc, version, lang, std::move(props)); - } + long registerServiceWithOptions(const celix::ServiceRegistrationOptions<I>& opts) noexcept; //TODO register std::function ? @@ -138,15 +154,7 @@ namespace celix { * @return the tracker id or < 0 if unsuccessful. */ template<typename I> - long trackService( - const std::string &serviceName, - std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> set - ) noexcept { - return this->trackServiceInternal(serviceName, [set](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) { - I* typedSvc = static_cast<I*>(voidSvc); - set(typedSvc, props, bnd); - }); - } + long trackService(const std::string &serviceName, std::function<void(I *svc)> set) noexcept; /** * track services for the provided serviceName and/or filter. @@ -158,25 +166,9 @@ namespace celix { * @return the tracker id or < 0 if unsuccessful. */ template<typename I> - long trackServices( - const std::string &serviceName, - std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> add, - std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> remove - ) noexcept { - return this->trackServicesInternal(serviceName, - [add](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) { - I *typedSvc = static_cast<I *>(voidSvc); - add(typedSvc, props, bnd); - }, - [remove](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) { - I *typedSvc = static_cast<I *>(voidSvc); - remove(typedSvc, props, bnd); - } - ); - } + long trackServices(const std::string &serviceName, std::function<void(I *svc)> add, std::function<void(I *svc)> remove) noexcept; - //TODO make add / remove service refs?? - //TODO add trackService(s)WithOptions + //TODO trackService(s)WithOptions //TODO add trackCService(s) variants /** @@ -262,16 +254,10 @@ namespace celix { virtual bool useBundle(long bundleId, const std::function<void(const celix::Bundle &bnd)> &use) noexcept = 0; protected: - virtual long registerServiceInternal(const std::string &serviceName, void *svc, const std::string &version, const std::string &lang, celix::Properties props) noexcept = 0; - - virtual long trackServiceInternal(const std::string &serviceName, - std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> set) noexcept = 0; + virtual long registerServiceInternal(const celix_service_registration_options_t &opts) noexcept = 0; - virtual long trackServicesInternal( - const std::string &serviceName, - std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> add, - std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> remove - ) noexcept = 0; + virtual long trackServiceInternal(const std::string &serviceName, std::function<void(void *svc)> set) noexcept = 0; + virtual long trackServicesInternal(const std::string &serviceName, std::function<void(void *svc)> add, std::function<void(void *svc)> remove) noexcept = 0; virtual bool useServiceInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0; virtual void useServicesInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0; http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/Framework.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/Framework.h b/framework/include/celix/Framework.h index e8daa6a..790cfc0 100644 --- a/framework/include/celix/Framework.h +++ b/framework/include/celix/Framework.h @@ -17,9 +17,6 @@ *under the License. */ -#ifndef CXX_CELIX_FRAMEWORK_H -#define CXX_CELIX_FRAMEWORK_H - #include <functional> #include "celix/Constants.h" @@ -27,6 +24,9 @@ #include "Bundle.h" #include "celix/BundleContext.h" +#ifndef CXX_CELIX_FRAMEWORK_H +#define CXX_CELIX_FRAMEWORK_H + namespace celix { class Framework { http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/dm/DependencyManager.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/dm/DependencyManager.h b/framework/include/celix/dm/DependencyManager.h index 5a4dd99..538edb1 100644 --- a/framework/include/celix/dm/DependencyManager.h +++ b/framework/include/celix/dm/DependencyManager.h @@ -25,7 +25,7 @@ #include "celix/dm/Component.h" #include "celix/dm/ServiceDependency.h" -#include "bundle_context.h" +#include "celix_bundle_context.h" #include "dm_dependency_manager.h" #include <vector> http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/impl/BundleContextImpl.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/impl/BundleContextImpl.h b/framework/include/celix/impl/BundleContextImpl.h index cc2bc0e..42af304 100644 --- a/framework/include/celix/impl/BundleContextImpl.h +++ b/framework/include/celix/impl/BundleContextImpl.h @@ -166,36 +166,30 @@ namespace celix { protected: - long registerServiceInternal(const std::string &serviceName, void *svc, const std::string &version, const std::string &lang, Properties props = {}) noexcept override { - properties_t *c_props = properties_create(); - for (auto &pair : props) { - properties_set(c_props, pair.first.c_str(), pair.second.c_str()); - } - return celix_bundleContext_registerServiceForLang(this->c_ctx, serviceName.c_str(), svc, version.c_str(), lang.c_str(), c_props); + long registerServiceInternal(const celix_service_registration_options_t &opts) noexcept override { + return celix_bundleContext_registerServiceWithOptions(this->c_ctx, &opts); } - long trackServiceInternal(const std::string &serviceName, - std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> set) noexcept override { - celix_service_tracking_options_t opts; - std::memset(&opts, 0, sizeof(opts)); + long trackServiceInternal(const std::string &serviceName, std::function<void(void *svc)> set) noexcept override { + celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS; - auto c_set = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) { + auto c_set = [](void *handle, void *svc) { auto *entry = static_cast<TrackEntry*>(handle); - celix::Properties props = createFromCProps(c_props); - auto m_bnd = const_cast<celix_bundle_t *>(c_bnd); - celix::impl::BundleImpl bnd{m_bnd}; - (entry->set)(svc, props, bnd); + //celix::Properties props = createFromCProps(c_props); + //auto m_bnd = const_cast<celix_bundle_t *>(c_bnd); + //celix::impl::BundleImpl bnd{m_bnd}; + (entry->set)(svc); }; const char *cname = serviceName.empty() ? nullptr : serviceName.c_str(); - opts.serviceName = cname; - opts.lang = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE; + opts.filter.serviceName = cname; + opts.filter.serviceLanguage = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE; auto te = std::unique_ptr<TrackEntry>{new TrackEntry{}}; te->set = std::move(set); opts.callbackHandle = te.get(); - opts.setWithOwner = c_set; + opts.set = c_set; long id = celix_bundleContext_trackServicesWithOptions(this->c_ctx, &opts); if (id >= 0) { @@ -207,37 +201,37 @@ namespace celix { long trackServicesInternal( const std::string &serviceName, - std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> add, - std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> remove + std::function<void(void *svc)> add, + std::function<void(void *svc)> remove ) noexcept override { celix_service_tracking_options_t opts; std::memset(&opts, 0, sizeof(opts)); - auto c_add = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) { + auto c_add = [](void *handle, void *svc) { auto *entry = static_cast<TrackEntry*>(handle); - celix::Properties props = createFromCProps(c_props); - auto m_bnd = const_cast<celix_bundle_t *>(c_bnd); - celix::impl::BundleImpl bnd{m_bnd}; - (entry->add)(svc, props, bnd); + //celix::Properties props = createFromCProps(c_props); + //auto m_bnd = const_cast<celix_bundle_t *>(c_bnd); + //celix::impl::BundleImpl bnd{m_bnd}; + (entry->add)(svc); }; - auto c_remove = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) { + auto c_remove = [](void *handle, void *svc) { auto *entry = static_cast<TrackEntry*>(handle); - celix::Properties props = createFromCProps(c_props); - auto m_bnd = const_cast<celix_bundle_t *>(c_bnd); - celix::impl::BundleImpl bnd{m_bnd}; - (entry->remove)(svc, props, bnd); + //celix::Properties props = createFromCProps(c_props); + //auto m_bnd = const_cast<celix_bundle_t *>(c_bnd); + //celix::impl::BundleImpl bnd{m_bnd}; + (entry->remove)(svc); }; - opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str(); - opts.lang = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE; + opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str(); + opts.filter.serviceLanguage = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE; auto te = std::unique_ptr<TrackEntry>{new TrackEntry{}}; te->add = std::move(add); te->remove = std::move(remove); opts.callbackHandle = te.get(); - opts.addWithOwner = c_add; - opts.removeWithOwner = c_remove; + opts.add = c_add; + opts.remove = c_remove; long id = celix_bundleContext_trackServicesWithOptions(this->c_ctx, &opts); if (id >= 0) { @@ -261,10 +255,10 @@ namespace celix { celix_service_use_options_t opts; std::memset(&opts, 0, sizeof(opts)); - opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();; - opts.lang = celix::Constants::SERVICE_CXX_LANG; + opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();; + opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG; opts.callbackHandle = (void*)&use; - opts.use = c_use; + opts.useWithOwner = c_use; return celix_bundleContext_useServiceWithOptions(this->c_ctx, &opts); } @@ -283,10 +277,10 @@ namespace celix { celix_service_use_options_t opts; std::memset(&opts, 0, sizeof(opts)); - opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();; - opts.lang = celix::Constants::SERVICE_CXX_LANG; + opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();; + opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG; opts.callbackHandle = (void*)&use; - opts.use = c_use; + opts.useWithOwner = c_use; celix_bundleContext_useServicesWithOptions(this->c_ctx, &opts); } @@ -299,9 +293,17 @@ namespace celix { celix::dm::DependencyManager dm; struct TrackEntry { - std::function<void(void *, const celix::Properties &, const celix::Bundle &)> set{}; - std::function<void(void *, const celix::Properties &, const celix::Bundle &)> add{}; - std::function<void(void *, const celix::Properties &, const celix::Bundle &)> remove{}; + std::function<void(void *)> set{}; + std::function<void(void *, const celix::Properties &)> setWithProperties{}; + std::function<void(void *, const celix::Properties &, const celix::Bundle &)> setWithOwner{}; + + std::function<void(void *)> add{}; + std::function<void(void *, const celix::Properties &)> addWithProperties{}; + std::function<void(void *, const celix::Properties &, const celix::Bundle &)> addWithOwner{}; + + std::function<void(void *)> remove{}; + std::function<void(void *, const celix::Properties &)> removeWithProperties{}; + std::function<void(void *, const celix::Properties &, const celix::Bundle &)> removeWithOwner{}; }; std::mutex mutex{}; @@ -310,4 +312,60 @@ namespace celix { } } + +template<typename I> +long celix::BundleContext::registerService(I *svc, const std::string &serviceName, Properties props) noexcept { + celix::ServiceRegistrationOptions<I> opts{*svc, serviceName}; + opts.properties = std::move(props); + return this->registerServiceWithOptions(opts); +} + +template<typename I> +long celix::BundleContext::registerCService(I *svc, const std::string &serviceName, Properties props) noexcept { + static_assert(std::is_pod<I>::value, "Service I must be a 'Plain Old Data' object"); + celix::ServiceRegistrationOptions<I> opts{*svc, serviceName}; + opts.properties = std::move(props); + opts.serviceLanguage = celix::Constants::SERVICE_C_LANG; + return this->registerServiceWithOptions(opts); +} + +template<typename I> +long celix::BundleContext::registerServiceWithOptions(const celix::ServiceRegistrationOptions<I>& opts) noexcept { + celix_properties_t *c_props = celix_properties_create(); + for (auto &pair : opts.properties) { + celix_properties_set(c_props, pair.first.c_str(), pair.second.c_str()); + } + + celix_service_registration_options_t cOpts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS; + cOpts.svc = static_cast<void*>(&opts.svc); + cOpts.serviceName = opts.serviceName.c_str(); + cOpts.serviceVersion = opts.serviceVersion.c_str(); + cOpts.serviceLanguage = opts.serviceLanguage.c_str(); + cOpts.properties = c_props; + return this->registerServiceInternal(cOpts); +} + +template<typename I> +long celix::BundleContext::trackService(const std::string &serviceName, std::function<void(I *svc)> set) noexcept { + return this->trackServiceInternal(serviceName, [set](void *voidSvc) { + I* typedSvc = static_cast<I*>(voidSvc); + set(typedSvc); + }); +} + +template<typename I> +long celix::BundleContext::trackServices(const std::string &serviceName, + std::function<void(I *svc)> add, std::function<void(I *svc)> remove) noexcept { + auto voidAdd = [add](void *voidSvc) { + I *typedSvc = static_cast<I *>(voidSvc); + add(typedSvc); + }; + auto voidRemove = [remove](void *voidSvc) { + I *typedSvc = static_cast<I *>(voidSvc); + remove(typedSvc); + }; + return this->trackServicesInternal(serviceName, std::move(voidAdd), std::move(voidRemove)); +} + + #endif //CELIX_IMPL_BUNDLECONTEXTIMPL_H http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/impl/BundleImpl.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/impl/BundleImpl.h b/framework/include/celix/impl/BundleImpl.h index 1f5c9c8..5fc6374 100644 --- a/framework/include/celix/impl/BundleImpl.h +++ b/framework/include/celix/impl/BundleImpl.h @@ -21,6 +21,7 @@ #define CELIX_IMPL_BUNDLEIMPL_H #include "celix_bundle.h" +#include "celix_bundle_context.h" namespace celix { http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/impl/FrameworkImpl.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/impl/FrameworkImpl.h b/framework/include/celix/impl/FrameworkImpl.h index 0b7475e..7043ffa 100644 --- a/framework/include/celix/impl/FrameworkImpl.h +++ b/framework/include/celix/impl/FrameworkImpl.h @@ -17,8 +17,8 @@ *under the License. */ -#ifndef CELIX_IMPL_FRAMEWORKIMPL_H -#define CELIX_IMPL_FRAMEWORKIMPL_H +#ifndef CXX_CELIX_IMPL_FRAMEWORKIMPL_H +#define CXX_CELIX_IMPL_FRAMEWORKIMPL_H #include "celix_framework_factory.h" #include "framework.h" @@ -81,8 +81,9 @@ namespace celix { } //TODO also in c virtual void breakWaitForStops() noexcept = 0; - virtual std::string getUUID() const noexcept override { - return std::string{framework_getUUID(this->c_fwm)}; + std::string getUUID() const noexcept override { + //TODO return std::string{celix_framework_getUUID(this->c_fwm)}; + return "TODO"; } celix::BundleContext& getFrameworkContext() noexcept override { @@ -123,4 +124,4 @@ namespace celix { } } -#endif //CELIX_IMPL_FRAMEWORKIMPL_H +#endif //CXX_CELIX_IMPL_FRAMEWORKIMPL_H http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix_bundle.h ---------------------------------------------------------------------- diff --git a/framework/include/celix_bundle.h b/framework/include/celix_bundle.h index 9b38627..798a6f7 100644 --- a/framework/include/celix_bundle.h +++ b/framework/include/celix_bundle.h @@ -33,12 +33,13 @@ extern "C" { ********************************************************************************************************************** **********************************************************************************************************************/ - long celix_bundle_getId(const bundle_t *bnd); - - celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd); - - + long celix_bundle_getId(const celix_bundle_t *bnd); + celix_bundle_state_e celix_bundle_getState(const celix_bundle_t *bnd); + + char* celix_bundle_getEntry(const celix_bundle_t *bnd, const char* name); + + #ifdef __cplusplus } #endif http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix_bundle_context.h ---------------------------------------------------------------------- diff --git a/framework/include/celix_bundle_context.h b/framework/include/celix_bundle_context.h index 1e8dff5..4c7af12 100644 --- a/framework/include/celix_bundle_context.h +++ b/framework/include/celix_bundle_context.h @@ -650,7 +650,7 @@ long celix_bundleContext_trackBundlesWithOptions( * @param use The callback which will be called for the currently started bundles. * The bundle pointers are only guaranteed to be valid during the callback. */ -void celix_bundleContext_useBundle( +bool celix_bundleContext_useBundle( celix_bundle_context_t *ctx, long bundleId, void *callbackHandle, @@ -684,6 +684,13 @@ void celix_bundleContext_useBundles( */ dm_dependency_manager_t* celix_bundleContext_getDependencyManager(celix_bundle_context_t *ctx); +/** + * Gets the bundle for this bundle context + * + * @return the bundle or NULL if unsuccessful. + */ + celix_bundle_t* celix_bundleContext_getBundle(celix_bundle_context_t *ctx); + #ifdef __cplusplus } #endif http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/framework.h ---------------------------------------------------------------------- diff --git a/framework/include/framework.h b/framework/include/framework.h index 0b718af..6f6827c 100644 --- a/framework/include/framework.h +++ b/framework/include/framework.h @@ -51,8 +51,6 @@ FRAMEWORK_EXPORT celix_status_t framework_stop(framework_t *framework); FRAMEWORK_EXPORT celix_status_t framework_destroy(framework_t *framework); -FRAMEWORK_EXPORT const char* framework_getUUID(framework_t *framework); - FRAMEWORK_EXPORT celix_status_t fw_init(framework_t *framework); FRAMEWORK_EXPORT celix_status_t framework_waitForStop(framework_t *framework); http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/private/mock/framework_mock.c ---------------------------------------------------------------------- diff --git a/framework/private/mock/framework_mock.c b/framework/private/mock/framework_mock.c index 86a2791..9933dc0 100644 --- a/framework/private/mock/framework_mock.c +++ b/framework/private/mock/framework_mock.c @@ -16,13 +16,7 @@ *specific language governing permissions and limitations *under the License. */ -/* - * framework_mock.c - * - * \date Feb 7, 2013 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ + #include <CppUTestExt/MockSupport_c.h> #include "CppUTestExt/MockSupport_c.h" http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/src/BundleImpl.c ---------------------------------------------------------------------- diff --git a/framework/src/BundleImpl.c b/framework/src/BundleImpl.c deleted file mode 100644 index 0fcba53..0000000 --- a/framework/src/BundleImpl.c +++ /dev/null @@ -1,765 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you 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. - */ - -#include <stdlib.h> -#include <string.h> - -#include "framework_private.h" -#include "bundle_private.h" -#include "resolver.h" -#include "utils.h" - -celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module); -celix_status_t bundle_closeRevisions(bundle_pt bundle); - -celix_status_t bundle_create(bundle_pt * bundle) { - celix_status_t status; - bundle_archive_pt archive = NULL; - - *bundle = (bundle_pt) malloc(sizeof(**bundle)); - if (*bundle == NULL) { - return CELIX_ENOMEM; - } - status = bundleArchive_createSystemBundleArchive(&archive); - if (status == CELIX_SUCCESS) { - module_pt module; - - (*bundle)->archive = archive; - (*bundle)->activator = NULL; - (*bundle)->context = NULL; - (*bundle)->framework = NULL; - (*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED; - (*bundle)->modules = NULL; - arrayList_create(&(*bundle)->modules); - (*bundle)->handle = NULL; - (*bundle)->manifest = NULL; - - module = module_createFrameworkModule((*bundle)); - bundle_addModule(*bundle, module); - - status = celixThreadMutex_create(&(*bundle)->lock, NULL); - if (status != CELIX_SUCCESS) { - status = CELIX_ILLEGAL_STATE; - } else { - (*bundle)->lockCount = 0; - (*bundle)->lockThread = celix_thread_default; - } - } - framework_logIfError(logger, status, NULL, "Failed to create bundle"); - - return status; -} - -celix_status_t bundle_createFromArchive(bundle_pt * bundle, framework_pt framework, bundle_archive_pt archive) { - module_pt module; - - celix_status_t status; - - *bundle = (bundle_pt) malloc(sizeof(**bundle)); - if (*bundle == NULL) { - return CELIX_ENOMEM; - } - (*bundle)->archive = archive; - (*bundle)->activator = NULL; - (*bundle)->context = NULL; - (*bundle)->handle = NULL; - (*bundle)->manifest = NULL; - (*bundle)->framework = framework; - (*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED; - (*bundle)->modules = NULL; - arrayList_create(&(*bundle)->modules); - - status = bundle_createModule(*bundle, &module); - if (status == CELIX_SUCCESS) { - bundle_addModule(*bundle, module); - status = celixThreadMutex_create(&(*bundle)->lock, NULL); - if (status != CELIX_SUCCESS) { - status = CELIX_ILLEGAL_STATE; - } else { - (*bundle)->lockCount = 0; - (*bundle)->lockThread = celix_thread_default; - } - } else { - status = CELIX_FILE_IO_EXCEPTION; - } - - framework_logIfError(logger, status, NULL, "Failed to create bundle"); - - return status; -} - -celix_status_t bundle_destroy(bundle_pt bundle) { - array_list_iterator_pt iter = arrayListIterator_create(bundle->modules); - while (arrayListIterator_hasNext(iter)) { - module_pt module = arrayListIterator_next(iter); - module_destroy(module); - } - arrayListIterator_destroy(iter); - arrayList_destroy(bundle->modules); - celixThreadMutex_destroy(&bundle->lock); - - free(bundle); - - return CELIX_SUCCESS; -} - -celix_status_t bundle_getArchive(bundle_pt bundle, bundle_archive_pt *archive) { - celix_status_t status = CELIX_SUCCESS; - - if (bundle != NULL && *archive == NULL) { - *archive = bundle->archive; - } else { - status = CELIX_ILLEGAL_ARGUMENT; - } - - framework_logIfError(logger, status, NULL, "Failed to get bundle archive"); - - return status; -} - -celix_status_t bundle_getCurrentModule(bundle_pt bundle, module_pt *module) { - celix_status_t status = CELIX_SUCCESS; - - if (bundle == NULL || arrayList_size(bundle->modules)==0 ) { - status = CELIX_ILLEGAL_ARGUMENT; - } else { - *module = arrayList_get(bundle->modules, arrayList_size(bundle->modules) - 1); - } - - return status; -} - -array_list_pt bundle_getModules(bundle_pt bundle) { - return bundle->modules; -} - -void * bundle_getHandle(bundle_pt bundle) { - return bundle->handle; -} - -void bundle_setHandle(bundle_pt bundle, void * handle) { - bundle->handle = handle; -} - -activator_pt bundle_getActivator(bundle_pt bundle) { - return bundle->activator; -} - -celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator) { - bundle->activator = activator; - return CELIX_SUCCESS; -} - -celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context) { - *context = bundle->context; - return CELIX_SUCCESS; -} - -celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context) { - bundle->context = context; - return CELIX_SUCCESS; -} - -celix_status_t bundle_getEntry(bundle_pt bundle, const char* name, char** out) { - char *entry = celix_bundle_getEntry(bundle, name); - if (out != NULL ) { - *out = entry; - } - return CELIX_SUCCESS; -} - -celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state) { - if(bundle==NULL){ - *state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN; - return CELIX_BUNDLE_EXCEPTION; - } - *state = bundle->state; - return CELIX_SUCCESS; -} - -celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state) { - bundle->state = state; - return CELIX_SUCCESS; -} - -celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module) { - celix_status_t status = CELIX_SUCCESS; - bundle_archive_pt archive = NULL; - bundle_revision_pt revision = NULL; - manifest_pt headerMap = NULL; - - status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive)); - status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision)); - status = CELIX_DO_IF(status, bundleRevision_getManifest(revision, &headerMap)); - if (status == CELIX_SUCCESS) { - long bundleId = 0; - status = bundleArchive_getId(bundle->archive, &bundleId); - if (status == CELIX_SUCCESS) { - int revision = 0; - char moduleId[512]; - - snprintf(moduleId, sizeof(moduleId), "%ld.%d", bundleId, revision); - *module = module_create(headerMap, moduleId, bundle); - - if (*module != NULL) { - version_pt bundleVersion = module_getVersion(*module); - const char * symName = NULL; - status = module_getSymbolicName(*module, &symName); - if (status == CELIX_SUCCESS) { - array_list_pt bundles = framework_getBundles(bundle->framework); - unsigned int i; - for (i = 0; i < arrayList_size(bundles); i++) { - bundle_pt check = (bundle_pt) arrayList_get(bundles, i); - - long id; - if (bundleArchive_getId(check->archive, &id) == CELIX_SUCCESS) { - if (id != bundleId) { - module_pt mod = NULL; - const char * sym = NULL; - version_pt version; - int cmp; - status = bundle_getCurrentModule(check, &mod); - status = module_getSymbolicName(mod, &sym); - - version = module_getVersion(mod); - version_compareTo(bundleVersion, version, &cmp); - if ((symName != NULL) && (sym != NULL) && !strcmp(symName, sym) && - !cmp) { - char *versionString = NULL; - version_toString(version, &versionString); - printf("Bundle symbolic name and version are not unique: %s:%s\n", sym, versionString); - free(versionString); - status = CELIX_BUNDLE_EXCEPTION; - break; - } - } - } - } - arrayList_destroy(bundles); - } - } - } - } - - framework_logIfError(logger, status, NULL, "Failed to create module"); - - return status; -} - -celix_status_t bundle_start(bundle_pt bundle) { - return bundle_startWithOptions(bundle, 0); -} - -celix_status_t bundle_startWithOptions(bundle_pt bundle, int options) { - celix_status_t status = CELIX_SUCCESS; - if (bundle != NULL) { - bool systemBundle = false; - status = bundle_isSystemBundle(bundle, &systemBundle); - if (status == CELIX_SUCCESS) { - if (systemBundle) { - framework_start(bundle->framework); - } else { - status = fw_startBundle(bundle->framework, bundle, options); - } - } - } - - framework_logIfError(logger, status, NULL, "Failed to start bundle"); - - return status; -} - -celix_status_t bundle_update(bundle_pt bundle, const char *inputFile) { - celix_status_t status = CELIX_SUCCESS; - if (bundle != NULL) { - bool systemBundle = false; - status = bundle_isSystemBundle(bundle, &systemBundle); - if (status == CELIX_SUCCESS) { - if (systemBundle) { - // #TODO: Support framework update - status = CELIX_BUNDLE_EXCEPTION; - } else { - status = framework_updateBundle(bundle->framework, bundle, inputFile); - } - } - } - - framework_logIfError(logger, status, NULL, "Failed to update bundle"); - - return status; -} - -celix_status_t bundle_stop(bundle_pt bundle) { - return bundle_stopWithOptions(bundle, 0); -} - -celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options) { - celix_status_t status = CELIX_SUCCESS; - if (bundle != NULL) { - bool systemBundle = false; - status = bundle_isSystemBundle(bundle, &systemBundle); - if (status == CELIX_SUCCESS) { - if (systemBundle) { - framework_stop(bundle->framework); - } else { - status = fw_stopBundle(bundle->framework, bundle, options); - } - } - } - - framework_logIfError(logger, status, NULL, "Failed to stop bundle"); - - return status; -} - -celix_status_t bundle_uninstall(bundle_pt bundle) { - celix_status_t status = CELIX_SUCCESS; - if (bundle != NULL) { - bool systemBundle = false; - status = bundle_isSystemBundle(bundle, &systemBundle); - if (status == CELIX_SUCCESS) { - if (systemBundle) { - status = CELIX_BUNDLE_EXCEPTION; - } else { - status = fw_uninstallBundle(bundle->framework, bundle); - } - } - } - - framework_logIfError(logger, status, NULL, "Failed to uninstall bundle"); - - return status; -} - -celix_status_t bundle_setPersistentStateInactive(bundle_pt bundle) { - celix_status_t status; - bool systemBundle; - - status = bundle_isSystemBundle(bundle, &systemBundle); - if (status == CELIX_SUCCESS) { - if (!systemBundle) { - status = bundleArchive_setPersistentState(bundle->archive, OSGI_FRAMEWORK_BUNDLE_INSTALLED); - } - } - - framework_logIfError(logger, status, NULL, "Failed to set persistent state to inactive"); - - return status; -} - -celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle) { - celix_status_t status; - bool systemBundle; - - status = bundle_isSystemBundle(bundle, &systemBundle); - if (status == CELIX_SUCCESS) { - if (!systemBundle) { - status = bundleArchive_setPersistentState(bundle->archive, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED); - } - } - - framework_logIfError(logger, status, NULL, "Failed to set persistent state to uninstalled"); - - return status; -} - -celix_status_t bundle_revise(bundle_pt bundle, const char * location, const char *inputFile) { - celix_status_t status; - - bundle_archive_pt archive = NULL; - status = bundle_getArchive(bundle, &archive); - if (status == CELIX_SUCCESS) { - status = bundleArchive_revise(archive, location, inputFile); - if (status == CELIX_SUCCESS) { - module_pt module; - status = bundle_createModule(bundle, &module); - if (status == CELIX_SUCCESS) { - status = bundle_addModule(bundle, module); - } else { - bool rolledback; - status = bundleArchive_rollbackRevise(archive, &rolledback); - if (status == CELIX_SUCCESS) { - status = CELIX_BUNDLE_EXCEPTION; - } - } - } - } - - framework_logIfError(logger, status, NULL, "Failed to revise bundle"); - - return status; -} - -//bool bundle_rollbackRevise(bundle_pt bundle) { -// module_pt module = arrayList_remove(bundle->modules, arrayList_set(bundle->modules) - 1); -// return resolver_removeModule(module); -//} - -celix_status_t bundle_addModule(bundle_pt bundle, module_pt module) { - arrayList_add(bundle->modules, module); - resolver_addModule(module); - return CELIX_SUCCESS; -} - -celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle) { - celix_status_t status; - long bundleId; - bundle_archive_pt archive = NULL; - - status = bundle_getArchive(bundle, &archive); - if (status == CELIX_SUCCESS) { - status = bundleArchive_getId(archive, &bundleId); - if (status == CELIX_SUCCESS) { - *systemBundle = (bundleId == 0); - } - } - - framework_logIfError(logger, status, NULL, "Failed to check if bundle is the systembundle"); - - return status; -} - -celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable) { - celix_status_t status; - - status = celixThreadMutex_lock(&bundle->lock); - if (status != CELIX_SUCCESS) { - status = CELIX_BUNDLE_EXCEPTION; - } else { - bool equals; - status = thread_equalsSelf(bundle->lockThread, &equals); - if (status == CELIX_SUCCESS) { - *lockable = (bundle->lockCount == 0) || (equals); - } - - status = celixThreadMutex_unlock(&bundle->lock); - if (status != CELIX_SUCCESS) { - status = CELIX_BUNDLE_EXCEPTION; - } - } - - framework_logIfError(logger, status, NULL, "Failed to check if bundle is lockable"); - - return status; -} - -celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread) { - celix_status_t status; - - status = celixThreadMutex_lock(&bundle->lock); - if (status != CELIX_SUCCESS) { - status = CELIX_BUNDLE_EXCEPTION; - } else { - *thread = bundle->lockThread; - - status = celixThreadMutex_unlock(&bundle->lock); - if (status != CELIX_SUCCESS) { - status = CELIX_BUNDLE_EXCEPTION; - } - } - - framework_logIfError(logger, status, NULL, "Failed to get locking thread"); - - return status; -} - -celix_status_t bundle_lock(bundle_pt bundle, bool *locked) { - celix_status_t status; - bool equals; - - celixThreadMutex_lock(&bundle->lock); - - status = thread_equalsSelf(bundle->lockThread, &equals); - if (status == CELIX_SUCCESS) { - if ((bundle->lockCount > 0) && !equals) { - *locked = false; - } else { - bundle->lockCount++; - bundle->lockThread = celixThread_self(); - *locked = true; - } - } - - celixThreadMutex_unlock(&bundle->lock); - - framework_logIfError(logger, status, NULL, "Failed to lock bundle"); - - return status; -} - -celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked) { - celix_status_t status = CELIX_SUCCESS; - - bool equals; - - celixThreadMutex_lock(&bundle->lock); - - if (bundle->lockCount == 0) { - *unlocked = false; - } else { - status = thread_equalsSelf(bundle->lockThread, &equals); - if (status == CELIX_SUCCESS) { - if ((bundle->lockCount > 0) && !equals) { - *unlocked = false; - } - else{ - bundle->lockCount--; - if (bundle->lockCount == 0) { - bundle->lockThread = celix_thread_default; - } - *unlocked = true; - } - } - } - - celixThreadMutex_unlock(&bundle->lock); - - framework_logIfError(logger, status, NULL, "Failed to unlock bundle"); - - return status; -} - -celix_status_t bundle_close(bundle_pt bundle) { - bundle_archive_pt archive = NULL; - - celix_status_t status; - - bundle_closeModules(bundle); - bundle_closeRevisions(bundle); - status = bundle_getArchive(bundle, &archive); - if (status == CELIX_SUCCESS) { - bundleArchive_close(archive); - } - - framework_logIfError(logger, status, NULL, "Failed to close bundle"); - - return status; -} - -celix_status_t bundle_closeAndDelete(bundle_pt bundle) { - celix_status_t status; - - bundle_archive_pt archive = NULL; - - bundle_closeModules(bundle); - bundle_closeRevisions(bundle); - status = bundle_getArchive(bundle, &archive); - if (status == CELIX_SUCCESS) { - bundleArchive_closeAndDelete(archive); - } - - framework_logIfError(logger, status, NULL, "Failed to close and delete bundle"); - - return status; -} - -celix_status_t bundle_closeRevisions(bundle_pt bundle) { - celix_status_t status = CELIX_SUCCESS; - - // TODO implement this - return status; -} - -celix_status_t bundle_closeModules(bundle_pt bundle) { - celix_status_t status = CELIX_SUCCESS; - - unsigned int i = 0; - for (i = 0; i < arrayList_size(bundle->modules); i++) { - module_pt module = (module_pt) arrayList_get(bundle->modules, i); - resolver_removeModule(module); - module_setWires(module, NULL); - } - - return status; -} - -celix_status_t bundle_refresh(bundle_pt bundle) { - celix_status_t status; - module_pt module; - - status = bundle_closeModules(bundle); - if (status == CELIX_SUCCESS) { - arrayList_clear(bundle->modules); - status = bundle_createModule(bundle, &module); - if (status == CELIX_SUCCESS) { - status = bundle_addModule(bundle, module); - if (status == CELIX_SUCCESS) { - bundle->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED; - } - } - } - - framework_logIfError(logger, status, NULL, "Failed to refresh bundle"); - - return status; -} - -celix_status_t bundle_getBundleId(bundle_t *bundle, long *bndId) { - celix_status_t status = CELIX_SUCCESS; - long id = celix_bundle_getId(bundle); - if (id >= 0) { - *bndId = id; - } else { - status = CELIX_BUNDLE_EXCEPTION; - *bndId = -1; - } - return status; -} - -celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt *list) { - celix_status_t status; - - status = fw_getBundleRegisteredServices(bundle->framework, bundle, list); - - framework_logIfError(bundle->framework->logger, status, NULL, "Failed to get registered services"); - - return status; -} - -celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list) { - celix_status_t status; - - status = fw_getBundleServicesInUse(bundle->framework, bundle, list); - - framework_logIfError(logger, status, NULL, "Failed to get in use services"); - - return status; -} - -celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework) { - celix_status_t status = CELIX_SUCCESS; - - if (bundle != NULL && framework != NULL) { - bundle->framework = framework; - } else { - status = CELIX_ILLEGAL_ARGUMENT; - } - - framework_logIfError(logger, status, NULL, "Failed to set framework"); - - return status; -} - -celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework) { - celix_status_t status = CELIX_SUCCESS; - - if (bundle != NULL && *framework == NULL) { - *framework = bundle->framework; - } else { - status = CELIX_ILLEGAL_ARGUMENT; - } - - framework_logIfError(logger, status, NULL, "Failed to get framework"); - - return status; -} - -celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location){ - celix_status_t status; - - bundle_archive_pt archive = NULL; - - status = bundle_getArchive(bundle, &archive); - if (status != CELIX_SUCCESS){ - printf("[ ERROR ]: Bundle - getBundleLocation (BundleArchive) \n"); - return status; - } - - status = bundleArchive_getLocation(archive, location); - if (status != CELIX_SUCCESS){ - printf("[ ERROR ]: Bundle - getBundleLocation (BundleArchiveLocation) \n"); - return status; - } - - return CELIX_SUCCESS; -} - - -celix_status_t bundle_getBundleCache(bundle_pt bundle, const char **out) { - celix_status_t status; - - const char *cache = NULL; - bundle_archive_pt archive = NULL; - bundle_revision_pt rev = NULL; - - status = bundle_getArchive(bundle, &archive); - if (status != CELIX_SUCCESS){ - printf("[ ERROR ]: Bundle - bundle_getBundleCache (BundleArchive) \n"); - return status; - } - - status = bundleArchive_getCurrentRevision(archive, &rev); - if (status != CELIX_SUCCESS){ - printf("[ ERROR ]: Bundle - bundle_getBundleCache (BundleArchiveRevision) \n"); - return status; - } - - status = bundleRevision_getRoot(rev, &cache); - if (status != CELIX_SUCCESS){ - printf("[ ERROR ]: Bundle - bundle_getBundleCache (BundleArchiveRevision) \n"); - return status; - } - - if (out != NULL) { - *out = cache; - } - - return CELIX_SUCCESS; -} - - - - -/********************************************************************************************************************** - ********************************************************************************************************************** - * Updated API - ********************************************************************************************************************** - **********************************************************************************************************************/ - -long celix_bundle_getId(const bundle_t* bnd) { - long bndId = -1; - bundle_archive_pt archive = NULL; - if (bnd != NULL) { - bundle_getArchive((bundle_t *) bnd, &archive); - } - if (archive != NULL) { - bundleArchive_getId(archive, &bndId); - } - if (bndId < 0) { - framework_logIfError(logger, CELIX_BUNDLE_EXCEPTION, NULL, "Failed to get bundle id"); - } - return bndId; -} - -celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd) { - celix_bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN; - if (bnd != NULL) { - state = bnd->state; - } - return state; -} - -char* celix_bundle_getEntry(const bundle_t *bnd, const char *relPath) { - char *entry = NULL; - if (bnd != NULL) { - framework_getBundleEntry(bnd->framework, (bundle_t*)bnd, relPath, &entry); - } - return entry; -} - http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/src/bundle.c ---------------------------------------------------------------------- diff --git a/framework/src/bundle.c b/framework/src/bundle.c new file mode 100644 index 0000000..cbdf794 --- /dev/null +++ b/framework/src/bundle.c @@ -0,0 +1,766 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you 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. + */ + +#include <stdlib.h> +#include <string.h> + +#include "framework_private.h" +#include "bundle_private.h" +#include "resolver.h" +#include "utils.h" +#include "celix_bundle.h" + +celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module); +celix_status_t bundle_closeRevisions(bundle_pt bundle); + +celix_status_t bundle_create(bundle_pt * bundle) { + celix_status_t status; + bundle_archive_pt archive = NULL; + + *bundle = (bundle_pt) malloc(sizeof(**bundle)); + if (*bundle == NULL) { + return CELIX_ENOMEM; + } + status = bundleArchive_createSystemBundleArchive(&archive); + if (status == CELIX_SUCCESS) { + module_pt module; + + (*bundle)->archive = archive; + (*bundle)->activator = NULL; + (*bundle)->context = NULL; + (*bundle)->framework = NULL; + (*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED; + (*bundle)->modules = NULL; + arrayList_create(&(*bundle)->modules); + (*bundle)->handle = NULL; + (*bundle)->manifest = NULL; + + module = module_createFrameworkModule((*bundle)); + bundle_addModule(*bundle, module); + + status = celixThreadMutex_create(&(*bundle)->lock, NULL); + if (status != CELIX_SUCCESS) { + status = CELIX_ILLEGAL_STATE; + } else { + (*bundle)->lockCount = 0; + (*bundle)->lockThread = celix_thread_default; + } + } + framework_logIfError(logger, status, NULL, "Failed to create bundle"); + + return status; +} + +celix_status_t bundle_createFromArchive(bundle_pt * bundle, framework_pt framework, bundle_archive_pt archive) { + module_pt module; + + celix_status_t status; + + *bundle = (bundle_pt) malloc(sizeof(**bundle)); + if (*bundle == NULL) { + return CELIX_ENOMEM; + } + (*bundle)->archive = archive; + (*bundle)->activator = NULL; + (*bundle)->context = NULL; + (*bundle)->handle = NULL; + (*bundle)->manifest = NULL; + (*bundle)->framework = framework; + (*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED; + (*bundle)->modules = NULL; + arrayList_create(&(*bundle)->modules); + + status = bundle_createModule(*bundle, &module); + if (status == CELIX_SUCCESS) { + bundle_addModule(*bundle, module); + status = celixThreadMutex_create(&(*bundle)->lock, NULL); + if (status != CELIX_SUCCESS) { + status = CELIX_ILLEGAL_STATE; + } else { + (*bundle)->lockCount = 0; + (*bundle)->lockThread = celix_thread_default; + } + } else { + status = CELIX_FILE_IO_EXCEPTION; + } + + framework_logIfError(logger, status, NULL, "Failed to create bundle"); + + return status; +} + +celix_status_t bundle_destroy(bundle_pt bundle) { + array_list_iterator_pt iter = arrayListIterator_create(bundle->modules); + while (arrayListIterator_hasNext(iter)) { + module_pt module = arrayListIterator_next(iter); + module_destroy(module); + } + arrayListIterator_destroy(iter); + arrayList_destroy(bundle->modules); + celixThreadMutex_destroy(&bundle->lock); + + free(bundle); + + return CELIX_SUCCESS; +} + +celix_status_t bundle_getArchive(bundle_pt bundle, bundle_archive_pt *archive) { + celix_status_t status = CELIX_SUCCESS; + + if (bundle != NULL && *archive == NULL) { + *archive = bundle->archive; + } else { + status = CELIX_ILLEGAL_ARGUMENT; + } + + framework_logIfError(logger, status, NULL, "Failed to get bundle archive"); + + return status; +} + +celix_status_t bundle_getCurrentModule(bundle_pt bundle, module_pt *module) { + celix_status_t status = CELIX_SUCCESS; + + if (bundle == NULL || arrayList_size(bundle->modules)==0 ) { + status = CELIX_ILLEGAL_ARGUMENT; + } else { + *module = arrayList_get(bundle->modules, arrayList_size(bundle->modules) - 1); + } + + return status; +} + +array_list_pt bundle_getModules(bundle_pt bundle) { + return bundle->modules; +} + +void * bundle_getHandle(bundle_pt bundle) { + return bundle->handle; +} + +void bundle_setHandle(bundle_pt bundle, void * handle) { + bundle->handle = handle; +} + +activator_pt bundle_getActivator(bundle_pt bundle) { + return bundle->activator; +} + +celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator) { + bundle->activator = activator; + return CELIX_SUCCESS; +} + +celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context) { + *context = bundle->context; + return CELIX_SUCCESS; +} + +celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context) { + bundle->context = context; + return CELIX_SUCCESS; +} + +celix_status_t bundle_getEntry(bundle_pt bundle, const char* name, char** out) { + char *entry = celix_bundle_getEntry(bundle, name); + if (out != NULL ) { + *out = entry; + } + return CELIX_SUCCESS; +} + +celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state) { + if(bundle==NULL){ + *state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN; + return CELIX_BUNDLE_EXCEPTION; + } + *state = bundle->state; + return CELIX_SUCCESS; +} + +celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state) { + bundle->state = state; + return CELIX_SUCCESS; +} + +celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module) { + celix_status_t status = CELIX_SUCCESS; + bundle_archive_pt archive = NULL; + bundle_revision_pt revision = NULL; + manifest_pt headerMap = NULL; + + status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive)); + status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision)); + status = CELIX_DO_IF(status, bundleRevision_getManifest(revision, &headerMap)); + if (status == CELIX_SUCCESS) { + long bundleId = 0; + status = bundleArchive_getId(bundle->archive, &bundleId); + if (status == CELIX_SUCCESS) { + int revision = 0; + char moduleId[512]; + + snprintf(moduleId, sizeof(moduleId), "%ld.%d", bundleId, revision); + *module = module_create(headerMap, moduleId, bundle); + + if (*module != NULL) { + version_pt bundleVersion = module_getVersion(*module); + const char * symName = NULL; + status = module_getSymbolicName(*module, &symName); + if (status == CELIX_SUCCESS) { + array_list_pt bundles = framework_getBundles(bundle->framework); + unsigned int i; + for (i = 0; i < arrayList_size(bundles); i++) { + bundle_pt check = (bundle_pt) arrayList_get(bundles, i); + + long id; + if (bundleArchive_getId(check->archive, &id) == CELIX_SUCCESS) { + if (id != bundleId) { + module_pt mod = NULL; + const char * sym = NULL; + version_pt version; + int cmp; + status = bundle_getCurrentModule(check, &mod); + status = module_getSymbolicName(mod, &sym); + + version = module_getVersion(mod); + version_compareTo(bundleVersion, version, &cmp); + if ((symName != NULL) && (sym != NULL) && !strcmp(symName, sym) && + !cmp) { + char *versionString = NULL; + version_toString(version, &versionString); + printf("Bundle symbolic name and version are not unique: %s:%s\n", sym, versionString); + free(versionString); + status = CELIX_BUNDLE_EXCEPTION; + break; + } + } + } + } + arrayList_destroy(bundles); + } + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to create module"); + + return status; +} + +celix_status_t bundle_start(bundle_pt bundle) { + return bundle_startWithOptions(bundle, 0); +} + +celix_status_t bundle_startWithOptions(bundle_pt bundle, int options) { + celix_status_t status = CELIX_SUCCESS; + if (bundle != NULL) { + bool systemBundle = false; + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (systemBundle) { + framework_start(bundle->framework); + } else { + status = fw_startBundle(bundle->framework, bundle, options); + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to start bundle"); + + return status; +} + +celix_status_t bundle_update(bundle_pt bundle, const char *inputFile) { + celix_status_t status = CELIX_SUCCESS; + if (bundle != NULL) { + bool systemBundle = false; + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (systemBundle) { + // #TODO: Support framework update + status = CELIX_BUNDLE_EXCEPTION; + } else { + status = framework_updateBundle(bundle->framework, bundle, inputFile); + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to update bundle"); + + return status; +} + +celix_status_t bundle_stop(bundle_pt bundle) { + return bundle_stopWithOptions(bundle, 0); +} + +celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options) { + celix_status_t status = CELIX_SUCCESS; + if (bundle != NULL) { + bool systemBundle = false; + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (systemBundle) { + framework_stop(bundle->framework); + } else { + status = fw_stopBundle(bundle->framework, bundle, options); + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to stop bundle"); + + return status; +} + +celix_status_t bundle_uninstall(bundle_pt bundle) { + celix_status_t status = CELIX_SUCCESS; + if (bundle != NULL) { + bool systemBundle = false; + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (systemBundle) { + status = CELIX_BUNDLE_EXCEPTION; + } else { + status = fw_uninstallBundle(bundle->framework, bundle); + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to uninstall bundle"); + + return status; +} + +celix_status_t bundle_setPersistentStateInactive(bundle_pt bundle) { + celix_status_t status; + bool systemBundle; + + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (!systemBundle) { + status = bundleArchive_setPersistentState(bundle->archive, OSGI_FRAMEWORK_BUNDLE_INSTALLED); + } + } + + framework_logIfError(logger, status, NULL, "Failed to set persistent state to inactive"); + + return status; +} + +celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle) { + celix_status_t status; + bool systemBundle; + + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (!systemBundle) { + status = bundleArchive_setPersistentState(bundle->archive, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED); + } + } + + framework_logIfError(logger, status, NULL, "Failed to set persistent state to uninstalled"); + + return status; +} + +celix_status_t bundle_revise(bundle_pt bundle, const char * location, const char *inputFile) { + celix_status_t status; + + bundle_archive_pt archive = NULL; + status = bundle_getArchive(bundle, &archive); + if (status == CELIX_SUCCESS) { + status = bundleArchive_revise(archive, location, inputFile); + if (status == CELIX_SUCCESS) { + module_pt module; + status = bundle_createModule(bundle, &module); + if (status == CELIX_SUCCESS) { + status = bundle_addModule(bundle, module); + } else { + bool rolledback; + status = bundleArchive_rollbackRevise(archive, &rolledback); + if (status == CELIX_SUCCESS) { + status = CELIX_BUNDLE_EXCEPTION; + } + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to revise bundle"); + + return status; +} + +//bool bundle_rollbackRevise(bundle_pt bundle) { +// module_pt module = arrayList_remove(bundle->modules, arrayList_set(bundle->modules) - 1); +// return resolver_removeModule(module); +//} + +celix_status_t bundle_addModule(bundle_pt bundle, module_pt module) { + arrayList_add(bundle->modules, module); + resolver_addModule(module); + return CELIX_SUCCESS; +} + +celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle) { + celix_status_t status; + long bundleId; + bundle_archive_pt archive = NULL; + + status = bundle_getArchive(bundle, &archive); + if (status == CELIX_SUCCESS) { + status = bundleArchive_getId(archive, &bundleId); + if (status == CELIX_SUCCESS) { + *systemBundle = (bundleId == 0); + } + } + + framework_logIfError(logger, status, NULL, "Failed to check if bundle is the systembundle"); + + return status; +} + +celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable) { + celix_status_t status; + + status = celixThreadMutex_lock(&bundle->lock); + if (status != CELIX_SUCCESS) { + status = CELIX_BUNDLE_EXCEPTION; + } else { + bool equals; + status = thread_equalsSelf(bundle->lockThread, &equals); + if (status == CELIX_SUCCESS) { + *lockable = (bundle->lockCount == 0) || (equals); + } + + status = celixThreadMutex_unlock(&bundle->lock); + if (status != CELIX_SUCCESS) { + status = CELIX_BUNDLE_EXCEPTION; + } + } + + framework_logIfError(logger, status, NULL, "Failed to check if bundle is lockable"); + + return status; +} + +celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread) { + celix_status_t status; + + status = celixThreadMutex_lock(&bundle->lock); + if (status != CELIX_SUCCESS) { + status = CELIX_BUNDLE_EXCEPTION; + } else { + *thread = bundle->lockThread; + + status = celixThreadMutex_unlock(&bundle->lock); + if (status != CELIX_SUCCESS) { + status = CELIX_BUNDLE_EXCEPTION; + } + } + + framework_logIfError(logger, status, NULL, "Failed to get locking thread"); + + return status; +} + +celix_status_t bundle_lock(bundle_pt bundle, bool *locked) { + celix_status_t status; + bool equals; + + celixThreadMutex_lock(&bundle->lock); + + status = thread_equalsSelf(bundle->lockThread, &equals); + if (status == CELIX_SUCCESS) { + if ((bundle->lockCount > 0) && !equals) { + *locked = false; + } else { + bundle->lockCount++; + bundle->lockThread = celixThread_self(); + *locked = true; + } + } + + celixThreadMutex_unlock(&bundle->lock); + + framework_logIfError(logger, status, NULL, "Failed to lock bundle"); + + return status; +} + +celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked) { + celix_status_t status = CELIX_SUCCESS; + + bool equals; + + celixThreadMutex_lock(&bundle->lock); + + if (bundle->lockCount == 0) { + *unlocked = false; + } else { + status = thread_equalsSelf(bundle->lockThread, &equals); + if (status == CELIX_SUCCESS) { + if ((bundle->lockCount > 0) && !equals) { + *unlocked = false; + } + else{ + bundle->lockCount--; + if (bundle->lockCount == 0) { + bundle->lockThread = celix_thread_default; + } + *unlocked = true; + } + } + } + + celixThreadMutex_unlock(&bundle->lock); + + framework_logIfError(logger, status, NULL, "Failed to unlock bundle"); + + return status; +} + +celix_status_t bundle_close(bundle_pt bundle) { + bundle_archive_pt archive = NULL; + + celix_status_t status; + + bundle_closeModules(bundle); + bundle_closeRevisions(bundle); + status = bundle_getArchive(bundle, &archive); + if (status == CELIX_SUCCESS) { + bundleArchive_close(archive); + } + + framework_logIfError(logger, status, NULL, "Failed to close bundle"); + + return status; +} + +celix_status_t bundle_closeAndDelete(bundle_pt bundle) { + celix_status_t status; + + bundle_archive_pt archive = NULL; + + bundle_closeModules(bundle); + bundle_closeRevisions(bundle); + status = bundle_getArchive(bundle, &archive); + if (status == CELIX_SUCCESS) { + bundleArchive_closeAndDelete(archive); + } + + framework_logIfError(logger, status, NULL, "Failed to close and delete bundle"); + + return status; +} + +celix_status_t bundle_closeRevisions(bundle_pt bundle) { + celix_status_t status = CELIX_SUCCESS; + + // TODO implement this + return status; +} + +celix_status_t bundle_closeModules(bundle_pt bundle) { + celix_status_t status = CELIX_SUCCESS; + + unsigned int i = 0; + for (i = 0; i < arrayList_size(bundle->modules); i++) { + module_pt module = (module_pt) arrayList_get(bundle->modules, i); + resolver_removeModule(module); + module_setWires(module, NULL); + } + + return status; +} + +celix_status_t bundle_refresh(bundle_pt bundle) { + celix_status_t status; + module_pt module; + + status = bundle_closeModules(bundle); + if (status == CELIX_SUCCESS) { + arrayList_clear(bundle->modules); + status = bundle_createModule(bundle, &module); + if (status == CELIX_SUCCESS) { + status = bundle_addModule(bundle, module); + if (status == CELIX_SUCCESS) { + bundle->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED; + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to refresh bundle"); + + return status; +} + +celix_status_t bundle_getBundleId(bundle_t *bundle, long *bndId) { + celix_status_t status = CELIX_SUCCESS; + long id = celix_bundle_getId(bundle); + if (id >= 0) { + *bndId = id; + } else { + status = CELIX_BUNDLE_EXCEPTION; + *bndId = -1; + } + return status; +} + +celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt *list) { + celix_status_t status; + + status = fw_getBundleRegisteredServices(bundle->framework, bundle, list); + + framework_logIfError(bundle->framework->logger, status, NULL, "Failed to get registered services"); + + return status; +} + +celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list) { + celix_status_t status; + + status = fw_getBundleServicesInUse(bundle->framework, bundle, list); + + framework_logIfError(logger, status, NULL, "Failed to get in use services"); + + return status; +} + +celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework) { + celix_status_t status = CELIX_SUCCESS; + + if (bundle != NULL && framework != NULL) { + bundle->framework = framework; + } else { + status = CELIX_ILLEGAL_ARGUMENT; + } + + framework_logIfError(logger, status, NULL, "Failed to set framework"); + + return status; +} + +celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework) { + celix_status_t status = CELIX_SUCCESS; + + if (bundle != NULL && *framework == NULL) { + *framework = bundle->framework; + } else { + status = CELIX_ILLEGAL_ARGUMENT; + } + + framework_logIfError(logger, status, NULL, "Failed to get framework"); + + return status; +} + +celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location){ + celix_status_t status; + + bundle_archive_pt archive = NULL; + + status = bundle_getArchive(bundle, &archive); + if (status != CELIX_SUCCESS){ + printf("[ ERROR ]: Bundle - getBundleLocation (BundleArchive) \n"); + return status; + } + + status = bundleArchive_getLocation(archive, location); + if (status != CELIX_SUCCESS){ + printf("[ ERROR ]: Bundle - getBundleLocation (BundleArchiveLocation) \n"); + return status; + } + + return CELIX_SUCCESS; +} + + +celix_status_t bundle_getBundleCache(bundle_pt bundle, const char **out) { + celix_status_t status; + + const char *cache = NULL; + bundle_archive_pt archive = NULL; + bundle_revision_pt rev = NULL; + + status = bundle_getArchive(bundle, &archive); + if (status != CELIX_SUCCESS){ + printf("[ ERROR ]: Bundle - bundle_getBundleCache (BundleArchive) \n"); + return status; + } + + status = bundleArchive_getCurrentRevision(archive, &rev); + if (status != CELIX_SUCCESS){ + printf("[ ERROR ]: Bundle - bundle_getBundleCache (BundleArchiveRevision) \n"); + return status; + } + + status = bundleRevision_getRoot(rev, &cache); + if (status != CELIX_SUCCESS){ + printf("[ ERROR ]: Bundle - bundle_getBundleCache (BundleArchiveRevision) \n"); + return status; + } + + if (out != NULL) { + *out = cache; + } + + return CELIX_SUCCESS; +} + + + + +/********************************************************************************************************************** + ********************************************************************************************************************** + * Updated API + ********************************************************************************************************************** + **********************************************************************************************************************/ + +long celix_bundle_getId(const bundle_t* bnd) { + long bndId = -1; + bundle_archive_pt archive = NULL; + if (bnd != NULL) { + bundle_getArchive((bundle_t *) bnd, &archive); + } + if (archive != NULL) { + bundleArchive_getId(archive, &bndId); + } + if (bndId < 0) { + framework_logIfError(logger, CELIX_BUNDLE_EXCEPTION, NULL, "Failed to get bundle id"); + } + return bndId; +} + +celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd) { + celix_bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN; + if (bnd != NULL) { + state = bnd->state; + } + return state; +} + +char* celix_bundle_getEntry(const bundle_t *bnd, const char *relPath) { + char *entry = NULL; + if (bnd != NULL) { + framework_getBundleEntry(bnd->framework, (bundle_t*)bnd, relPath, &entry); + } + return entry; +} + http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/src/bundle_context.c ---------------------------------------------------------------------- diff --git a/framework/src/bundle_context.c b/framework/src/bundle_context.c index b7afe82..1173e4a 100644 --- a/framework/src/bundle_context.c +++ b/framework/src/bundle_context.c @@ -867,4 +867,8 @@ celix_array_list_t* celix_bundleContext_findServicesWithOptions(celix_bundle_con useOpts.useWithProperties = bundleContext_retrieveSvcIds; celix_bundleContext_useServicesWithOptions(ctx, &useOpts); return list; +} + +celix_bundle_t* celix_bundleContext_getBundle(celix_bundle_context_t *ctx) { + return ctx->bundle; } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/src/framework.c ---------------------------------------------------------------------- diff --git a/framework/src/framework.c b/framework/src/framework.c index c87eaf4..12e5030 100644 --- a/framework/src/framework.c +++ b/framework/src/framework.c @@ -2772,16 +2772,19 @@ void celix_framework_useBundles(framework_t *fw, void *callbackHandle, void(*use } } -void celix_framework_useBundle(framework_t *fw, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)) { +bool celix_framework_useBundle(framework_t *fw, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)) { + bool called = false; if (bundleId >= 0) { //TODO get bundle lock without throwing errors framework_acquireBundleLock() -> a more simple lock ?? bundle_t *bnd = framework_getBundleById(fw, bundleId); celix_bundle_state_e bndState = celix_bundle_getState(bnd); if (bndState == OSGI_FRAMEWORK_BUNDLE_ACTIVE) { use(callbackHandle, bnd); + called = true; } //TODO unlock } + return called; } service_registration_t* celix_framework_registerServiceFactory(framework_t *fw , const celix_bundle_t *bnd, const char* serviceName, celix_service_factory_t *factory, celix_properties_t *properties) { http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/src/framework_private.h ---------------------------------------------------------------------- diff --git a/framework/src/framework_private.h b/framework/src/framework_private.h index a04bbaa..e02e272 100644 --- a/framework/src/framework_private.h +++ b/framework/src/framework_private.h @@ -16,13 +16,6 @@ *specific language governing permissions and limitations *under the License. */ -/* - * framework_private.h - * - * \date May 22, 2013 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ #ifndef FRAMEWORK_PRIVATE_H_ @@ -156,7 +149,7 @@ FRAMEWORK_EXPORT bundle_pt framework_getBundleById(framework_pt framework, long **********************************************************************************************************************/ void celix_framework_useBundles(framework_t *fw, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)); -void celix_framework_useBundle(framework_t *fw, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)); +bool celix_framework_useBundle(framework_t *fw, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)); service_registration_t* celix_framework_registerServiceFactory(framework_t *fw , const celix_bundle_t *bnd, const char* serviceName, celix_service_factory_t *factory, celix_properties_t *properties); #endif /* FRAMEWORK_PRIVATE_H_ */
