You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2018/05/06 18:45:21 UTC
[2/2] celix git commit: CELIX-426: Initial commit for the C++ api
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 <pe...@gmail.com>
Authored: Sun Apr 15 21:25:20 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
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:dev@celix.apache.org">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