CELIX-426: Initial commit for the C++ api
Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/764bd7f7 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/764bd7f7 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/764bd7f7 Branch: refs/heads/feature/CELIX-426-cxx-api Commit: 764bd7f7a8ef2648bfbc79531d1915bb26e87aaa Parents: debb4b1 Author: Pepijn Noltes <[email protected]> Authored: Sun Apr 15 21:25:20 2018 +0200 Committer: Pepijn Noltes <[email protected]> Committed: Sun May 6 20:43:51 2018 +0200 ---------------------------------------------------------------------- CMakeLists.txt | 8 +- cmake/celix_project/AddGTest.cmake | 40 + cmake/cmake_celix/BundlePackaging.cmake | 9 + framework/CMakeLists.txt | 9 +- framework/gtest/CMakeLists.txt | 37 + framework/gtest/src/cxx_BundleContext_tests.cc | 233 ++++++ framework/gtest/src/cxx_Bundle_tests.cc | 66 ++ .../gtest/src/cxx_FrameworkFactory_tests.cc | 54 ++ framework/gtest/src/cxx_Framework_tests.cc | 45 ++ framework/gtest/src/main.cc | 25 + framework/include/bundle.h | 135 +--- framework/include/bundle_context.h | 23 +- framework/include/celix/Bundle.h | 77 ++ framework/include/celix/BundleContext.h | 241 ++++++ framework/include/celix/Celix.h | 36 + framework/include/celix/Constants.h | 47 ++ framework/include/celix/Framework.h | 51 ++ framework/include/celix/FrameworkFactory.h | 66 ++ framework/include/celix/IServiceFactory.h | 35 + framework/include/celix/Properties.h | 60 ++ framework/include/celix/dm/Properties.h | 5 +- .../include/celix/impl/BundleContextImpl.h | 293 +++++++ framework/include/celix/impl/BundleImpl.h | 171 ++++ framework/include/celix/impl/FrameworkImpl.h | 113 +++ framework/include/celix_api.h | 4 +- framework/include/celix_bundle.h | 153 ++++ framework/include/celix_constants.h | 79 ++ framework/include/celix_launcher.h | 6 +- framework/include/constants.h | 61 +- framework/include/framework.h | 13 +- framework/include/service_reference.h | 1 + framework/private/mock/bundle_context_mock.c | 3 +- framework/private/mock/bundle_mock.c | 14 + framework/src/BundleImpl.c | 771 +++++++++++++++++++ framework/src/bundle.c | 723 ----------------- framework/src/bundle_context.c | 4 +- framework/src/framework.c | 29 +- framework/src/framework_private.h | 7 +- shell/CMakeLists.txt | 2 +- utils/include/celix_exports.h | 25 + 40 files changed, 2811 insertions(+), 963 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index d534a55..0da1b5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,11 +51,15 @@ set(CELIX_MAJOR "2") set(CELIX_MINOR "2") set(CELIX_MICRO "0") -option(ENABLE_TESTING "Enables unit/bundle testing" FALSE) +option(ENABLE_TESTING "Enables unit testing using CPPUTEST" OFF) +option(ENABLE_GTESTING "Enables unit testing using GTest" ON) if (ENABLE_TESTING) enable_testing() -endif() +endif () +if (ENABLE_TESTING AND ENABLE_GTESTING) + include(cmake/celix_project/AddGTest.cmake) +endif () # Default bundle version set(DEFAULT_VERSION 1.0.0) http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/cmake/celix_project/AddGTest.cmake ---------------------------------------------------------------------- diff --git a/cmake/celix_project/AddGTest.cmake b/cmake/celix_project/AddGTest.cmake new file mode 100644 index 0000000..60705ed --- /dev/null +++ b/cmake/celix_project/AddGTest.cmake @@ -0,0 +1,40 @@ +# 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(ExternalProject) +ExternalProject_Add( + googletest_project + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG master + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gtest + INSTALL_COMMAND "" +) + +ExternalProject_Get_Property(googletest_project source_dir binary_dir) +add_library(gtest IMPORTED STATIC GLOBAL) +add_dependencies(gtest googletest_project) +set_target_properties(gtest PROPERTIES + IMPORTED_LOCATION "${binary_dir}/googlemock/gtest/libgtest.a" + INTERFACE_INCLUDE_DIRECTORIES "${source_dir}/googletest/include" +) + +add_library(gmock IMPORTED STATIC GLOBAL) +add_dependencies(gmock googletest_project) +set_target_properties(gmock PROPERTIES + IMPORTED_LOCATION "${binary_dir}/googlemock/libgmock.a" + INTERFACE_INCLUDE_DIRECTORIES "${source_dir}/googlemock/include" +) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/cmake/cmake_celix/BundlePackaging.cmake ---------------------------------------------------------------------- diff --git a/cmake/cmake_celix/BundlePackaging.cmake b/cmake/cmake_celix/BundlePackaging.cmake index 6666d20..bc65c68 100644 --- a/cmake/cmake_celix/BundlePackaging.cmake +++ b/cmake/cmake_celix/BundlePackaging.cmake @@ -280,6 +280,15 @@ function(add_celix_bundle) celix_bundle_headers(${BUNDLE_TARGET_NAME} ${BUNDLE_HEADERS}) endfunction() +function(add_celix_bundle_dependencies) + list(GET ARGN 0 TARGET) + list(REMOVE_AT ARGN 0) + + foreach(BND IN ITEMS ${ARGN}) + add_dependencies(${TARGET} ${BND}_bundle) + endforeach() +endfunction() + function(bundle_export_libs) message(DEPRECATION "bundle_export_libs is deprecated, use celix_bundle_export_libs instead.") celix_bundle_export_libs(${ARGN}) http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 9f237af..cdcd044 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -24,7 +24,7 @@ if(WIN32) endif(WIN32) set(SOURCES - src/attribute.c src/bundle.c src/bundle_archive.c src/bundle_cache.c + src/attribute.c src/BundleImpl.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 @@ -72,6 +72,9 @@ if (ENABLE_TESTING) add_subdirectory(tst) endif() +if (ENABLE_TESTING AND ENABLE_GTESTING) + add_subdirectory(gtest) +endif () celix_subproject(FRAMEWORK_TESTS "Option to build the framework tests" "OFF" DEPS) if (ENABLE_TESTING AND FRAMEWORK_TESTS) @@ -145,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/bundle.c + src/BundleImpl.c src/celix_errorcodes.c private/mock/celix_log_mock.c) target_link_libraries(bundle_test ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY} Celix::utils pthread) @@ -189,7 +192,7 @@ if (ENABLE_TESTING AND FRAMEWORK_TESTS) private/mock/dm_dependency_manager_mock.c src/celix_errorcodes.c private/mock/celix_log_mock.c - src/framework.c) + src/framework.c) target_link_libraries(framework_test ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY} ${UUID} Celix::utils pthread dl) add_executable(manifest_parser_test http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/gtest/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/framework/gtest/CMakeLists.txt b/framework/gtest/CMakeLists.txt new file mode 100644 index 0000000..a768f3f --- /dev/null +++ b/framework/gtest/CMakeLists.txt @@ -0,0 +1,37 @@ +# 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. + +set(SOURCES + src/main.cc + src/cxx_Framework_tests.cc + src/cxx_FrameworkFactory_tests.cc + src/cxx_BundleContext_tests.cc + src/cxx_Bundle_tests.cc +) +add_executable(cxx_framework_tests ${SOURCES}) +target_link_libraries(cxx_framework_tests PRIVATE gtest Celix::framework) + + +add_celix_bundle(cxx_fwm_test_bundle1 + VERSION 1.0.0 + NO_ACTIVATOR +) + +add_custom_command(TARGET cxx_framework_tests POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_PROPERTY:cxx_fwm_test_bundle1,BUNDLE_FILE> ${CMAKE_CURRENT_BINARY_DIR}/bundle1.zip +) +add_celix_bundle_dependencies(cxx_framework_tests cxx_fwm_test_bundle1) \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/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 new file mode 100644 index 0000000..d1a6a06 --- /dev/null +++ b/framework/gtest/src/cxx_BundleContext_tests.cc @@ -0,0 +1,233 @@ +/** + *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 "gtest/gtest.h" + +#include "celix/FrameworkFactory.h" + +class BundleContextTest : public ::testing::Test { +public: + BundleContextTest() { + celix::Properties config{}; + config["org.osgi.framework.storage.clean"] = "onFirstInit"; + config["org.osgi.framework.storage"] = "test-cache"; //TODO tmp dir? + this->fw_ptr = std::unique_ptr<celix::Framework>{celix::FrameworkFactory::newFramework(std::move(config))}; + } + + ~BundleContextTest(){} + + celix::Framework& framework() { return *(this->fw_ptr); } +private: + std::unique_ptr<celix::Framework> fw_ptr{nullptr}; +}; + +TEST_F(BundleContextTest, TestInstallBundle) { + auto &ctx = this->framework().getFrameworkContext(); + + long id; + + //invalid + id = ctx.installBundle("Invalid loc", false); + EXPECT_TRUE(id < 0); + + id = ctx.installBundle("bundle1.zip", false); + EXPECT_TRUE(id > 0); + + long again = ctx.installBundle("bundle1.zip", false); + EXPECT_EQ(id, again); +} + +TEST_F(BundleContextTest, RegisterCServiceTest) { + struct test_svc { + void *dummy; + }; + + auto &ctx = this->framework().getFrameworkContext(); + + test_svc svc1{}; + + long svcId = ctx.registerCService("test service", &svc1); + EXPECT_TRUE(svcId > 0); + ctx.unregisterService(svcId); + + long svcId2 = ctx.registerCService("test service", &svc1); + EXPECT_TRUE(svcId2 > 0); + EXPECT_NE(svcId, svcId2); //new registration new id + ctx.unregisterService(svcId2); +} + +TEST_F(BundleContextTest, UseService) { + struct test_svc { + int (*calc)(int input); + }; + + auto &ctx = this->framework().getFrameworkContext(); + + test_svc svc1{}; + svc1.calc = [](int input) -> int { + return input * 42; + }; + + long svcId = ctx.registerCService("test service", &svc1); + EXPECT_TRUE(svcId > 0); + + + int result = -1; + std::function<void(test_svc &svc, const celix::Properties&, const celix::Bundle&)> func = [&result](test_svc &svc, const celix::Properties&, const celix::Bundle&) { + result = svc.calc(1); + }; + ctx.useService<test_svc>(svcId, "test service", func); + EXPECT_EQ(result, 42); + + result = -1; + ctx.useService<test_svc>(svcId, "test service", [&result](test_svc &svc, const celix::Properties&, const celix::Bundle&) { + result = svc.calc(2); + }); + EXPECT_EQ(result, 84); + + ctx.unregisterService(svcId); +} + +TEST_F(BundleContextTest, UseServices) { + auto &ctx = this->framework().getFrameworkContext(); + + struct test_svc { + int (*calc)(int input); + }; + + test_svc svc{}; + svc.calc = [](int input) -> int { + return input * 42; + }; + + long svcId1 = ctx.registerCService("test service", &svc); + EXPECT_TRUE(svcId1 > 0); + + long svcId2 = ctx.registerCService("test service", &svc); + EXPECT_TRUE(svcId2 > 0); + + + int result = 0; + std::function<void(test_svc &svc, const celix::Properties&, const celix::Bundle&)> func = [&result](test_svc &svc, const celix::Properties&, const celix::Bundle&) { + result += svc.calc(1); + }; + ctx.useServices("test service", "", "", func); + EXPECT_EQ(result, 84); //two times + + ctx.unregisterService(svcId1); + + ctx.useServices("test service", "", "", func); + EXPECT_EQ(result, 126); //one time + + ctx.unregisterService(svcId2); +} + + +TEST_F(BundleContextTest, TrackService) { + auto &ctx = this->framework().getFrameworkContext(); + + int count = 0; + + struct test_svc { + int (*calc)(int input); + }; + + struct test_svc *svc1 = (struct test_svc*)0x100; //no ranking + struct test_svc *svc2 = (struct test_svc*)0x200; //no ranking + struct test_svc *svc3 = (struct test_svc*)0x300; //10 ranking + struct test_svc *svc4 = (struct test_svc*)0x400; //5 ranking + + + auto set = [&](struct test_svc *svc, const celix::Properties &, const celix::Bundle &) { + static int callCount = 0; + callCount += 1; + if (callCount == 1) { + //first time svc1 should be set (oldest service with equal ranking + EXPECT_EQ(svc1, svc); + } else if (callCount == 2) { + EXPECT_EQ(svc3, svc); + //second time svc3 should be set (highest ranking) + } else if (callCount == 3) { + //third time svc4 should be set (highest ranking + EXPECT_EQ(svc4, svc); + } + + count = callCount; + }; + + long svcId1 = ctx.registerService("NA", svc1); + long svcId2 = ctx.registerService("NA", svc2); + + //starting tracker should lead to first set call + long trackerId = ctx.trackService<struct test_svc>("NA", "", "", set); + EXPECT_TRUE(trackerId > 0); + + //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)); + + //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); + + //unregister svc3 should lead to set (new highest ranking) + ctx.unregisterService(svcId3); + + ctx.stopTracker(trackerId); + ctx.unregisterService(svcId1); + ctx.unregisterService(svcId4); + ctx.unregisterService(svcId2); + + EXPECT_EQ(3, count); //check if the set is called the expected times +} + +TEST_F(BundleContextTest, useBundleTest) { + auto &ctx = this->framework().getFrameworkContext(); + int count = 0; + + ctx.useBundle(0, [&count](const celix::Bundle &bnd) { + count++; + long id = bnd.getBundleId(); + EXPECT_EQ(0, id); + }); + + EXPECT_EQ(1, count); +}; + + +TEST_F(BundleContextTest, useBundlesTest) { + auto &ctx = this->framework().getFrameworkContext(); + int count = 0; + + auto use = [&count](const celix::Bundle &bnd) { + count++; + long id = bnd.getBundleId(); + EXPECT_TRUE(id >= 0); + }; + + ctx.useBundles(use); + EXPECT_EQ(1, count); + + count = 0; + ctx.installBundle("bundle1.zip", true); + ctx.useBundles(use); + EXPECT_EQ(2, count); +}; http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/gtest/src/cxx_Bundle_tests.cc ---------------------------------------------------------------------- diff --git a/framework/gtest/src/cxx_Bundle_tests.cc b/framework/gtest/src/cxx_Bundle_tests.cc new file mode 100644 index 0000000..e7eb0d8 --- /dev/null +++ b/framework/gtest/src/cxx_Bundle_tests.cc @@ -0,0 +1,66 @@ +/** + *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 "gtest/gtest.h" + +#include "celix/FrameworkFactory.h" + +class BundleTest : public ::testing::Test { +public: + BundleTest() { + celix::Properties config{}; + config["org.osgi.framework.storage.clean"] = "onFirstInit"; + config["org.osgi.framework.storage"] = "test-cache"; //TODO tmp dir? + this->fw_ptr = std::unique_ptr<celix::Framework>{celix::FrameworkFactory::newFramework(std::move(config))}; + } + + ~BundleTest(){} + + celix::Framework& framework() { return *(this->fw_ptr); } +private: + std::unique_ptr<celix::Framework> fw_ptr{nullptr}; +}; + +TEST_F(BundleTest, getInfoFromFrameworkBundle) { + auto &bnd = this->framework().getFrameworkBundle(); + + long id = bnd.getBundleId(); + EXPECT_EQ(0, id); //framework bundle is 0 + + //TODO FIXME returned name is id +// std::string name = bnd.getBundleName(); +// EXPECT_EQ("system", name); + + std::string sym = bnd.getBundleSymbolicName(); + EXPECT_EQ("framework", sym); + + std::string loc = bnd.getBundleLocation(); + EXPECT_EQ("System Bundle", loc); + + celix::BundleState state = bnd.getState(); + EXPECT_EQ(celix::BundleState::ACTIVE, state); + + //TODO +// std::string cache = bnd.getBundleCache(); //TODO make getCacheLoc? +// EXPECT_TRUE(!cache.emtpy()); + + //TODO returns "" should be framework version +// std::string version = bnd.getBundleVersion(); +// EXPECT_EQ("2.2.0", version); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/gtest/src/cxx_FrameworkFactory_tests.cc ---------------------------------------------------------------------- diff --git a/framework/gtest/src/cxx_FrameworkFactory_tests.cc b/framework/gtest/src/cxx_FrameworkFactory_tests.cc new file mode 100644 index 0000000..3920efb --- /dev/null +++ b/framework/gtest/src/cxx_FrameworkFactory_tests.cc @@ -0,0 +1,54 @@ +/** + *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 "gtest/gtest.h" + +#include "celix/FrameworkFactory.h" + +TEST(FrameworkFactoryTest, CreateDestroyTest) { + celix::Framework *fw1 = celix::FrameworkFactory::newFramework(); + EXPECT_NE(fw1, nullptr); + delete fw1; + + fw1 = celix::FrameworkFactory::newFramework(); + EXPECT_NE(fw1, nullptr); + fw1->start(); //NOTE should already be done + fw1->stop(); + fw1->waitForStop(); + delete fw1; +} + +TEST(FrameworkFactoryTest, StartStopTest) { + celix::Properties config1{}; + config1["org.osgi.framework.storage.clean"] = "onFirstInit"; + config1["org.osgi.framework.storage"] = "test-cache1"; + + celix::Properties config2 = config1; + config2["org.osgi.framework.storage"] = "test-cache2"; + + celix::Framework *fw1 = celix::FrameworkFactory::newFramework(config1); + celix::Framework *fw2 = celix::FrameworkFactory::newFramework(config2); + + EXPECT_NE(fw1, nullptr); + EXPECT_NE(fw2, nullptr); + EXPECT_NE(fw1, fw2); + + delete fw1; + delete fw2; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/gtest/src/cxx_Framework_tests.cc ---------------------------------------------------------------------- diff --git a/framework/gtest/src/cxx_Framework_tests.cc b/framework/gtest/src/cxx_Framework_tests.cc new file mode 100644 index 0000000..c8c88b4 --- /dev/null +++ b/framework/gtest/src/cxx_Framework_tests.cc @@ -0,0 +1,45 @@ +/** + *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 "gtest/gtest.h" + +#include "celix/Framework.h" +#include "celix/FrameworkFactory.h" + +class FrameworkTest : public ::testing::Test { +public: + FrameworkTest() { + celix::Properties config{}; + config["org.osgi.framework.storage.clean"] = "onFirstInit"; + config["org.osgi.framework.storage"] = "test-cache"; //TODO tmp dir? + this->fw_ptr = std::unique_ptr<celix::Framework>{celix::FrameworkFactory::newFramework(std::move(config))}; + } + + ~FrameworkTest(){} + + celix::Framework& framework() { return *(this->fw_ptr); } +private: + std::unique_ptr<celix::Framework> fw_ptr{nullptr}; +}; + +TEST_F(FrameworkTest, TestFrameworkUUID) { + auto &fw = this->framework(); + std::string uuid = fw.getUUID(); + EXPECT_NE(uuid, ""); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/gtest/src/main.cc ---------------------------------------------------------------------- diff --git a/framework/gtest/src/main.cc b/framework/gtest/src/main.cc new file mode 100644 index 0000000..63b9a5b --- /dev/null +++ b/framework/gtest/src/main.cc @@ -0,0 +1,25 @@ +/** + *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 "gtest/gtest.h" + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/bundle.h ---------------------------------------------------------------------- diff --git a/framework/include/bundle.h b/framework/include/bundle.h index 9cccd0c..d33a96d 100644 --- a/framework/include/bundle.h +++ b/framework/include/bundle.h @@ -16,138 +16,5 @@ *specific language governing permissions and limitations *under the License. */ -/* - * bundle.h - * - * \date Mar 23, 2010 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - -#ifndef BUNDLE_H_ -#define BUNDLE_H_ - -#include "celix_types.h" - -#include "celix_errno.h" -#include "bundle_state.h" -#include "bundle_archive.h" -#include "framework.h" -#include "wire.h" -#include "module.h" -#include "service_reference.h" -#include "bundle_context.h" -#include "celix_log.h" -#include "celix_threads.h" - -#ifdef __cplusplus -extern "C" { -#endif - -FRAMEWORK_EXPORT celix_status_t bundle_create(bundle_pt *bundle); - -FRAMEWORK_EXPORT celix_status_t -bundle_createFromArchive(bundle_pt *bundle, framework_pt framework, bundle_archive_pt archive); - -FRAMEWORK_EXPORT celix_status_t bundle_destroy(bundle_pt bundle); - -FRAMEWORK_EXPORT celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle); - -FRAMEWORK_EXPORT celix_status_t bundle_getArchive(bundle_pt bundle, bundle_archive_pt *archive); - -FRAMEWORK_EXPORT celix_status_t bundle_getCurrentModule(bundle_pt bundle, module_pt *module); - -FRAMEWORK_EXPORT array_list_pt bundle_getModules(bundle_pt bundle); - -FRAMEWORK_EXPORT void *bundle_getHandle(bundle_pt bundle); - -FRAMEWORK_EXPORT void bundle_setHandle(bundle_pt bundle, void *handle); - -FRAMEWORK_EXPORT activator_pt bundle_getActivator(bundle_pt bundle); - -FRAMEWORK_EXPORT celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator); - -FRAMEWORK_EXPORT celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context); - -FRAMEWORK_EXPORT celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context); - -FRAMEWORK_EXPORT celix_status_t bundle_getEntry(bundle_pt bundle, const char *name, char **entry); - -FRAMEWORK_EXPORT celix_status_t bundle_start(bundle_pt bundle); - -FRAMEWORK_EXPORT celix_status_t bundle_startWithOptions(bundle_pt bundle, int options); - -FRAMEWORK_EXPORT celix_status_t bundle_update(bundle_pt bundle, const char *inputFile); - -FRAMEWORK_EXPORT celix_status_t bundle_stop(bundle_pt bundle); - -FRAMEWORK_EXPORT celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options); - -FRAMEWORK_EXPORT celix_status_t bundle_uninstall(bundle_pt bundle); - -FRAMEWORK_EXPORT celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state); - -FRAMEWORK_EXPORT celix_status_t bundle_setPersistentStateInactive(bundle_pt bundle); - -FRAMEWORK_EXPORT celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle); - -FRAMEWORK_EXPORT void uninstallBundle(bundle_pt bundle); - -FRAMEWORK_EXPORT celix_status_t bundle_revise(bundle_pt bundle, const char *location, const char *inputFile); - -FRAMEWORK_EXPORT celix_status_t bundle_addModule(bundle_pt bundle, module_pt module); - -FRAMEWORK_EXPORT celix_status_t bundle_closeModules(bundle_pt bundle); - -// Service Reference Functions -FRAMEWORK_EXPORT array_list_pt getUsingBundles(service_reference_pt reference); - -FRAMEWORK_EXPORT int compareTo(service_reference_pt a, service_reference_pt b); - -FRAMEWORK_EXPORT celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state); - -FRAMEWORK_EXPORT celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable); - -FRAMEWORK_EXPORT celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread); - -FRAMEWORK_EXPORT celix_status_t bundle_lock(bundle_pt bundle, bool *locked); - -FRAMEWORK_EXPORT celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked); - -FRAMEWORK_EXPORT celix_status_t bundle_closeAndDelete(bundle_pt bundle); - -FRAMEWORK_EXPORT celix_status_t bundle_close(bundle_pt bundle); - -FRAMEWORK_EXPORT celix_status_t bundle_refresh(bundle_pt bundle); - -FRAMEWORK_EXPORT celix_status_t bundle_getBundleId(bundle_pt bundle, long *id); - -FRAMEWORK_EXPORT celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt *list); - -FRAMEWORK_EXPORT celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list); - -FRAMEWORK_EXPORT celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework); - -FRAMEWORK_EXPORT celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework); - -FRAMEWORK_EXPORT celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location); - - - -/********************************************************************************************************************** - ********************************************************************************************************************** - * Updated API - ********************************************************************************************************************** - **********************************************************************************************************************/ - -long celix_bundle_getId(const bundle_t *bnd); - -celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd); - - - -#ifdef __cplusplus -} -#endif -#endif /* BUNDLE_H_ */ +#include "celix_bundle.h" http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/bundle_context.h ---------------------------------------------------------------------- diff --git a/framework/include/bundle_context.h b/framework/include/bundle_context.h index 36547c4..2bc582e 100644 --- a/framework/include/bundle_context.h +++ b/framework/include/bundle_context.h @@ -238,7 +238,7 @@ void celix_bundleContext_unregisterService(celix_bundle_context_t *ctx, long ser * * @param ctx The bundle context. * @param serviceName The required service name to track - * @param serviceVersionRange Optional the service version range to track + * @param versionRange Optional the service version range to track * @param filter Optional the LDAP filter to use * @param callbackHandle The data pointer, which will be used in the callbacks * @param set is a required callback, which will be called when a new highest ranking service is set. @@ -247,7 +247,7 @@ void celix_bundleContext_unregisterService(celix_bundle_context_t *ctx, long ser long celix_bundleContext_trackService( celix_bundle_context_t* ctx, const char* serviceName, - const char* versioRange, + const char* versionRange, const char* filter, void* callbackHandle, void (*set)(void* handle, void* svc) @@ -258,7 +258,7 @@ long celix_bundleContext_trackService( * * @param ctx The bundle context. * @param serviceName The required service name to track - * @param serviceVersionRange Optional the service version range to track + * @param versionRange Optional the service version range to track * @param filter Optional the LDAP filter to use * @param callbackHandle The data pointer, which will be used in the callbacks * @param add is a required callback, which will be called when a service is added and initially for the existing service. @@ -268,7 +268,7 @@ long celix_bundleContext_trackService( long celix_bundleContext_trackServices( celix_bundle_context_t* ctx, const char* serviceName, - const char* versioRange, + const char* versionRange, const char* filter, void* callbackHandle, void (*add)(void* handle, void* svc), @@ -312,6 +312,14 @@ typedef struct celix_service_tracker_options { long celix_bundleContext_trackServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_tracker_options_t *opts); +//TODO find services -> list of service ids. +celix_array_list_t* celix_bundleContext_findServices( + celix_bundle_context_t *ctx, + const char *serviceName, + const char *versionRange, + const char *filter, + const char *lang +); /** * Get and lock the service with the provided service id @@ -439,8 +447,6 @@ typedef struct celix_bundle_tracker_options { */ void (*onStopped)(void *handle, const celix_bundle_t *bundle); - //TODO callback for on installed, resolved, uninstalled ?? - /** * * @param handle The handle, contains the value of the callbackHandle. @@ -491,16 +497,13 @@ long celix_bundleContext_trackBundles( * @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, void (*use)(void *handle, const celix_bundle_t *bundle) ); -//TODO add useBundleWithState (bit wise or?) - - //TODO except framework & own bundle /** * Use the currently active (started) bundles. http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/celix/Bundle.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/Bundle.h b/framework/include/celix/Bundle.h new file mode 100644 index 0000000..de65e4d --- /dev/null +++ b/framework/include/celix/Bundle.h @@ -0,0 +1,77 @@ +/** + *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. + */ + +#ifndef CXX_CELIX_BUNDLE_H +#define CXX_CELIX_BUNDLE_H + +#include "celix/Properties.h" + +namespace celix { + class Framework; //forward declaration + + enum class BundleState { + UNKNOWN, + UNINSTALLED, + INSTALLED, + RESOLVED, + STARTING, + STOPPING, + ACTIVE + }; + + class Bundle { + public: + virtual ~Bundle() = default; + + virtual bool isSystemBundle() const noexcept = 0; + + virtual void * getHandle() const noexcept = 0; + + virtual BundleState getState() const noexcept = 0; + + virtual long getBundleId() const noexcept = 0; + + virtual std::string getBundleLocation() const noexcept = 0; + + virtual std::string getBundleCache() const noexcept = 0; + + virtual std::string getBundleName() const noexcept = 0; + + virtual std::string getBundleSymbolicName() const noexcept = 0; + + virtual std::string getBundleVersion() const noexcept = 0; + + virtual celix::Properties getManifestAsProperties() const noexcept = 0; + + //TODO make ref? + virtual celix::Framework* getFramework() const noexcept = 0; + + virtual void start() noexcept = 0; + + virtual void stop() noexcept = 0; + + virtual void uninstall() noexcept = 0; + + }; + +} + +#include "celix/impl/BundleImpl.h" + +#endif //CXX_CELIX_BUNDLE_H http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/celix/BundleContext.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/BundleContext.h b/framework/include/celix/BundleContext.h new file mode 100644 index 0000000..4169b0a --- /dev/null +++ b/framework/include/celix/BundleContext.h @@ -0,0 +1,241 @@ +/** + *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. + */ + +#ifndef CXX_CELIX_BUNDLECONTEXT_H +#define CXX_CELIX_BUNDLECONTEXT_H + +#include <string> +#include <vector> +#include <functional> + +#include "celix/Constants.h" +#include "celix/Properties.h" +#include "celix/Bundle.h" + +namespace celix { + + class BundleContext; //forward declaration + + struct BundleRegistrationOptions { + std::string id{}; + std::string name{}; + std::string version{}; + + bool autoStart{true}; + + std::function<void(celix::BundleContext &ctx)> start{}; + std::function<void(celix::BundleContext &ctx)> stop{}; + + celix::Properties manifest{}; + + //If manifest symbol and manifest len symbol is set, this is used instead of the properties as manifest + std::string manifestSymbol{}; + std::string manifestLenSymbol{}; + + std::string resourceSymbol{}; + std::string resourceLenSymbol{}; + }; + + class BundleContext { + public: + 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)); + } + + template<typename I> + long registerCService(const std::string &serviceName, I *svc, const std::string &version = "", Properties props = {}) noexcept { + return this->registerServiceInternal(serviceName, svc, version, celix::Constants::SERVICE_C_LANG, std::move(props)); + } + + 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)); + } + + //TODO register std::function ? + + virtual void unregisterService(long serviceId) noexcept = 0; + + //register service factory + + /** + * track service for the provided service type, service name, optional version range and optional filter. + * The highest ranking services will used for the callback. + * If a new and higher ranking services the callback with be called again with the new service. + * If a service is removed a the callback with be called with next highest ranking service or NULL as service. + * + * @param ctx The bundle context. + * @param serviceName The required service name to track + * @param serviceVersionRange Optional the service version range to track. Can be empty ("") + * @param filter Optional the LDAP filter to use. Can be empty ("") + * @param set is a required callback, which will be called when a new highest ranking service is set. + * @return the tracker id or < 0 if unsuccessful. + */ + template<typename I> + long trackService( + const std::string &serviceName, + const std::string &versionRange, + const std::string &filter, + std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> set + ) noexcept { + return this->trackServiceInternal(serviceName, versionRange, filter, [set](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) { + I* typedSvc = static_cast<I*>(voidSvc); + set(typedSvc, props, bnd); + }); + } + + /** + * track services for the provided serviceName and/or filter. + * + * @param ctx The bundle context. + * @param serviceName The required service name to track + * @param serviceVersionRange Optional the service version range to track + * @param filter Optional the LDAP filter to use + * @param callbackHandle The data pointer, which will be used in the callbacks + * @param add is a required callback, which will be called when a service is added and initially for the existing service. + * @param remove is a required callback, which will be called when a service is removed + * @return the tracker id or < 0 if unsuccessful. + */ + template<typename I> + long trackServices( + const std::string &serviceName, + const std::string &versionRange, + const std::string &filter, + 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, versionRange, filter, + [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); + } + ); + } + + //TODO make add / remove service refs?? + //TODO missing lang for track services + + /** + * Note use fucntion by const reference. Only used during the call. + * @param serviceId + * @param I + * @return + */ + template<typename I> + bool useService(long serviceId, const std::string &serviceName /*sanity*/, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept { + std::string filter = std::string{"(service.id="} + std::to_string(serviceId) + std::string{")"}; + return this->useService<I>(serviceName, "", filter, use); + } + + template<typename I> + bool useService(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept { + return this->useServiceInternal(serviceName, versionRange, filter, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) { + I *typedSvc = static_cast<I*>(voidSvc); + use(*typedSvc, props, svcOwner); + }); + } + + template<typename I> + void useServices(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept { + this->useServicesInternal(serviceName, filter, versionRange, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) { + I *typedSvc = static_cast<I*>(voidSvc); + use(*typedSvc, props, svcOwner); + }); + } + + /** + * Note ordered by service rank. + */ + virtual std::vector<long> findServices(const std::string &serviceName, const std::string &versionRange = "", const std::string &filter = "", const std::string &lang = "") noexcept = 0; + + //TODO also support getting int, long, unsigned int, etc?? + virtual std::string getProperty(const std::string &key, std::string defaultValue = "") noexcept = 0; + + //TODO options + + //track bundle + //TODO + + //track service tracker + //TODO + + /** + * Stop the tracker with the provided track id. + * Could be a service tracker, bundle tracker or service tracker tracker. + * Only works for the trackers owned by the bundle of the bundle context. + * + * Will log a error if the provided tracker id is unknown. Will silently ignore trackerId < 0. + */ + virtual void stopTracker(long trackerId) noexcept = 0; + + //TODO + //virtual Bundle& getBundle() const noexcept = 0; + + + //TODO + //class celix::DependencyManager; //forward declaration TODO create + //virtual celix::DependencyManager& getDependencyManager() const noexcept = 0; + + virtual long registerEmbeddedBundle( + std::string id, + std::function<void(celix::BundleContext& ctx)> start, + std::function<void(celix::BundleContext& ctx)> stop, + celix::Properties manifest = {}, + bool autoStart = true + ) noexcept = 0; + + virtual void registerEmbeddedBundle(const celix::BundleRegistrationOptions &opts) noexcept = 0; + + virtual long installBundle(const std::string &bundleLocation, bool autoStart = true) noexcept = 0; + + virtual void useBundles(const std::function<void(const celix::Bundle &bnd)> &use) noexcept = 0; + + 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, + const std::string &versionRange, + const std::string &filter, + std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> set) noexcept = 0; + + virtual long trackServicesInternal( + const std::string &serviceName, + const std::string &versionRange, + const std::string &filter, + 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 bool useServiceInternal(const std::string &serviceName, const std::string &versionRange, const std::string &filter, 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::string &versionRange, const std::string &filter, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0; + }; + +} + +#include "celix/impl/BundleContextImpl.h" + +#endif //CXX_CELIX_BUNDLECONTEXT_H http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/celix/Celix.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/Celix.h b/framework/include/celix/Celix.h new file mode 100644 index 0000000..c27969f --- /dev/null +++ b/framework/include/celix/Celix.h @@ -0,0 +1,36 @@ +/** + *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. + */ + +#ifndef CXX_CELIX_CELIX_H +#define CXX_CELIX_CELIX_H + +/** + * Celix C++ API header + */ + + +#include "celix/Constants.h" +#include "celix/Properties.h" +#include "celix/Bundle.h" +#include "celix/IServiceFactory.h" +#include "celix/BundleContext.h" +#include "celix/Framework.h" +#include "celix/FrameworkFactory.h" + +#endif //CXX_CELIX_CELIX_H http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/celix/Constants.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/Constants.h b/framework/include/celix/Constants.h new file mode 100644 index 0000000..8317069 --- /dev/null +++ b/framework/include/celix/Constants.h @@ -0,0 +1,47 @@ +/** + *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. + */ + + +#ifndef CXX_CELIX_CONSTANTS_H +#define CXX_CELIX_CONSTANTS_H + +#include "celix_constants.h" + +namespace celix { + class Constants { + public: + static constexpr const char *const SERVICE_NAME = OSGI_FRAMEWORK_OBJECTCLASS; + static constexpr const char *const SERVICE_ID = OSGI_FRAMEWORK_SERVICE_ID; + static constexpr const char *const SERVICE_PID = OSGI_FRAMEWORK_SERVICE_PID; + static constexpr const char *const SERVICE_RANKING = OSGI_FRAMEWORK_SERVICE_RANKING; + + static constexpr const char *const SERVICE_VERSION = CELIX_FRAMEWORK_SERVICE_VERSION; + static constexpr const char *const SERVICE_LANGUAGE = CELIX_FRAMEWORK_SERVICE_LANGUAGE; + static constexpr const char *const SERVICE_C_LANG = CELIX_FRAMEWORK_SERVICE_C_LANGUAGE; + static constexpr const char *const SERVICE_CXX_LANG = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE; + static constexpr const char *const SERVICE_SHARED_LANG = CELIX_FRAMEWORK_SERVICE_SHARED_LANGUAGE; //e.g. marker services + + static constexpr const char *const FRAMEWORK_STORAGE = OSGI_FRAMEWORK_FRAMEWORK_STORAGE; + static constexpr const char *const FRAMEWORK_CLEAN = OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN; + static constexpr const char *const FRAMEWORK_CLEAN_ON_FIRST_INIT = OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT; + static constexpr const char *const FRAMEWORK_UUID = OSGI_FRAMEWORK_FRAMEWORK_UUID; + }; +} + +#endif //CXX_CELIX_CONSTANTS_H http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/celix/Framework.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/Framework.h b/framework/include/celix/Framework.h new file mode 100644 index 0000000..ee7074b --- /dev/null +++ b/framework/include/celix/Framework.h @@ -0,0 +1,51 @@ +/** + *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. + */ + +#ifndef CXX_CELIX_FRAMEWORK_H +#define CXX_CELIX_FRAMEWORK_H + +#include <functional> + +#include "celix/Constants.h" +#include "celix/Properties.h" +#include "Bundle.h" +#include "celix/BundleContext.h" + +namespace celix { + /*TODO make framework a bundle ?? + * personally I was never a fan of the context that the framework is also a bundle + */ + class Framework { + public: + virtual ~Framework() = default; + + virtual void start() noexcept = 0; + virtual void stop() noexcept = 0; + + virtual void waitForStop() noexcept = 0; + //TODO also in c virtual void breakWaitForStops() noexcept = 0; + + virtual std::string getUUID() const noexcept = 0; + + virtual celix::BundleContext& getFrameworkContext() noexcept = 0; + virtual celix::Bundle& getFrameworkBundle() noexcept = 0; + }; +} + +#endif //CXX_CELIX_FRAMEWORK_H http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/celix/FrameworkFactory.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/FrameworkFactory.h b/framework/include/celix/FrameworkFactory.h new file mode 100644 index 0000000..b7bc9b7 --- /dev/null +++ b/framework/include/celix/FrameworkFactory.h @@ -0,0 +1,66 @@ +/** + *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. + */ + +#ifndef CXX_CELIX_FRAMEWORKFACTORY_H +#define CXX_CELIX_FRAMEWORKFACTORY_H + +#include "celix/Properties.h" +#include "celix/Framework.h" + +//include implementations +#include "celix/impl/BundleImpl.h" +#include "celix/impl/BundleContextImpl.h" +#include "celix/impl/FrameworkImpl.h" + +namespace celix { + class FrameworkFactory { + public: + static celix::Framework *newFramework(celix::Properties config = {}) noexcept; + + static void registerEmbeddedBundle( + std::string id, + std::function<void(celix::BundleContext &ctx)> start, + std::function<void(celix::BundleContext &ctx)> stop, + celix::Properties manifest = {}, + bool autoStart = true + ) noexcept; + + static void registerEmbeddedBundle(const celix::BundleRegistrationOptions &opts) noexcept; + }; +} + +inline celix::Framework* celix::FrameworkFactory::newFramework(celix::Properties config) noexcept { + return new celix::impl::FrameworkImpl(std::move(config)); +} + +inline void celix::FrameworkFactory::registerEmbeddedBundle( + std::string /*id*/, + std::function<void(celix::BundleContext& ctx)> /*start*/, + std::function<void(celix::BundleContext& ctx)> /*stop*/, + celix::Properties /*manifest*/, + bool /*autoStart*/ +) noexcept { + //TODO +} + +inline void celix::FrameworkFactory::registerEmbeddedBundle(const celix::BundleRegistrationOptions &/*opts*/) noexcept { + //TODO +}; + +#endif //CXX_CELIX_FRAMEWORKFACTORY_H \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/celix/IServiceFactory.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/IServiceFactory.h b/framework/include/celix/IServiceFactory.h new file mode 100644 index 0000000..1adc8b5 --- /dev/null +++ b/framework/include/celix/IServiceFactory.h @@ -0,0 +1,35 @@ +/** + *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. + */ + +#ifndef CXX_CELIX_ISERVICEFACTORY_H +#define CXX_CELIX_ISERVICEFACTORY_H + +#include "celix/Bundle.h" + +namespace celix { + + typename<I> + class IServiceFactory { + virtual I* getService(IBundle &bundle) = 0; + virtual void ungetService(IBundle* bundle, I* svc) = 0; + }; + +} + +#endif //CXX_CELIX_ISERVICEFACTORY_H http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/celix/Properties.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/Properties.h b/framework/include/celix/Properties.h new file mode 100644 index 0000000..65fd4ef --- /dev/null +++ b/framework/include/celix/Properties.h @@ -0,0 +1,60 @@ +/** + *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. + */ + +#ifndef CXX_CELIX_PROPERTIES_H +#define CXX_CELIX_PROPERTIES_H + +#include <string> +#include <map> + +namespace celix { + + using Properties = std::map<std::string, std::string>; + + inline const std::string& getProperty(const Properties& props, const std::string &key, const std::string &defaultValue) noexcept { + auto it = props.find(key); + if (it != props.end()) { + return props.at(key); + } else { + return defaultValue; + } + } + + inline int getProperty(const Properties& props, const std::string &key, int defaultValue) noexcept { + std::string val = getProperty(props, key, std::to_string(defaultValue)); + return std::stoi(val, nullptr, 10); + } + + inline unsigned int getProperty(const Properties& props, const std::string &key, unsigned int defaultValue) noexcept { + std::string val = getProperty(props, key, std::to_string(defaultValue)); + return static_cast<unsigned int>(std::stoul(val, nullptr, 10)); //NOTE no std::stou ?? + } + + inline long getProperty(const Properties& props, const std::string &key, long defaultValue) noexcept { + std::string val = getProperty(props, key, std::to_string(defaultValue)); + return std::stol(val, nullptr, 10); + } + + inline unsigned int getProperty(const Properties& props, const std::string &key, unsigned long defaultValue) noexcept { + std::string val = getProperty(props, key, std::to_string(defaultValue)); + return std::stoul(val, nullptr, 10); + } +} + +#endif //CXX_CELIX_PROPERTIES_H http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/celix/dm/Properties.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/dm/Properties.h b/framework/include/celix/dm/Properties.h index bb4fd78..77d2872 100644 --- a/framework/include/celix/dm/Properties.h +++ b/framework/include/celix/dm/Properties.h @@ -20,11 +20,10 @@ #ifndef CELIX_DM_PROPERTIES_H #define CELIX_DM_PROPERTIES_H -#include <map> -#include <string> +#include "celix/Properties.h" namespace celix { namespace dm { - using Properties = std::map<std::string, std::string>; + using Properties = celix::Properties; }} #endif //CELIX_DM_PROPERTIES_H http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/celix/impl/BundleContextImpl.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/impl/BundleContextImpl.h b/framework/include/celix/impl/BundleContextImpl.h new file mode 100644 index 0000000..8da3984 --- /dev/null +++ b/framework/include/celix/impl/BundleContextImpl.h @@ -0,0 +1,293 @@ +/** + *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. + */ + +#ifndef CELIX_IMPL_BUNDLECONTEXT_H +#define CELIX_IMPL_BUNDLECONTEXT_H + +#include "bundle_context.h" +#include "service_tracker.h" + +#include "celix/impl/BundleImpl.h" + +namespace celix { + + namespace impl { + + static celix::Properties createFromCProps(const celix_properties_t *c_props) { + celix::Properties result{}; + const char *key = nullptr; + CELIX_PROPERTIES_FOR_EACH(const_cast<celix_properties_t*>(c_props), key) { + result[key] = celix_properties_get(c_props, key); + } + return result; + } + + class BundleContextImpl : public celix::BundleContext { + public: + BundleContextImpl(bundle_context_t *ctx) : c_ctx{ctx} {} + + virtual ~BundleContextImpl() { + //NOTE no need to destroy the c bundle context -> done by c framework + + //clearing tracker entries + { + std::lock_guard<std::mutex> lock{this->mutex}; + for (auto &pair : this->trackEntries) { + celix_bundleContext_stopTracker(this->c_ctx, pair.first); + } + this->trackEntries.clear(); + } + + this->c_ctx = nullptr; + } + + void unregisterService(long serviceId) noexcept override { + celix_bundleContext_unregisterService(this->c_ctx, serviceId); + } + + std::vector<long> findServices(const std::string &serviceName, const std::string &versionRange, const std::string &filter, const std::string &/*lang = ""*/) noexcept override { + std::vector<long> result{}; + auto use = [&result](void *, const celix::Properties &props, const celix::Bundle &) { + long id = celix::getProperty(props, OSGI_FRAMEWORK_SERVICE_ID, -1); + if (id >= 0) { + result.push_back(id); + } + }; + this->useServicesInternal(serviceName, versionRange, filter, use); + return result; + } + + void stopTracker(long trackerId) noexcept override { + std::lock_guard<std::mutex> lock{this->mutex}; + celix_bundleContext_stopTracker(this->c_ctx, trackerId); + auto it = this->trackEntries.find(trackerId); + if (it != this->trackEntries.end()) { + this->trackEntries.erase(it); + } + } + + std::string getProperty(const std::string &key, std::string defaultValue) noexcept override { + const char *val = nullptr; + bundleContext_getPropertyWithDefault(this->c_ctx, key.c_str(), defaultValue.c_str(), &val); + return std::string{val}; + } + + bool isInvalid() const noexcept { + return this->c_ctx == nullptr; + } + + long registerEmbeddedBundle( + std::string /*id*/, + std::function<void(celix::BundleContext & ctx)> /*start*/, + std::function<void(celix::BundleContext & ctx)> /*stop*/, + celix::Properties /*manifest*/, + bool /*autoStart*/ + ) noexcept override { + return -1; //TODO + }; + + void registerEmbeddedBundle(const celix::BundleRegistrationOptions &/*opts*/) noexcept override { + //TODO + } + + long installBundle(const std::string &bundleLocation, bool autoStart) noexcept override { + long bndId = -1; + if (this->c_ctx != nullptr) { + bundle_t *bnd = nullptr; + bundleContext_installBundle(this->c_ctx, bundleLocation.c_str(), &bnd); + if (bnd != nullptr) { + bundle_getBundleId(bnd, &bndId); + if (autoStart) { + bundle_start(bnd); + } + } + } + return bndId; + } + + + void useBundles(const std::function<void(const celix::Bundle &bnd)> &use) noexcept override { + auto c_use = [](void *handle, const celix_bundle_t *c_bnd) { + auto *func = static_cast<std::function<void(const celix::Bundle &bnd)>*>(handle); + auto m_bnd = const_cast<celix_bundle_t*>(c_bnd); + celix::impl::BundleImpl bnd{m_bnd}; + (*func)(bnd); + }; + celix_bundleContext_useBundles(this->c_ctx, (void*)(&use), c_use); + } + + bool useBundle(long bundleId, const std::function<void(const celix::Bundle &bnd)> &use) noexcept override { + auto c_use = [](void *handle, const celix_bundle_t *c_bnd) { + auto *func = static_cast<std::function<void(const celix::Bundle &bnd)>*>(handle); + auto m_bnd = const_cast<celix_bundle_t*>(c_bnd); + celix::impl::BundleImpl bnd{m_bnd}; + (*func)(bnd); + }; + return celix_bundleContext_useBundle(this->c_ctx, bundleId, (void*)(&use), c_use); + } + + 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 trackServiceInternal(const std::string &serviceName, + const std::string &versionRange, + const std::string &filter, + std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> set) noexcept override { + celix_service_tracker_options_t opts; + std::memset(&opts, 0, sizeof(opts)); + + auto c_set = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) { + auto *entry = static_cast<TrackEntry*>(handle); + celix::Properties props = createFromCProps(c_props); + auto m_bnd = const_cast<celix_bundle_t *>(c_bnd); + auto bnd = celix::impl::BundleImpl(m_bnd); + (entry->set)(svc, props, bnd); + }; + const char *cname = serviceName.empty() ? nullptr : serviceName.c_str(); + const char *crange = versionRange.empty() ? nullptr : versionRange.c_str(); + const char *cfilter = filter.empty() ? nullptr : filter.c_str(); + + opts.serviceName = cname; + opts.versionRange = crange; + opts.filter = cfilter; + opts.lang = 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; + + long id = celix_bundleContext_trackServicesWithOptions(this->c_ctx, &opts); + if (id >= 0) { + std::lock_guard<std::mutex> lock{this->mutex}; + this->trackEntries[id] = std::move(te); + } + return id; + } + + long trackServicesInternal( + const std::string &serviceName, + const std::string &versionRange, + const std::string &filter, + 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 override { + celix_service_tracker_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 *entry = static_cast<TrackEntry*>(handle); + celix::Properties props = createFromCProps(c_props); + auto m_bnd = const_cast<celix_bundle_t *>(c_bnd); + auto bnd = celix::impl::BundleImpl(m_bnd); + (entry->add)(svc, props, bnd); + }; + auto c_remove = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) { + auto *entry = static_cast<TrackEntry*>(handle); + celix::Properties props = createFromCProps(c_props); + auto m_bnd = const_cast<celix_bundle_t *>(c_bnd); + auto bnd = celix::impl::BundleImpl(m_bnd); + (entry->remove)(svc, props, bnd); + }; + + const char *cname = serviceName.empty() ? nullptr : serviceName.c_str(); + const char *crange = versionRange.empty() ? nullptr : versionRange.c_str(); + const char *cfilter = filter.empty() ? nullptr : filter.c_str(); + + opts.serviceName = cname; + opts.versionRange = crange; + opts.filter = cfilter; + opts.lang = 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; + + long id = celix_bundleContext_trackServicesWithOptions(this->c_ctx, &opts); + if (id >= 0) { + std::lock_guard<std::mutex> lock{this->mutex}; + this->trackEntries[id] = std::move(te); + } + return id; + } + + bool useServiceInternal( + const std::string &serviceName, + const std::string &versionRange, + const std::string &filter, + const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept override { + auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) { + auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle); + celix::Properties props = createFromCProps(c_props); + celix_bundle_t *c_bnd = const_cast<celix_bundle_t*>(c_svcOwner); + auto bnd = celix::impl::BundleImpl{c_bnd}; + (*fn)(svc, props, bnd); + }; + const char *cname = serviceName.empty() ? nullptr : serviceName.c_str(); + const char *crange = versionRange.empty() ? nullptr : versionRange.c_str(); + const char *cfilter = filter.empty() ? nullptr : filter.c_str(); + return celix_bundleContext_useService(this->c_ctx, cname, crange, cfilter, (void*)(&use), c_use); + } + + void useServicesInternal( + const std::string &serviceName, + const std::string &versionRange, + const std::string &filter, + const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept override { + auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) { + auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle); + celix::Properties props = createFromCProps(c_props); + celix_bundle_t *c_bnd = const_cast<celix_bundle_t*>(c_svcOwner); + auto bnd = celix::impl::BundleImpl{c_bnd}; + (*fn)(svc, props, bnd); + }; + const char *cname = serviceName.empty() ? nullptr : serviceName.c_str(); + const char *crange = versionRange.empty() ? nullptr : versionRange.c_str(); + const char *cfilter = filter.empty() ? nullptr : filter.c_str(); + celix_bundleContext_useServices(this->c_ctx, cname, crange, cfilter, (void*)(&use), c_use); + } + + private: + bundle_context_t *c_ctx; + + 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::mutex mutex{}; + std::map<long,std::unique_ptr<TrackEntry>> trackEntries{}; + }; + } +} + +#endif //CELIX_IMPL_BUNDLECONTEXT_H http://git-wip-us.apache.org/repos/asf/celix/blob/764bd7f7/framework/include/celix/impl/BundleImpl.h ---------------------------------------------------------------------- diff --git a/framework/include/celix/impl/BundleImpl.h b/framework/include/celix/impl/BundleImpl.h new file mode 100644 index 0000000..583ae25 --- /dev/null +++ b/framework/include/celix/impl/BundleImpl.h @@ -0,0 +1,171 @@ +/** + *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. + */ + +#ifndef CELIX_IMPL_BUNDLEIMPL_H +#define CELIX_IMPL_BUNDLEIMPL_H + +#include "celix_bundle.h" + +namespace celix { + + //forward declaration + + namespace impl { + class BundleImpl : public celix::Bundle { + public: + BundleImpl(celix_bundle_t *b) : c_bnd{b} { + framework_t *c_fw{nullptr}; + bundle_getFramework(this->c_bnd, &c_fw); + //this->fw = std::unique_ptr<celix::impl::Framework>{new celix::impl::Framework(c_fw, false)}; + } + + virtual ~BundleImpl() { + //no need to destroy the c bundle context -> done by c framework + this->c_bnd = nullptr; + } + + bool isSystemBundle() const noexcept override { + bool r; + bundle_isSystemBundle(this->c_bnd, &r); + return r; + } + + void * getHandle() const noexcept override { + return bundle_getHandle(this->c_bnd); + } + + BundleState getState() const noexcept override { + bundle_state_e c_state; + bundle_getState(this->c_bnd, &c_state); + return this->fromCState(c_state); + } + + long getBundleId() const noexcept override { + long id{-1}; + bundle_getBundleId(this->c_bnd, &id); + return id; + } + + std::string getBundleLocation() const noexcept override { + std::string location{}; + const char *loc = nullptr; + bundle_getBundleLocation(this->c_bnd, &loc); + if (loc != nullptr) { + location = std::string{loc}; + } + return location; + } + + std::string getBundleCache() const noexcept override { + std::string cache{}; + const char *c = celix_bundle_getEntry(this->c_bnd, "."); + if (c != nullptr) { + cache = std::string{c}; + } + return cache; + } + + std::string getBundleName() const noexcept override { + std::string name{}; + module_pt mod = nullptr; + bundle_getCurrentModule(this->c_bnd, &mod); + if (mod != nullptr) { + name = module_getId(mod); + } + return name; + } + + std::string getBundleSymbolicName() const noexcept override { + std::string name{}; + module_pt mod = nullptr; + bundle_getCurrentModule(this->c_bnd, &mod); + if (mod != nullptr) { + const char *n = nullptr; + module_getSymbolicName(mod, &n); + if (n != nullptr) { + name = n; + } + } + return name; + } + + std::string getBundleVersion() const noexcept override { + return std::string{}; //TODO +// std::string version{}; +// module_pt mod = nullptr; +// bundle_getCurrentModule(this->c_bnd, &mod); +// if (mod != nullptr) { +// auto version = module_getVersion(mod); +// //TODO +// } +// return version; + } + + celix::Properties getManifestAsProperties() const noexcept override { + return celix::Properties{}; //TODO + } + + celix::Framework* getFramework() const noexcept override { +// return this->fw; + return nullptr; //TODO + } + + void start() noexcept override { + bundle_start(this->c_bnd); + } + + void stop() noexcept override { + bundle_stop(this->c_bnd); + } + + void uninstall() noexcept override { + bundle_uninstall(this->c_bnd); + } + + private: + BundleState fromCState(bundle_state_e c_state) const { + switch(c_state) { + case OSGI_FRAMEWORK_BUNDLE_UNKNOWN: + return BundleState::UNKNOWN; + case OSGI_FRAMEWORK_BUNDLE_UNINSTALLED: + return BundleState::INSTALLED; + case OSGI_FRAMEWORK_BUNDLE_INSTALLED: + return BundleState::INSTALLED; + case OSGI_FRAMEWORK_BUNDLE_RESOLVED: + return BundleState::RESOLVED; + case OSGI_FRAMEWORK_BUNDLE_STOPPING: + return BundleState::STOPPING; + case OSGI_FRAMEWORK_BUNDLE_ACTIVE: + return BundleState::ACTIVE; + case OSGI_FRAMEWORK_BUNDLE_STARTING: + return BundleState::STARTING; + default: + ;//passs + } + return BundleState::UNKNOWN; + }; + + celix_bundle_t *c_bnd; +// framework_t *c_fw{nullptr}; +// std::unique_ptr<celix::impl::Framework> fw{nullptr}; + }; + } +} + +#endif //CELIX_IMPL_BUNDLEIMPL_H
