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 2019/01/07 20:12:00 UTC
[celix] 12/22: CELIX-438: Adds a assert and warning log for wrong
useage of the use(Funcion)Service(s) calls and adds some unit tests for the
C++ shell.
This is an automated email from the ASF dual-hosted git repository.
pnoltes pushed a commit to branch feature/cxx
in repository https://gitbox.apache.org/repos/asf/celix.git
commit cc671b6deb823fa06c79b1f88ac6a732eebab261
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Sun Jan 6 20:29:25 2019 +0100
CELIX-438: Adds a assert and warning log for wrong useage of the use(Funcion)Service(s) calls and adds some unit tests for the C++ shell.
---
CMakeLists.txt | 2 +-
bundles/shell/cxx_shell/CMakeLists.txt | 6 +-
bundles/shell/cxx_shell/gtest/CMakeLists.txt | 7 +-
bundles/shell/cxx_shell/gtest/src/Shell_tests.cc | 163 ++++++++++++++++++
bundles/shell/cxx_shell/src/QueryCommand.cc | 2 +-
libs/CMakeLists.txt | 6 +-
libs/framework_cxx/gtest/src/Framework_tests.cc | 2 +-
libs/framework_cxx/include/celix/BundleContext.h | 29 +++-
libs/framework_cxx/include/celix/Framework.h | 2 +
libs/framework_cxx/src/Bundle.h | 6 +-
libs/framework_cxx/src/BundleContext.cc | 7 +-
libs/framework_cxx/src/BundleController.h | 2 +-
libs/framework_cxx/src/Framework.cc | 209 ++++++++++++-----------
libs/registry/CMakeLists.txt | 5 +-
libs/registry/gtest/CMakeLists.txt | 3 +-
libs/registry/gtest/src/Registry_tests.cc | 2 +-
libs/registry/gtest/src/Utils_tests.cc | 56 ++++++
libs/registry/include/celix/Constants.h | 6 +-
libs/registry/include/celix/ServiceRegistry.h | 47 +++--
libs/registry/include/celix/Utils.h | 46 +++--
libs/registry/src/ServiceRegistry.cc | 44 +++--
libs/registry/src/Utils.cc | 51 ++++++
22 files changed, 518 insertions(+), 185 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 968e74c..f1807f7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -56,7 +56,7 @@ option(ENABLE_TESTING "Enables unit testing" ON)
if (ENABLE_TESTING)
enable_testing()
include(cmake/celix_project/AddGTest.cmake)
- include(cmake/celix_project/AddCppUTest.cmake)
+ #include(cmake/celix_project/AddCppUTest.cmake)
endif ()
include(cmake/celix_project/AddGLog.cmake)
include(cmake/celix_project/AddLibzip.cmake)
diff --git a/bundles/shell/cxx_shell/CMakeLists.txt b/bundles/shell/cxx_shell/CMakeLists.txt
index c82d2ef..3dced30 100644
--- a/bundles/shell/cxx_shell/CMakeLists.txt
+++ b/bundles/shell/cxx_shell/CMakeLists.txt
@@ -56,6 +56,6 @@ else ()
endif ()
-#if (ENABLE_TESTING)
-# add_subdirectory(gtest)
-#endif ()
\ No newline at end of file
+if (ENABLE_TESTING)
+ add_subdirectory(gtest)
+endif ()
\ No newline at end of file
diff --git a/bundles/shell/cxx_shell/gtest/CMakeLists.txt b/bundles/shell/cxx_shell/gtest/CMakeLists.txt
index b4a7204..c95f364 100644
--- a/bundles/shell/cxx_shell/gtest/CMakeLists.txt
+++ b/bundles/shell/cxx_shell/gtest/CMakeLists.txt
@@ -17,9 +17,10 @@
set(SOURCES
src/main.cc
+ src/Shell_tests.cc
)
add_executable(celix_shell_cxx_tests ${SOURCES})
-target_link_libraries(celix_shell_cxx_tests PRIVATE gtest celix_framework_cxx celix_shell_cxx)
+target_link_libraries(celix_shell_cxx_tests PRIVATE gtest celix_framework_cxx celix_cxx_shell celix_cxx_shell_api glog::glog)
-add_test(NAME celix_shell_cxx_tests COMMAND celix_shell_cxx_tests)
-SETUP_TARGET_FOR_COVERAGE(celix_shell_cxx_tests_cov celix_shell_cxx_tests ${CMAKE_BINARY_DIR}/coverage/celix_shell_cxx_tests/celix_shell_cxx_tests)
\ No newline at end of file
+add_test(NAME celix_cxx_shell_tests COMMAND celix_cxx_shell_tests)
+SETUP_TARGET_FOR_COVERAGE(celix_cxx_shell_tests_cov celix_cxx_shell_tests ${CMAKE_BINARY_DIR}/coverage/celix_cxx_shell_tests/celix_cxx_shell_tests ..)
\ No newline at end of file
diff --git a/bundles/shell/cxx_shell/gtest/src/Shell_tests.cc b/bundles/shell/cxx_shell/gtest/src/Shell_tests.cc
new file mode 100644
index 0000000..b6bbd8b
--- /dev/null
+++ b/bundles/shell/cxx_shell/gtest/src/Shell_tests.cc
@@ -0,0 +1,163 @@
+/**
+ *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 <sstream>
+
+#include "gtest/gtest.h"
+
+#include "celix/api.h"
+#include "celix/IShellCommand.h"
+#include "celix/IShell.h"
+
+class ShellTest : public ::testing::Test {
+public:
+ ShellTest() {}
+ ~ShellTest(){}
+
+ celix::Framework& framework() { return fw; }
+private:
+ celix::Framework fw{};
+};
+
+
+
+
+TEST_F(ShellTest, AreCommandsAndShellRegistered) {
+
+ std::string filter = std::string{"("} + celix::IShellCommand::COMMAND_NAME + "=lb)";
+ long svcId = framework().context().findService<celix::IShellCommand>(filter);
+ EXPECT_TRUE(svcId > 0);
+
+ filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=help)";
+ svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+ EXPECT_TRUE(svcId > 0);
+
+ filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=inspect)";
+ svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+ EXPECT_TRUE(svcId > 0);
+
+ filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=query)";
+ svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+ EXPECT_TRUE(svcId > 0);
+
+ filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=stop)";
+ svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+ EXPECT_TRUE(svcId > 0);
+
+ filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=start)";
+ svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+ EXPECT_TRUE(svcId > 0);
+
+ filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=version)";
+ svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+ EXPECT_TRUE(svcId > 0);
+
+ svcId = framework().context().findService<celix::IShell>();
+ EXPECT_TRUE(svcId > 0);
+};
+
+TEST_F(ShellTest, LbCommandTest) {
+ std::stringstream ss{};
+ std::function<void(celix::IShellCommand&)> useLb = [&ss](celix::IShellCommand& cmd){
+ cmd.executeCommand("lb", {}, ss, ss);
+ };
+ std::string filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=lb)";
+ bool called = framework().context().useService(useLb, filter);
+ EXPECT_TRUE(called);
+
+ ss.flush();
+ std::string output = ss.str();
+
+ size_t pos = output.find("1: Framework");
+ EXPECT_LE(pos, output.size());
+ pos = output.find("2: Shell");
+ EXPECT_LE(pos, output.size());
+
+}
+
+TEST_F(ShellTest, HelpCommandTest) {
+ std::string filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=help)";
+ {
+ //call general help
+ std::stringstream ss{};
+ std::function<void(celix::ShellCommandFunction&)> useHelp = [&ss](celix::ShellCommandFunction& cmd){
+ cmd("help", {}, ss, ss);
+ };
+ bool called = framework().context().useFunctionService(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, useHelp, filter);
+ EXPECT_TRUE(called);
+
+ ss.flush();
+ std::string output = ss.str();
+ size_t pos = output.find("help"); //Expect help as command
+ EXPECT_LE(pos, output.size());
+ pos = output.find("lb"); //Expect lb as command
+ EXPECT_LE(pos, output.size());
+ pos = output.find("inspect"); //Expect inspect as command
+ EXPECT_LE(pos, output.size());
+ }
+
+ {
+ //call help with arg
+ std::stringstream ss{};
+ std::vector<std::string> args{};
+ std::function<void(celix::ShellCommandFunction&)> useHelp = [&ss, &args](celix::ShellCommandFunction& cmd){
+ cmd("help", args, ss, ss);
+ };
+
+ args.emplace_back("lb");
+ bool called = framework().context().useFunctionService(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, useHelp, filter);
+ EXPECT_TRUE(called);
+ ss.flush();
+ std::string output = ss.str();
+ size_t pos = output.find("list bundles.");
+ EXPECT_LE(pos, output.size());
+
+ args.clear();
+ args.emplace_back("unknown");
+ ss.clear();
+ called = framework().context().useFunctionService(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, useHelp, filter);
+ EXPECT_TRUE(called);
+ ss.flush();
+ output = ss.str();
+ pos = output.find("not available");
+ EXPECT_LE(pos, output.size());
+ }
+}
+
+TEST_F(ShellTest, VersionCommandTest) {
+ //NOTE that this also test if the resources zip usage (extender pattern).
+
+ std::string filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=version)";
+
+ //call general help
+ std::stringstream ss{};
+ std::function<void(celix::ShellCommandFunction &)> useHelp = [&ss](celix::ShellCommandFunction &cmd) {
+ cmd("version", {}, ss, ss);
+ };
+ bool called = framework().context().useFunctionService(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, useHelp, filter);
+ EXPECT_TRUE(called);
+
+ ss.flush();
+ std::string output = ss.str();
+ size_t pos = output.find("3.0.0"); //Expect 3.0.0 as version
+ EXPECT_LE(pos, output.size());
+}
+
+
+//TODO rest of the commands
\ No newline at end of file
diff --git a/bundles/shell/cxx_shell/src/QueryCommand.cc b/bundles/shell/cxx_shell/src/QueryCommand.cc
index 225709c..67206bc 100644
--- a/bundles/shell/cxx_shell/src/QueryCommand.cc
+++ b/bundles/shell/cxx_shell/src/QueryCommand.cc
@@ -45,7 +45,7 @@ namespace {
svcName = cmdArgs[1];
filter = cmdArgs[2];
} else {
- lang = celix::CXX_LANG;
+ lang = celix::C_AND_CXX_LANG_REG;
svcName = cmdArgs[0];
filter = cmdArgs[1];
}
diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt
index 928932a..c811b70 100644
--- a/libs/CMakeLists.txt
+++ b/libs/CMakeLists.txt
@@ -17,9 +17,9 @@
#utils, dfi and etcdlib are standalone
#(e.g. no dependency on celix framework
-add_subdirectory(utils)
-add_subdirectory(dfi)
-add_subdirectory(etcdlib)
+#add_subdirectory(utils)
+#add_subdirectory(dfi)
+#add_subdirectory(etcdlib)
#add_subdirectory(framework)
diff --git a/libs/framework_cxx/gtest/src/Framework_tests.cc b/libs/framework_cxx/gtest/src/Framework_tests.cc
index 88580f3..ab14713 100644
--- a/libs/framework_cxx/gtest/src/Framework_tests.cc
+++ b/libs/framework_cxx/gtest/src/Framework_tests.cc
@@ -40,7 +40,7 @@ TEST_F(FrameworkTest, CreateDestroy) {
EXPECT_EQ(0, framework().listBundles(false).size());
bool isFramework = false;
- framework().useBundle(0L, [&](const celix::IBundle &bnd) {
+ framework().useBundle(celix::FRAMEWORK_BUNDLE_ID, [&](const celix::IBundle &bnd) {
isFramework = bnd.isFrameworkBundle();
});
EXPECT_TRUE(isFramework);
diff --git a/libs/framework_cxx/include/celix/BundleContext.h b/libs/framework_cxx/include/celix/BundleContext.h
index 296b5c0..21a879e 100644
--- a/libs/framework_cxx/include/celix/BundleContext.h
+++ b/libs/framework_cxx/include/celix/BundleContext.h
@@ -53,7 +53,7 @@ namespace celix {
return registry().registerFunctionService(std::move(functionName), std::forward<F>(function), std::move(props), bundle());
}
- //TODO register C services
+ //TODO reg svc fatories
bool useBundle(long bndId, std::function<void(const celix::IBundle &bnd)> use) const {
return bundle()->framework().useBundle(bndId, std::move(use));
@@ -163,7 +163,25 @@ namespace celix {
return registry().useFunctionServices<F>(functionName, std::move(use), filter, bundle());
}
- //TODO use C services
+ template<typename I>
+ long findService(const std::string &filter = "") {
+ return registry().findService<I>(filter);
+ }
+
+ template<typename F>
+ long findFunctionService(const std::string &functionName, const std::string &filter = "") {
+ return registry().findFunctionService<F>(functionName, filter);
+ }
+
+ template<typename I>
+ std::vector<long> findServices(const std::string &filter = "") {
+ return registry().findServices<I>(filter);
+ }
+
+ template<typename F>
+ std::vector<long> findFunctionServices(const std::string &functionName, const std::string &filter = "") {
+ return registry().findFunctionServices<F>(functionName, filter);
+ }
template<typename I>
celix::ServiceTracker trackServices(celix::ServiceTrackerOptions<I> options = {}) {
@@ -175,15 +193,8 @@ namespace celix {
return registry().trackFunctionServices<F>(functionName, std::move(options), bundle());
}
- //TODO track C Services
-
- //TODO track trackers
-
- //TODO track c trackers
-
celix::ServiceRegistry& registry() const;
- celix::ServiceRegistry& cRegistry() const;
private:
class Impl;
diff --git a/libs/framework_cxx/include/celix/Framework.h b/libs/framework_cxx/include/celix/Framework.h
index 89e9a3b..22d6aef 100644
--- a/libs/framework_cxx/include/celix/Framework.h
+++ b/libs/framework_cxx/include/celix/Framework.h
@@ -89,6 +89,8 @@ namespace celix {
std::string cacheDir() const;
std::string uuid() const;
+ celix::BundleContext& context() const;
+
//TODO trackBundles
//long bundleIdForName(const std::string &bndName) const;
diff --git a/libs/framework_cxx/src/Bundle.h b/libs/framework_cxx/src/Bundle.h
index ce5e456..1adb2c7 100644
--- a/libs/framework_cxx/src/Bundle.h
+++ b/libs/framework_cxx/src/Bundle.h
@@ -29,9 +29,9 @@
namespace celix {
class Bundle : public celix::IBundle {
public:
- Bundle(long _bndId, celix::Framework *_fw, celix::Properties _manifest) :
+ Bundle(long _bndId, const std::string &cacheDir, celix::Framework *_fw, celix::Properties _manifest) :
bndId{_bndId}, fw{_fw}, bndManifest{std::move(_manifest)},
- bundleCache{framework().cacheDir() + "/bundle" + std::to_string(_bndId)},
+ bundleCache{cacheDir + "/bundle" + std::to_string(_bndId)},
bndState{BundleState::INSTALLED} {
bndState.store(BundleState::INSTALLED, std::memory_order_release);
}
@@ -48,7 +48,7 @@ namespace celix {
const std::string &cacheRoot() const noexcept override;
//bundle part
- bool isFrameworkBundle() const noexcept override { return false; }
+ bool isFrameworkBundle() const noexcept override { return bndId == 1 /*note 1 is the framework bundle id*/; }
void *handle() const noexcept override { return nullptr; } //TODO
diff --git a/libs/framework_cxx/src/BundleContext.cc b/libs/framework_cxx/src/BundleContext.cc
index 5b9b192..045f2e3 100644
--- a/libs/framework_cxx/src/BundleContext.cc
+++ b/libs/framework_cxx/src/BundleContext.cc
@@ -26,15 +26,13 @@ namespace celix {
public:
Impl(std::shared_ptr<celix::IBundle> _bnd) :
bnd{std::move(_bnd)},
- reg{&bnd->framework().registry(celix::CXX_LANG)},
- cReg(&bnd->framework().registry(celix::C_LANG)){}
+ reg{&bnd->framework().registry(celix::C_AND_CXX_LANG_REG)} {}
Impl(const Impl&) = delete;
Impl& operator=(const Impl&) = delete;
const std::shared_ptr<celix::IBundle> bnd;
celix::ServiceRegistry * const reg; //TODO make weak_ptr
- celix::ServiceRegistry * const cReg; //TODO make weak_ptr
};
}
@@ -52,7 +50,4 @@ celix::ServiceRegistry& celix::BundleContext::registry() const {
return *pimpl->reg;
}
-celix::ServiceRegistry& celix::BundleContext::cRegistry() const {
- return *pimpl->cReg;
-}
diff --git a/libs/framework_cxx/src/BundleController.h b/libs/framework_cxx/src/BundleController.h
index 1228066..01a821c 100644
--- a/libs/framework_cxx/src/BundleController.h
+++ b/libs/framework_cxx/src/BundleController.h
@@ -247,7 +247,7 @@ namespace celix {
const uint8_t *resourcesZip;
const size_t resourcesZipLen;
- mutable std::mutex mutex{};
+ mutable std::mutex mutex{}; //protects act and lock access to the bundle for state transitions
std::unique_ptr<celix::IBundleActivator> act{nullptr};
};
}
diff --git a/libs/framework_cxx/src/Framework.cc b/libs/framework_cxx/src/Framework.cc
index 0740e5b..1b3ab87 100644
--- a/libs/framework_cxx/src/Framework.cc
+++ b/libs/framework_cxx/src/Framework.cc
@@ -62,28 +62,67 @@ static struct {
static void registerFramework(celix::Framework *fw);
static void unregisterFramework(celix::Framework *fw);
-class celix::Framework::Impl : public IBundle {
-public:
- Impl(celix::Framework *_fw, celix::Properties _config) : fw{_fw}, config{std::move(_config)}, bndManifest{createManifest()}, cwd{cwdString()}, fwUUID{uuidString()}{
- startFramework();
+namespace {
+ //some utils function
+
+ celix::Properties createFwManifest() {
+ celix::Properties m{};
+ m[celix::MANIFEST_BUNDLE_SYMBOLIC_NAME] = "framework";
+ m[celix::MANIFEST_BUNDLE_NAME] = "Framework";
+ m[celix::MANIFEST_BUNDLE_GROUP] = "Celix";
+ m[celix::MANIFEST_BUNDLE_VERSION] = "3.0.0";
+ return m;
+ }
+
+ std::string genUUIDString() {
+ char uuidStr[37];
+ uuid_t uuid;
+ uuid_generate(uuid);
+ uuid_unparse(uuid, uuidStr);
+ return std::string{uuidStr};
+ }
+
+ std::string createCwdString() {
+ char workdir[PATH_MAX];
+ if (getcwd(workdir, sizeof(workdir)) != NULL) {
+ return std::string{workdir};
+ } else {
+ return std::string{};
+ }
}
+ std::string genFwCacheDir(const celix::Properties &/*fwConfig*/) {
+ //TODO make configeruable
+ return createCwdString() + "/.cache";
+ }
+}
+
+class celix::Framework::Impl {
+public:
+ Impl(celix::Framework *_fw, celix::Properties _config) :
+ fw{_fw},
+ config{std::move(_config)},
+ bndManifest{createFwManifest()},
+ cwd{createCwdString()},
+ fwUUID{genUUIDString()},
+ fwCacheDir{genFwCacheDir(config)} {}
+
Impl(const Impl&) = delete;
Impl& operator=(const Impl&) = delete;
- ~Impl() {
- stopFramework();
- waitForShutdown();
- }
+ ~Impl() {}
std::vector<long> listBundles(bool includeFrameworkBundle) const {
std::vector<long> result{};
- if (includeFrameworkBundle) {
- result.push_back(0L); //framework bundle id
- }
std::lock_guard<std::mutex> lock{bundles.mutex};
for (auto &entry : bundles.entries) {
- result.push_back(entry.first);
+ if (entry.second->bundle()->id() == FRAMEWORK_BUNDLE_ID) {
+ if (includeFrameworkBundle) {
+ result.push_back(entry.first);
+ }
+ } else {
+ result.push_back(entry.first);
+ }
}
std::sort(result.begin(), result.end());//ensure that the bundles are order by bndId -> i.e. time of install
return result;
@@ -118,7 +157,7 @@ public:
std::lock_guard<std::mutex> lck{bundles.mutex};
bndId = bundles.nextBundleId++;
- auto bnd = std::shared_ptr<celix::Bundle>{new celix::Bundle{bndId, this->fw, std::move(manifest)}};
+ auto bnd = std::shared_ptr<celix::Bundle>{new celix::Bundle{bndId, this->cacheDir(), this->fw, std::move(manifest)}};
auto ctx = std::shared_ptr<celix::BundleContext>{new celix::BundleContext{bnd}};
bndController = std::shared_ptr<celix::BundleController>{new celix::BundleController{std::move(actFactory), bnd, ctx, resourcesZip, resourcesZipLen}};
bundles.entries.emplace(std::piecewise_construct,
@@ -141,16 +180,15 @@ public:
}
bool startBundle(long bndId) {
- if (bndId == this->fwBndId) {
- //TODO
- return false;
+ if (bndId == FRAMEWORK_BUNDLE_ID) {
+ return startFramework();
} else {
return transitionBundleTo(bndId, BundleState::ACTIVE);
}
}
bool stopBundle(long bndId) {
- if (bndId == this->fwBndId) {
+ if (bndId == FRAMEWORK_BUNDLE_ID) {
return stopFramework();
} else {
return transitionBundleTo(bndId, BundleState::INSTALLED);
@@ -201,26 +239,20 @@ public:
bool useBundle(long bndId, std::function<void(const celix::IBundle &bnd)> use) const {
bool called = false;
- if (bndId == 0) {
- //framework bundle
- use(*this);
- called = true;
- } else {
- std::shared_ptr<celix::BundleController> match = nullptr;
- {
- std::lock_guard<std::mutex> lck{bundles.mutex};
- auto it = bundles.entries.find(bndId);
- if (it != bundles.entries.end()) {
- match = it->second;
- //TODO increase usage
- }
- }
- if (match) {
- use(*match->bundle());
- called = true;
- //TODO decrease usage -> use shared ptr instead
+ std::shared_ptr<celix::BundleController> match = nullptr;
+ {
+ std::lock_guard<std::mutex> lck{bundles.mutex};
+ auto it = bundles.entries.find(bndId);
+ if (it != bundles.entries.end()) {
+ match = it->second;
+ //TODO increase usage
}
}
+ if (match) {
+ use(*match->bundle());
+ called = true;
+ //TODO decrease usage -> use shared ptr instead
+ }
return called;
}
@@ -229,13 +261,16 @@ public:
{
std::lock_guard<std::mutex> lck{bundles.mutex};
for (const auto &it : bundles.entries) {
- useBundles[it.first] = it.second;
+ if (it.second->bundle()->id() == FRAMEWORK_BUNDLE_ID) {
+ if (includeFramework) {
+ useBundles[it.first] = it.second;
+ }
+ } else {
+ useBundles[it.first] = it.second;
+ }
}
}
- if (includeFramework) {
- use(*this);
- }
for (const auto &cntr : useBundles) {
use(*cntr.second->bundle());
}
@@ -257,51 +292,45 @@ public:
}
}
- //resource bundle part
- long id() const noexcept override { return 1L /*note registry empty bundle is id 0, framework is id 1*/; }
- bool hasCacheEntry(const std::string &) const noexcept override { return false; }
- bool isCacheEntryDir(const std::string &) const noexcept override { return false; }
- bool isCacheEntryFile(const std::string &) const noexcept override { return false; }
-
- //virtual bool storeResource(const std::string &path, std::ostream content) noexcept = 0;
- //virtual std::istream open(const std::string &path) const noexcept = 0;
- //virtual std::fstream open(const std::string &path) noexcept = 0;
- std::string absPathForCacheEntry(const std::string &) const noexcept override { return {}; }
- const std::string& cacheRoot() const noexcept override { //TODO
- return cwd;
- }
-
- //bundle stuff
- bool isFrameworkBundle() const noexcept override { return true; }
- void* handle() const noexcept override { return nullptr; }
- celix::BundleState state() const noexcept override { return BundleState::ACTIVE ; }
- const std::string& name() const noexcept override { return bndManifest.at(celix::MANIFEST_BUNDLE_NAME); }
- const std::string& symbolicName() const noexcept override { return bndManifest.at(celix::MANIFEST_BUNDLE_SYMBOLIC_NAME); }
- const std::string& group() const noexcept override { return bndManifest.at(celix::MANIFEST_BUNDLE_GROUP); }
- const std::string& version() const noexcept override { return bndManifest.at(celix::MANIFEST_BUNDLE_VERSION); }
- const celix::Properties& manifest() const noexcept override { return bndManifest;}
- bool isValid() const noexcept override { return true; }
- celix::Framework& framework() const noexcept override { return *fw; }
std::string cacheDir() const {
- return cwd + "/.cache"; //TODO make configurable
+ return fwCacheDir;
}
- std::vector<std::string> readCacheDir(const std::string &) const noexcept override { return {}; } //TODO
-
std::string uuid() const {
return fwUUID;
}
+ celix::BundleContext& frameworkContext() const {
+ std::lock_guard<std::mutex> lck(bundles.mutex);
+ return *bundles.entries.at(celix::FRAMEWORK_BUNDLE_ID)->context();
+ }
+
bool startFramework() {
//TODO create cache dir using a process id (and lock file?).
//Maybe also move to /var/cache or /tmp and when framework stop delete all framework caches of not running processes
- std::cout << "Celix Framework Started";
+
+ {
+ //Adding framework bundle to the bundles.
+ auto bnd = std::shared_ptr<celix::Bundle>{new celix::Bundle{FRAMEWORK_BUNDLE_ID, this->fwCacheDir, this->fw, bndManifest}};
+ bnd->setState(BundleState::ACTIVE);
+ auto ctx = std::shared_ptr<celix::BundleContext>{new celix::BundleContext{bnd}};
+ class EmptyActivator : public IBundleActivator {};
+ std::function<celix::IBundleActivator*(std::shared_ptr<celix::BundleContext>)> fac = [](std::shared_ptr<celix::BundleContext>) {
+ return new EmptyActivator{};
+ };
+ auto ctr = std::shared_ptr<celix::BundleController>{new celix::BundleController{std::move(fac), std::move(bnd), std::move(ctx), nullptr, 0}};
+ std::lock_guard<std::mutex> lck{bundles.mutex};
+ bundles.entries[FRAMEWORK_BUNDLE_ID] = std::move(ctr);
+ }
+
+ //TODO update state
+
+ std::cout << "Celix Framework Started\n";
return true;
}
bool stopFramework() {
- //TODO create cache dir
std::lock_guard<std::mutex> lck{shutdown.mutex};
if (!shutdown.shutdownStarted) {
shutdown.future = std::async(std::launch::async, [this]{
@@ -317,7 +346,12 @@ public:
shutdown.shutdownStarted = true;
shutdown.cv.notify_all();
}
- std::cout << "Celix Framework Stopped";
+
+ //TODO update bundle state
+
+ //TODO clean cache dir
+
+ std::cout << "Celix Framework Stopped\n";
return true;
}
@@ -329,38 +363,13 @@ public:
return true;
}
private:
- celix::Properties createManifest() {
- celix::Properties m{};
- m[celix::MANIFEST_BUNDLE_SYMBOLIC_NAME] = "framework";
- m[celix::MANIFEST_BUNDLE_NAME] = "Framework";
- m[MANIFEST_BUNDLE_GROUP] = "Celix";
- m[celix::MANIFEST_BUNDLE_VERSION] = "3.0.0";
- return m;
- }
- std::string uuidString() {
- char uuidStr[37];
- uuid_t uuid;
- uuid_generate(uuid);
- uuid_unparse(uuid, uuidStr);
- return std::string{uuidStr};
- }
-
- std::string cwdString() {
- char workdir[PATH_MAX];
- if (getcwd(workdir, sizeof(workdir)) != NULL) {
- return std::string{workdir};
- } else {
- return std::string{};
- }
- }
-
- const long fwBndId = 1L;
celix::Framework * const fw;
const celix::Properties config;
const celix::Properties bndManifest;
const std::string cwd;
const std::string fwUUID;
+ const std::string fwCacheDir;
struct {
@@ -374,7 +383,7 @@ private:
struct {
std::unordered_map<long, std::shared_ptr<celix::BundleController>> entries{};
- long nextBundleId = 2;
+ long nextBundleId = FRAMEWORK_BUNDLE_ID + 1;
mutable std::mutex mutex{};
} bundles{};
@@ -389,11 +398,14 @@ private:
**********************************************************************************************************************/
celix::Framework::Framework(celix::Properties config) : pimpl{std::unique_ptr<Impl>{new Impl{this, std::move(config)}}} {
+ pimpl->startFramework();
registerFramework(this);
}
celix::Framework::~Framework() {
unregisterFramework(this);
+ pimpl->stopFramework();
+ pimpl->waitForShutdown();
}
celix::Framework::Framework(Framework &&rhs) = default;
@@ -435,6 +447,9 @@ std::string celix::Framework::uuid() const {
return pimpl->uuid();
}
+celix::BundleContext& celix::Framework::context() const {
+ return pimpl->frameworkContext();
+}
/***********************************************************************************************************************
* Celix 'global' functions
diff --git a/libs/registry/CMakeLists.txt b/libs/registry/CMakeLists.txt
index 5880f52..a7de533 100644
--- a/libs/registry/CMakeLists.txt
+++ b/libs/registry/CMakeLists.txt
@@ -16,10 +16,11 @@
# under the License.
add_library(celix_registry STATIC
- src/ServiceRegistry.cc
+ src/Utils.cc
src/Filter.cc
src/Properties.cc
-)
+ src/ServiceRegistry.cc)
+
target_include_directories(celix_registry PRIVATE src)
target_include_directories(celix_registry PUBLIC include)
target_link_libraries(celix_registry PRIVATE glog::glog)
diff --git a/libs/registry/gtest/CMakeLists.txt b/libs/registry/gtest/CMakeLists.txt
index b534c50..88a8b87 100644
--- a/libs/registry/gtest/CMakeLists.txt
+++ b/libs/registry/gtest/CMakeLists.txt
@@ -17,8 +17,9 @@
set(SOURCES
src/main.cc
- src/Registry_tests.cc
+ src/Utils_tests.cc
src/Filter_tests.cc
+ src/Registry_tests.cc
src/ServiceTracking_tests.cc
src/RegistryConcurrency_tests.cc
)
diff --git a/libs/registry/gtest/src/Registry_tests.cc b/libs/registry/gtest/src/Registry_tests.cc
index d8fad0e..49941ea 100644
--- a/libs/registry/gtest/src/Registry_tests.cc
+++ b/libs/registry/gtest/src/Registry_tests.cc
@@ -180,7 +180,7 @@ TEST_F(RegistryTest, UseServices) {
EXPECT_EQ(&svc, &intf1);
long id = celix::getProperty(props, celix::SERVICE_ID, 0);
EXPECT_EQ(svcId1, id);
- EXPECT_EQ(0, bnd.id()); //not nullptr -> use empty bundle (bndId 0)
+ EXPECT_EQ(LONG_MAX, bnd.id()); //not nullptr -> use empty bundle (bndId 0)
});
EXPECT_TRUE(called);
}
diff --git a/libs/registry/gtest/src/Utils_tests.cc b/libs/registry/gtest/src/Utils_tests.cc
new file mode 100644
index 0000000..3994109
--- /dev/null
+++ b/libs/registry/gtest/src/Utils_tests.cc
@@ -0,0 +1,56 @@
+/**
+ *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/Utils.h"
+
+class UtilsTest : public ::testing::Test {
+public:
+ UtilsTest() {}
+ ~UtilsTest(){}
+};
+
+class MarkerInterface;
+
+namespace example {
+ class MarkerInterface;
+}
+
+class SvcWithFqn {
+ static constexpr const char * const FQN = "SvcWithFqn[Version 1]";
+};
+
+TEST_F(UtilsTest, svcName) {
+ std::string name = celix::serviceName<MarkerInterface>();
+ EXPECT_EQ("MarkerInterface", name);
+
+ name = celix::serviceName<example::MarkerInterface>();
+ EXPECT_EQ("example::MarkerInterface", name);
+
+ name = celix::serviceName<SvcWithFqn>();
+ //TODO EXPECT_EQ("SvcWithFqn[Version 1]", name);
+
+ name = celix::functionServiceName<std::function<void()>>("do");
+ EXPECT_EQ("do[std::function<void()>]", name);
+
+
+ name = celix::functionServiceName<std::function<std::vector<std::vector<long>>(long, int, std::vector<double>)>>("collect");
+ //TODO EXPECT_EQ("collect[std::function<std::vector<std::vector<long>>(long, int, std::vector<double>)>]", name);
+}
\ No newline at end of file
diff --git a/libs/registry/include/celix/Constants.h b/libs/registry/include/celix/Constants.h
index 517a372..96f6326 100644
--- a/libs/registry/include/celix/Constants.h
+++ b/libs/registry/include/celix/Constants.h
@@ -31,14 +31,14 @@ namespace celix {
static constexpr const char *const FRAMEWORK_UUID = "framework.uuid";
- static constexpr const char *const CXX_LANG = "C++";
- static constexpr const char *const C_LANG = "C";
-
+ static constexpr const char *const C_AND_CXX_LANG_REG = "C/C++";
static constexpr const char *const MANIFEST_BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
static constexpr const char *const MANIFEST_BUNDLE_NAME = "Bundle-Name";
static constexpr const char *const MANIFEST_BUNDLE_VERSION = "Bundle-Version";
static constexpr const char *const MANIFEST_BUNDLE_GROUP = "Bundle-Group";
+
+ static constexpr long FRAMEWORK_BUNDLE_ID = 1L;
}
#endif //CXX_CELIX_CONSTANTS_H
diff --git a/libs/registry/include/celix/ServiceRegistry.h b/libs/registry/include/celix/ServiceRegistry.h
index 76b277d..c9a9a8e 100644
--- a/libs/registry/include/celix/ServiceRegistry.h
+++ b/libs/registry/include/celix/ServiceRegistry.h
@@ -145,10 +145,29 @@ namespace celix {
}
template<typename F>
- celix::ServiceRegistration registerFunctionService(const std::string &functionName, F&& func, celix::Properties props = {}, std::shared_ptr<const celix::IResourceBundle> owner = {});
+ celix::ServiceRegistration registerFunctionService(
+ const std::string &functionName,
+ F&& func, celix::Properties props = {},
+ std::shared_ptr<const celix::IResourceBundle> owner = {});
template<typename I>
- celix::ServiceRegistration registerServiceFactory(std::shared_ptr<celix::IServiceFactory<I>> factory, celix::Properties props = {}, std::shared_ptr<const celix::IResourceBundle> owner = {});
+ celix::ServiceRegistration registerServiceFactory(
+ std::shared_ptr<celix::IServiceFactory<I>> factory,
+ celix::Properties props = {},
+ std::shared_ptr<const celix::IResourceBundle> owner = {}) {
+ auto svcName = celix::serviceName<I>();
+ return registerServiceFactory(svcName, std::move(factory), std::move(props), std::move(owner));
+ }
+
+ template<typename F>
+ celix::ServiceRegistration registerFunctionServiceFactory(
+ const std::string &functionName,
+ std::shared_ptr<celix::IServiceFactory<F>> factory,
+ celix::Properties props = {},
+ std::shared_ptr<const celix::IResourceBundle> owner = {}) {
+ auto svcName = celix::functionServiceName<F>(functionName);
+ return registerServiceFactory(svcName, std::move(factory), std::move(props), std::move(owner));
+ }
template<typename I>
//NOTE C++17 typename std::enable_if<!std::is_callable<I>::value, long>::type
@@ -160,7 +179,7 @@ namespace celix {
template<typename I>
//NOTE C++17 typename std::enable_if<std::is_callable<I>::value, long>::type
long findFunctionService(const std::string &functionName, const std::string &filter = "") const {
- auto services = findFunctionService<I>(functionName, filter);
+ auto services = findFunctionServices<I>(functionName, filter);
return services.size() > 0 ? services[0] : -1L;
}
@@ -190,8 +209,6 @@ namespace celix {
return trackServices<F>(svcName, std::move(options), std::move(requester));
}
- //TODO trackTrackers
-
template<typename I>
int useServices(std::function<void(I& svc)> use, const std::string &filter = "", std::shared_ptr<const celix::IResourceBundle> requester = {}) const {
auto svcName = celix::serviceName<I>();
@@ -338,8 +355,18 @@ namespace celix {
std::unique_ptr<celix::ServiceRegistry::Impl> pimpl;
//register services
- celix::ServiceRegistration registerService(std::string svcName, std::shared_ptr<void> svc, celix::Properties props, std::shared_ptr<const celix::IResourceBundle> owner);
- celix::ServiceRegistration registerServiceFactory(std::string svcName, std::shared_ptr<celix::IServiceFactory<void>> factory, celix::Properties props, std::shared_ptr<const celix::IResourceBundle> owner);
+ celix::ServiceRegistration registerService(
+ std::string svcName,
+ std::shared_ptr<void> svc,
+ celix::Properties props,
+ std::shared_ptr<const celix::IResourceBundle> owner);
+
+ template<typename I>
+ celix::ServiceRegistration registerServiceFactory(
+ std::string svcName,
+ std::shared_ptr<celix::IServiceFactory<I>> factory,
+ celix::Properties props,
+ std::shared_ptr<const celix::IResourceBundle> owner);
//use Services
template<typename I>
@@ -351,6 +378,8 @@ namespace celix {
const std::string &filter,
std::shared_ptr<const celix::IResourceBundle> requester) const;
+ celix::ServiceRegistration registerServiceFactory(std::string svcName, std::shared_ptr<celix::IServiceFactory<void>> factory, celix::Properties props, std::shared_ptr<const celix::IResourceBundle> owner);
+
template<typename I>
bool useService(
const std::string &svcName,
@@ -394,9 +423,7 @@ inline celix::ServiceRegistration celix::ServiceRegistry::registerFunctionServic
}
template<typename I>
-inline celix::ServiceRegistration celix::ServiceRegistry::registerServiceFactory(std::shared_ptr<celix::IServiceFactory<I>> factory, celix::Properties props, std::shared_ptr<const celix::IResourceBundle> owner) {
- std::string svcName = celix::serviceName<I>();
-
+inline celix::ServiceRegistration celix::ServiceRegistry::registerServiceFactory(std::string svcName, std::shared_ptr<celix::IServiceFactory<I>> factory, celix::Properties props, std::shared_ptr<const celix::IResourceBundle> owner) {
class VoidServiceFactory : public celix::IServiceFactory<void> {
public:
VoidServiceFactory(std::shared_ptr<celix::IServiceFactory<I>> _factory) : factory{std::move(_factory)} {}
diff --git a/libs/registry/include/celix/Utils.h b/libs/registry/include/celix/Utils.h
index 5640636..09d674d 100644
--- a/libs/registry/include/celix/Utils.h
+++ b/libs/registry/include/celix/Utils.h
@@ -24,29 +24,20 @@
#include <string>
#include <iostream>
+namespace celix {
+namespace impl {
+ void assertIsNotFunctionService(const std::string &svcName);
+ std::string typeNameFromPrettyFunction(const std::string &templateName, const std::string &pretty);
+}
+}
+
namespace {
template<typename INTERFACE_TYPENAME>
std::string typeName() {
- std::string result;
-
- const char *templateStr = "INTERFACE_TYPENAME = ";
- const size_t templateStrLen = strlen(templateStr);
-
- result = __PRETTY_FUNCTION__; //USING pretty function to retrieve the filled in template argument without using typeid()
- size_t bpos = result.find(templateStr) + templateStrLen; //find begin pos after INTERFACE_TYPENAME = entry
- size_t epos = bpos;
- while (isalnum(result[epos]) || result[epos] == '_' || result[epos] == ':' || result[epos] == ' ' || result[epos] == '*' || result[epos] == '&' || result[epos] == '<' || result[epos] == '>') {
- epos += 1;
- }
- size_t len = epos - bpos;
- result = result.substr(bpos, len);
-
- if (result.empty()) {
- std::cerr << "Cannot infer type name in function call '" << __PRETTY_FUNCTION__ << "'\n'";
- }
-
- return result;
+ static const std::string templateStr = "INTERFACE_TYPENAME = ";
+ std::string pretty = __PRETTY_FUNCTION__;
+ return celix::impl::typeNameFromPrettyFunction(templateStr, __PRETTY_FUNCTION__);
}
template<typename Arg>
@@ -60,13 +51,13 @@ namespace {
}
template<typename R>
- std::string functionName(const std::string &funcName) {
- return funcName + " [std::function<" + typeName<R>() + "()>]";
+ std::string functionName() {
+ return "std::function<" + typeName<R>() + "()>";
}
template<typename R, typename Arg1, typename... Args>
- std::string functionName(const std::string &funcName) {
- return funcName + " [std::function<" + typeName<R>() + "(" + argName<Arg1, Args...>() + ")>]";
+ std::string functionName() {
+ return "std::function<" + typeName<R>() + "(" + argName<Arg1, Args...>() + ")>";
}
};
@@ -85,9 +76,13 @@ namespace celix {
template<typename I>
//NOTE C++17 typename std::enable_if<!std::is_callable<I>::value, std::string>::type
std::string serviceName() {
- return typeName<I>();
+ std::string svcName = typeName<I>();
+ celix::impl::assertIsNotFunctionService(svcName);
+ return svcName;
}
+ //TODO resolve FQN for Function Service.
+
/**
* Returns the service name for a std::function I.
* Note that for a std::function the additional function name is needed to get a fully qualified service name;
@@ -95,7 +90,8 @@ namespace celix {
template<typename F>
//NOTE C++17 typename std::enable_if<std::is_callable<I>::value, std::string>::type
std::string functionServiceName(const std::string &fName) {
- return functionName<decltype(&F::operator())>(fName);
+ std::string func = functionName<decltype(&F::operator())>();
+ return fName + "[" + func + "]";
}
}
diff --git a/libs/registry/src/ServiceRegistry.cc b/libs/registry/src/ServiceRegistry.cc
index 58d5778..6ed83f7 100644
--- a/libs/registry/src/ServiceRegistry.cc
+++ b/libs/registry/src/ServiceRegistry.cc
@@ -40,7 +40,11 @@ namespace {
public:
~EmptyBundle() override = default;
- long id() const noexcept override { return 0; }
+ long id() const noexcept override {
+ //TODO not sure what todo. 1 is reserved for the framework and I would like to keep <= 0 as invalid, so
+ //that default initialized long are not a valid bundle / svc id.
+ return LONG_MAX;
+ }
const std::string& cacheRoot() const noexcept override {
static std::string empty{};
@@ -94,7 +98,11 @@ namespace {
void decrUsage() const {
std::lock_guard<std::mutex> lck{mutex};
- usage -= 1;
+ if (usage == 0) {
+ LOG(ERROR) << "Usage count decrease below 0!" << std::endl;
+ } else {
+ usage -= 1;
+ }
cond.notify_all();
}
@@ -298,7 +306,11 @@ namespace {
void decrUsage() const {
std::lock_guard<std::mutex> lck{mutex};
- usage -= 1;
+ if (usage == 0) {
+ LOG(ERROR) << "Usage count decrease below 0!" << std::endl;
+ } else {
+ usage -= 1;
+ }
cond.notify_all();
}
@@ -516,8 +528,8 @@ public:
celix::ServiceRegistry::ServiceRegistry(std::string name) : pimpl{new ServiceRegistry::Impl{std::move(name)}} {}
-celix::ServiceRegistry::ServiceRegistry(celix::ServiceRegistry &&rhs) = default;
-celix::ServiceRegistry& celix::ServiceRegistry::operator=(celix::ServiceRegistry &&rhs) = default;
+celix::ServiceRegistry::ServiceRegistry(celix::ServiceRegistry &&) = default;
+celix::ServiceRegistry& celix::ServiceRegistry::operator=(celix::ServiceRegistry &&) = default;
celix::ServiceRegistry::~ServiceRegistry() {
if (pimpl) {
//TODO
@@ -637,6 +649,7 @@ int celix::ServiceRegistry::useAnyServices(const std::string &svcName,
const celix::IResourceBundle &bnd)> use,
const std::string &f,
std::shared_ptr<const celix::IResourceBundle> requester) const {
+
celix::Filter filter = f;
if (!filter.valid()) {
LOG(WARNING) << "Invalid filter (" << f << ") provided. Cannot find services" << std::endl;
@@ -664,18 +677,19 @@ int celix::ServiceRegistry::useAnyServices(const std::string &svcName,
entry->decrUsage();
}};
use(svc, entry->props, *entry->owner);
- entry->decrUsage();
}
return (int)matches.size();
}
//TODO move to Impl
-bool celix::ServiceRegistry::useAnyService(const std::string &svcName,
- std::function<void(std::shared_ptr<void> svc, const celix::Properties &props,
- const celix::IResourceBundle &bnd)> use,
- const std::string &f,
- std::shared_ptr<const celix::IResourceBundle> requester) const {
+bool celix::ServiceRegistry::useAnyService(
+ const std::string &svcName,
+ std::function<void(std::shared_ptr<void> svc, const celix::Properties &props,
+ const celix::IResourceBundle &bnd)> use,
+ const std::string &f,
+ std::shared_ptr<const celix::IResourceBundle> requester) const {
+
celix::Filter filter = f;
if (!filter.valid()) {
LOG(WARNING) << "Invalid filter (" << f << ") provided. Cannot find services" << std::endl;
@@ -720,8 +734,8 @@ std::vector<std::string> celix::ServiceRegistry::listAllRegisteredServiceNames()
celix::ServiceRegistration::ServiceRegistration() : pimpl{nullptr} {}
celix::ServiceRegistration::ServiceRegistration(celix::ServiceRegistration::Impl *impl) : pimpl{impl} {}
-celix::ServiceRegistration::ServiceRegistration(celix::ServiceRegistration &&rhs) noexcept = default;
-celix::ServiceRegistration& celix::ServiceRegistration::operator=(celix::ServiceRegistration &&rhs) noexcept = default;
+celix::ServiceRegistration::ServiceRegistration(celix::ServiceRegistration &&) noexcept = default;
+celix::ServiceRegistration& celix::ServiceRegistration::operator=(celix::ServiceRegistration &&) noexcept = default;
celix::ServiceRegistration::~ServiceRegistration() { unregister(); }
long celix::ServiceRegistration::serviceId() const { return pimpl ? pimpl->entry->svcId : -1L; }
@@ -774,8 +788,8 @@ void celix::ServiceTracker::stop() {
}
}
-celix::ServiceTracker::ServiceTracker(celix::ServiceTracker &&rhs) noexcept = default;
-celix::ServiceTracker& celix::ServiceTracker::operator=(celix::ServiceTracker &&rhs) noexcept = default;
+celix::ServiceTracker::ServiceTracker(celix::ServiceTracker &&) noexcept = default;
+celix::ServiceTracker& celix::ServiceTracker::operator=(celix::ServiceTracker &&) noexcept = default;
int celix::ServiceTracker::trackCount() const { return pimpl ? pimpl->entry->count() : 0; }
const std::string& celix::ServiceTracker::serviceName() const { return pimpl? pimpl->entry->svcName : emptyString; }
diff --git a/libs/registry/src/Utils.cc b/libs/registry/src/Utils.cc
new file mode 100644
index 0000000..27feccb
--- /dev/null
+++ b/libs/registry/src/Utils.cc
@@ -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.
+ */
+
+#include "celix/Utils.h"
+
+#include <string>
+
+#include <glog/logging.h>
+
+void celix::impl::assertIsNotFunctionService(const std::string &svcName) {
+ size_t pos = svcName.find("::function"); //note could be std::fuction or st::__1::function, etc?
+ if (pos <= svcName.size()) {
+ //match
+ LOG(WARNING) << "Unexpected std::function as template argument. For function use the find/use/trackFunctionService instead of find/use/trackService!" << std::endl;
+ assert(false);
+ }
+}
+
+std::string celix::impl::typeNameFromPrettyFunction(const std::string &templateName, const std::string &prettyFunction) {
+ std::string result = prettyFunction; //USING pretty function to retrieve the filled in template argument without using typeid()
+ size_t bpos = result.find(templateName) + templateName.size(); //find begin pos after INTERFACE_TYPENAME = entry
+ size_t epos = bpos;
+ while (isalnum(result[epos]) || result[epos] == '_' || result[epos] == ':' || result[epos] == '*' || result[epos] == '&' || result[epos] == '<' || result[epos] == '>') {
+ epos += 1;
+ }
+ size_t len = epos - bpos;
+ result = result.substr(bpos, len);
+
+ if (result.empty()) {
+ LOG(WARNING) << "Cannot infer type name in function call '" << prettyFunction << "'\n'";
+ }
+
+ return result;
+}
+