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/27 18:53:06 UTC
[58/60] [abbrv] celix git commit: Merge branch 'develop' into
feature/CELIX-426-cxx-api
http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/Properties.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/Properties.h
index 0000000,0000000..65fd4ef
new file mode 100644
--- /dev/null
+++ b/libs/framework/include/celix/Properties.h
@@@ -1,0 -1,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/2e04253d/libs/framework/include/celix/dm/Component.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/Component.h
index 0000000,06aaf20..0edc8e9
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/Component.h
+++ b/libs/framework/include/celix/dm/Component.h
@@@ -1,0 -1,234 +1,234 @@@
+ /**
+ * 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_DM_COMPONENT_H
-#define CELIX_DM_COMPONENT_H
++#ifndef CXX_CELIX_DM_COMPONENT_H
++#define CXX_CELIX_DM_COMPONENT_H
+
+ #include "celix/dm/types.h"
+ #include "dm_component.h"
+
+ #include <map>
+ #include <string>
+ #include <vector>
+
+ namespace celix { namespace dm {
+
+ class BaseComponent {
+ private:
+ bundle_context_pt context {nullptr};
+ dm_component_pt cCmp {nullptr};
+ public:
+ BaseComponent(const bundle_context_pt con, std::string name) : context{con}, cCmp{nullptr} {
+ component_create(this->context, name.c_str(), &this->cCmp);
+ component_setImplementation(this->cCmp, this);
+ }
+ virtual ~BaseComponent() {}
+
+ BaseComponent(const BaseComponent&) = delete;
+ BaseComponent& operator=(const BaseComponent&) = delete;
+
+ /**
+ * Returns the C DM Component
+ */
+ dm_component_pt cComponent() const { return this->cCmp; }
+
+ /**
+ * Returns the C bundle context
+ */
+ bundle_context_pt bundleContext() const { return this->context; }
+ };
+
+
+ template<class T>
+ class Component : public BaseComponent {
+ using type = T;
+ private:
+ std::unique_ptr<T> instance {nullptr};
+ std::shared_ptr<T> sharedInstance {nullptr};
+ std::vector<T> valInstance {};
+ std::vector<std::shared_ptr<BaseServiceDependency>> dependencies {};
+
+ void (T::*initFp)() = {};
+ void (T::*startFp)() = {};
+ void (T::*stopFp)() = {};
+ void (T::*deinitFp)() = {};
+
+ int (T::*initFpNoExc)() = {};
+ int (T::*startFpNoExc)() = {};
+ int (T::*stopFpNoExc)() = {};
+ int (T::*deinitFpNoExc)() = {};
+ public:
+ Component(const bundle_context_pt context, std::string name);
+ virtual ~Component();
+
+ /**
+ * Creates a Component using the provided bundle context
+ * and component name.
+ * Will use new(nothrow) if exceptions are disabled.
+ * @return newly created DM Component or nullptr
+ */
+ static Component<T>* create(bundle_context_pt, std::string name);
+
+ /**
+ * Creates a Component using the provided bundle context.
+ * Will use new(nothrow) if exceptions are disabled.
+ * @return newly created DM Component or nullptr
+ */
+ static Component<T>* create(bundle_context_pt);
+
+ /**
+ * Wether the component is valid. Invalid component can occurs when no new components can be created and
+ * exceptions are not allowed.
+ * @return
+ */
+ bool isValid() const;
+
+ /**
+ * Get the component instance. If no instance is explicitly set with setInstance than a instance will be create
+ * using a default constructor.
+ *
+ * @return A reference to the component instance.
+ */
+ T& getInstance();
+
+ /**
+ * Set the component instance using a shared pointer.
+ *
+ * @return the DM Component reference for chaining (fluent API)
+ */
+ Component<T>& setInstance(std::shared_ptr<T> inst);
+
+ /**
+ * Set the component instance using a unique pointer.
+ *
+ * @return the DM Component reference for chaining (fluent API)
+ */
+ Component<T>& setInstance(std::unique_ptr<T>&& inst);
+
+ /**
+ * Set the component instance using a value or rval reference
+ * The DM Component will contain the instance.
+ *
+ * @return the DM Component reference for chaining (fluent API)
+ */
+ Component<T>& setInstance(T&& inst);
+
+ /**
+ * Adds a C++ interface to provide as service to the Celix framework.
+ *
+ * @param serviceName The service name to use
+ * @param version The version of the interface (e.g. "1.0.0"), can be an empty string
+ * @param properties To (meta) properties to provide with the service
+ * @return the DM Component reference for chaining (fluent API)
+ */
+ template<class I> Component<T>& addInterfaceWithName(const std::string serviceName, const std::string version = std::string{}, const Properties properties = Properties{});
+
+ /**
+ * Adds a C++ interface to provide as service to the Celix framework.
+ *
+ * @param serviceName The service name to use
+ * @param version The version of the interface (e.g. "1.0.0"), can be an empty string
+ * @param properties To (meta) properties to provide with the service
+ * @return the DM Component reference for chaining (fluent API)
+ */
+ template<class I> Component<T>& addInterface(const std::string version = std::string{}, const Properties properties = Properties{});
+
+ /**
+ * Adds a C interface to provide as service to the Celix framework.
+ *
+ * @param svc The service struct
+ * @param serviceName The service name to use
+ * @param version The version of the interface (e.g. "1.0.0"), can be an empty string
+ * @param properties To (meta) properties to provide with the service
+ */
+ template<class I> Component<T>& addCInterface(const I* svc, const std::string serviceName, const std::string version = std::string{}, const Properties properties = Properties{});
+
+
+ /**
+ * Creates and adds a C++ service dependency to the component
+ *
+ * @return the Service Dependency reference for chaining (fluent API)
+ */
+ template<class I>
+ ServiceDependency<T,I>& createServiceDependency(const std::string name = std::string{});
+
+ /**
+ Removes a C++ service dependency from the component
+ *
+ * @return the DM Component reference for chaining (fluent API)
+ */
+ template<class I>
+ Component<T>& remove(ServiceDependency<T,I>& dep);
+
+ /**
+ * Adds a C service dependency to the component
+ *
+ * @return the DM Component reference for chaining (fluent API)
+ */
+ template<typename I>
+ CServiceDependency<T,I>& createCServiceDependency(const std::string name);
+
+ /**
+ * Removes a C service dependency to the component
+ *
+ * @return the DM Component reference for chaining (fluent API)
+ */
+ template<typename I>
+ Component<T>& remove(CServiceDependency<T,I>& dep);
+
+ /**
+ * Set the callback for the component life cycle control
+ *
+ * @param init The init callback.
+ * @param start The start callback.
+ * @param stop The stop callback.
+ * @param deinit The deinit callback.
+ *
+ * @return the DM Component reference for chaining (fluent API)
+ */
+ Component<T>& setCallbacks(
+ void (T::*init)(),
+ void (T::*start)(),
+ void (T::*stop)(),
+ void (T::*deinit)()
+ );
+
+ /**
+ * Set the callback for the component life cycle control
+ * with a int return to indicate an error.
+ *
+ * @param init The init callback.
+ * @param start The start callback.
+ * @param stop The stop callback.
+ * @param deinit The deinit callback.
+ *
+ * @return the DM Component reference for chaining (fluent API)
+ */
+ Component<T>& setCallbacks(
+ int (T::*init)(),
+ int (T::*start)(),
+ int (T::*stop)(),
+ int (T::*deinit)()
+ );
+ };
+ }}
+
+ #include "celix/dm/Component_Impl.h"
+
-#endif //CELIX_DM_COMPONENT_H
++#endif //CXX_CELIX_DM_COMPONENT_H
http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/dm/DependencyManager.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/DependencyManager.h
index 0000000,f90a03c..538edb1
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/DependencyManager.h
+++ b/libs/framework/include/celix/dm/DependencyManager.h
@@@ -1,0 -1,150 +1,149 @@@
+ /**
+ * 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_DM_DEPENDENCYMANAGER_H
++#define CXX_CELIX_DM_DEPENDENCYMANAGER_H
++
+
+ #include "celix/dm/types.h"
+ #include "celix/dm/Component.h"
+ #include "celix/dm/ServiceDependency.h"
+
-#include "bundle_context.h"
+ #include "celix_bundle_context.h"
+ #include "dm_dependency_manager.h"
+
+ #include <vector>
+ #include <mutex>
+
-#ifndef CELIX_DM_DEPENDENCYMANAGER_H
-#define CELIX_DM_DEPENDENCYMANAGER_H
-
+ namespace celix { namespace dm {
-
++
+ class DependencyManager {
+ public:
+ DependencyManager(bundle_context_pt ctx) : context(ctx) {
- this->cDepMan = celix_bundleContext_getDependencyManager(ctx);
++ this->cDepMan = celix_bundleContext_getDependencyManager(ctx);
+ }
-
++
+ virtual ~DependencyManager() {
- this->cDepMan = nullptr;
++ this->cDepMan = nullptr;
+ }
-
++
+ DependencyManager(DependencyManager&& mgr) : componentsMutex{} {
- std::lock_guard<std::recursive_mutex> lock(this->componentsMutex);
- mgr.context = this->context;
- mgr.queuedComponents = std::move(this->queuedComponents);
- mgr.startedComponents = std::move(this->startedComponents);
- mgr.cDepMan = this->cDepMan;
- this->cDepMan = nullptr;
- this->context = nullptr;
++ std::lock_guard<std::recursive_mutex> lock(this->componentsMutex);
++ mgr.context = this->context;
++ mgr.queuedComponents = std::move(this->queuedComponents);
++ mgr.startedComponents = std::move(this->startedComponents);
++ mgr.cDepMan = this->cDepMan;
++ this->cDepMan = nullptr;
++ this->context = nullptr;
+ }
+ DependencyManager& operator=(DependencyManager&&) = default;
-
++
+ DependencyManager(const DependencyManager&) = delete;
+ DependencyManager& operator=(const DependencyManager&) = delete;
-
++
+ bundle_context_pt bundleContext() const { return context; }
+ dm_dependency_manager_pt cDependencyManager() const { return cDepMan; }
-
-
++
++
+ /**
+ * Creates and adds a new DM Component for a component of type T.
+ *
+ * @return Returns a reference to the DM Component
+ */
+ template<class T>
+ Component<T>& createComponent(std::string name = std::string{});
-
++
+ /**
+ * Creates and adds a new DM Component for a component of type T and setting
+ * the instance using a unique ptr.
+ *
+ * @return Returns a reference to the DM Component
+ */
+ template<class T>
+ Component<T>& createComponent(std::unique_ptr<T>&& rhs, std::string name = std::string{});
-
++
+ /**
+ * Creates and adds a new DM Component for a component of type T and setting
+ * the instance using a shared ptr.
+ *
+ * @return Returns a reference to the DM Component
+ */
+ template<class T>
+ Component<T>& createComponent(std::shared_ptr<T> rhs, std::string name = std::string{});
-
++
+ /**
+ * Creates and adds a new DM Component for a component of type T and setting
+ * the instance.
+ *
+ * @return Returns a reference to the DM Component
+ */
+ template<class T>
+ Component<T>& createComponent(T rhs, std::string name = std::string{});
-
++
+ /**
+ * Starts the Dependency Manager
+ */
+ void start() {
- std::vector<std::unique_ptr<BaseComponent>> toBeStartedComponents {};
- {
- std::lock_guard<std::recursive_mutex> lock(componentsMutex);
- for (auto it = queuedComponents.begin(); it != queuedComponents.end(); ++it) {
- toBeStartedComponents.push_back(std::move(*it));
- }
- queuedComponents.clear();
++ std::vector<std::unique_ptr<BaseComponent>> toBeStartedComponents {};
++ {
++ std::lock_guard<std::recursive_mutex> lock(componentsMutex);
++ for (auto it = queuedComponents.begin(); it != queuedComponents.end(); ++it) {
++ toBeStartedComponents.push_back(std::move(*it));
+ }
- for (auto it = toBeStartedComponents.begin(); it != toBeStartedComponents.end(); ++it) {
-
- dependencyManager_add(cDepMan, (*it)->cComponent());
- {
- std::lock_guard<std::recursive_mutex> lock(componentsMutex);
- startedComponents.push_back(std::move(*it));
- }
++ queuedComponents.clear();
++ }
++ for (auto it = toBeStartedComponents.begin(); it != toBeStartedComponents.end(); ++it) {
++
++ dependencyManager_add(cDepMan, (*it)->cComponent());
++ {
++ std::lock_guard<std::recursive_mutex> lock(componentsMutex);
++ startedComponents.push_back(std::move(*it));
+ }
++ }
+ }
-
++
+ /**
+ * Removes a component from the Dependency Manager and destroys it
+ */
+ template<typename T>
+ void destroyComponent(Component<T> &component) {
+ dependencyManager_remove(cDepMan, component.cComponent());
+ }
-
++
+ /**
+ * Stops the Dependency Manager
+ */
+ void stop() {
- dependencyManager_removeAllComponents(cDepMan);
- queuedComponents.clear();
- startedComponents.clear();
++ dependencyManager_removeAllComponents(cDepMan);
++ queuedComponents.clear();
++ startedComponents.clear();
+ }
+ private:
+ bundle_context_pt context {nullptr};
+ std::vector<std::unique_ptr<BaseComponent>> queuedComponents {};
+ std::vector<std::unique_ptr<BaseComponent>> startedComponents {};
+ dm_dependency_manager_pt cDepMan {nullptr};
+ std::recursive_mutex componentsMutex{};
+ };
-
++
+ }}
+
+ #include "celix/dm/DependencyManager_Impl.h"
+
-#endif //CELIX_DM_DEPENDENCYMANAGER_H
++#endif //CXX_CELIX_DM_DEPENDENCYMANAGER_H
http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/dm/DmActivator.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/DmActivator.h
index 0000000,d7aac3c..ee8cde7
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/DmActivator.h
+++ b/libs/framework/include/celix/dm/DmActivator.h
@@@ -1,0 -1,97 +1,97 @@@
+ /**
+ * 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_DM_ACTIVATOR_H
-#define CELIX_DM_ACTIVATOR_H
++#ifndef CXX_CELIX_DM_ACTIVATOR_H
++#define CXX_CELIX_DM_ACTIVATOR_H
+
+
+ #include <utility>
+
+ #include "celix/dm/DependencyManager.h"
+ #include "bundle_activator.h"
+
+ namespace celix { namespace dm {
+
+ class DmActivator {
+ public:
+ DmActivator(DependencyManager& m) : mng(m), ctx{m.bundleContext()} {}
+ virtual ~DmActivator() = default;
+
+ DmActivator(const DmActivator&) = delete;
+ DmActivator& operator=(const DmActivator&) = delete;
+
+ DependencyManager& manager() const { return this->mng; }
+
+ bundle_context_pt context() const { return this->ctx; }
+
+ /**
+ * The init of the DM Activator. Should be overridden by the bundle specific DM activator.
+ *
+ * @param manager A reference to the Dependency Manager
+ */
+ virtual void init() {};
+
+ /**
+ * The init of the DM Activator. Can be overridden by the bundle specific DM activator.
+ *
+ * @param manager A reference to the Dependency Manager
+ */
+ virtual void deinit() {};
+
+ /**
+ * The static method to create a new DM activator.
+ * NOTE that this method in intentionally not implemented in the C++ Dependency Manager library.
+ * This should be done by the bundle specific DM activator.
+ *
+ * @param mng A reference to the Dependency Manager
+ * @returns A pointer to a DmActivator. The Dependency Manager is responsible for deleting the pointer when the bundle is stopped.
+ */
+ static DmActivator* create(DependencyManager& mng);
+
+ protected:
+ DependencyManager& mng;
+ bundle_context_pt ctx;
+ private:
+ int start() {
+ celix_status_t status = CELIX_SUCCESS;
+ this->init();
+ this->mng.start();
+
+ return status;
+ }
+
+ int stop() {
+ celix_status_t status = CELIX_SUCCESS;
+
+ this->deinit();
+
+ // Remove all components
+ dependencyManager_removeAllComponents(this->mng.cDependencyManager());
+
+ return status;
+ }
+
+ friend int ::bundleActivator_create(::bundle_context_pt, void**);
+ friend int ::bundleActivator_start(void*, ::bundle_context_pt);
+ friend int ::bundleActivator_stop(void*, ::bundle_context_pt);
+ friend int ::bundleActivator_destroy(void*, ::bundle_context_pt);
+ };
+ }}
+
-#endif //CELIX_DM_ACTIVATOR_H
++#endif //CXX_CELIX_DM_ACTIVATOR_H
http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/dm/Properties.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/Properties.h
index 0000000,bb4fd78..fc485ca
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/Properties.h
+++ b/libs/framework/include/celix/dm/Properties.h
@@@ -1,0 -1,30 +1,29 @@@
+ /**
+ * 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_DM_PROPERTIES_H
-#define CELIX_DM_PROPERTIES_H
++#ifndef CXX_CELIX_DM_PROPERTIES_H
++#define CXX_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
++#endif //CXX_CELIX_DM_PROPERTIES_H
http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/dm/ServiceDependency.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/ServiceDependency.h
index 0000000,f439b82..b2b6afb
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/ServiceDependency.h
+++ b/libs/framework/include/celix/dm/ServiceDependency.h
@@@ -1,0 -1,326 +1,326 @@@
+ /**
+ * 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_DM_SERVICEDEPENDENCY_H
-#define CELIX_DM_SERVICEDEPENDENCY_H
++#ifndef CXX_CELIX_DM_SERVICEDEPENDENCY_H
++#define CXX_CELIX_DM_SERVICEDEPENDENCY_H
+
+ #include "dm_service_dependency.h"
+ #include "celix/dm/types.h"
+
+ #include <map>
+ #include <string>
+ #include <list>
+ #include <tuple>
+ #include <memory>
+ #include <iostream>
+ #include <functional>
+
+ namespace celix { namespace dm {
+
+ class DependencyManager; //forward declaration
+
+ enum class DependencyUpdateStrategy {
+ suspend,
+ locking
+ };
+
+ class BaseServiceDependency {
+ protected:
+ const bool valid;
+ dm_service_dependency_pt cServiceDep {nullptr};
+
+ void setDepStrategy(DependencyUpdateStrategy strategy) {
+ if (!valid) {
+ return;
+ }
+ if (strategy == DependencyUpdateStrategy::locking) {
+ serviceDependency_setStrategy(this->cServiceDependency(), DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING);
+ } else if (strategy == DependencyUpdateStrategy::suspend) {
+ serviceDependency_setStrategy(this->cServiceDependency(), DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND);
+ } else {
+ std::cerr << "Unexpected dependency update strategy. Cannot convert for dm_depdendency\n";
+ }
+ }
+ public:
+ BaseServiceDependency(bool v) : valid{v} {
+ if (this->valid) {
+ serviceDependency_create(&this->cServiceDep);
+ //NOTE using suspend as default strategy
+ serviceDependency_setStrategy(this->cServiceDep, DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND);
+ }
+ }
+
+ virtual ~BaseServiceDependency() = default;
+
+ BaseServiceDependency(const BaseServiceDependency&) = delete;
+ BaseServiceDependency& operator=(const BaseServiceDependency&) = delete;
+
+ /**
+ * Wether the service dependency is valid.
+ */
+ bool isValid() const { return valid; }
+
+ /**
+ * Returns the C DM service dependency
+ */
+ dm_service_dependency_pt cServiceDependency() const { return cServiceDep; }
+ };
+
+ template<class T>
+ class TypedServiceDependency : public BaseServiceDependency {
+ using cmpType = T;
+ protected:
+ T* componentInstance {nullptr};
+ public:
+ TypedServiceDependency(bool valid) : BaseServiceDependency(valid) {}
+ virtual ~TypedServiceDependency() = default;
+
+ TypedServiceDependency(const TypedServiceDependency&) = delete;
+ TypedServiceDependency& operator=(const TypedServiceDependency&) = delete;
+ TypedServiceDependency(TypedServiceDependency&&) = default;
+ TypedServiceDependency& operator=(TypedServiceDependency&&) = default;
+
+ /**
+ * Set the component instance with a pointer
+ */
+ void setComponentInstance(T* cmp) { componentInstance = cmp;}
+ };
+
+ template<class T, typename I>
+ class CServiceDependency : public TypedServiceDependency<T> {
+ using type = I;
+ public:
+ CServiceDependency(const std::string name, bool valid = true);
+ virtual ~CServiceDependency() = default;
+
+ /**
+ * Sets the service version range for the C service dependency.
+ *
+ * @param serviceVersionRange The service version range, can be an empty string
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ CServiceDependency<T,I>& setVersionRange(const std::string serviceVersionRange);
+
+ /**
+ * Sets the service filter for the C service dependency.
+ *
+ * @param filter The (additional) filter to use (e.g. "(location=front)")
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ CServiceDependency<T,I>& setFilter(const std::string filter);
+
+ /**
+ * Specify if the service dependency is required. Default is false
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ CServiceDependency<T,I>& setRequired(bool req);
+
+ /**
+ * Specify if the update strategy to use
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ CServiceDependency<T,I>& setStrategy(DependencyUpdateStrategy strategy);
+
+ /**
+ * Set the set callback for when the service dependency becomes available
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ CServiceDependency<T,I>& setCallbacks(void (T::*set)(const I* service));
+
+ /**
+ * Set the set callback for when the service dependency becomes available
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ CServiceDependency<T,I>& setCallbacks(void (T::*set)(const I* service, Properties&& properties));
+
+ /**
+ * Set the set callback for when the service dependency becomes available
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ CServiceDependency<T,I>& setCallbacks(std::function<void(const I* service, Properties&& properties)> set);
+
+ /**
+ * Set the add and remove callback for when the services of service dependency are added or removed.
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ CServiceDependency<T,I>& setCallbacks(void (T::*add)(const I* service), void (T::*remove)(const I* service));
+
+ /**
+ * Set the add and remove callback for when the services of service dependency are added or removed.
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ CServiceDependency<T,I>& setCallbacks(
+ void (T::*add)(const I* service, Properties&& properties),
+ void (T::*remove)(const I* service, Properties&& properties)
+ );
+
+ /**
+ * Set the add and remove callback for when the services of service dependency are added or removed.
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ CServiceDependency<T,I>& setCallbacks(
+ std::function<void(const I* service, Properties&& properties)> add,
+ std::function<void(const I* service, Properties&& properties)> remove
+ );
+
+ /**
+ * Specify if the service dependency should add a service.lang filter part if it is not already present
+ * For C service dependencies 'service.lang=C' will be added.
+ */
+ CServiceDependency<T,I>& setAddLanguageFilter(bool addLang);
+ private:
+ std::string name {};
+ std::string filter {};
+ std::string versionRange {};
+
+ std::function<void(const I* service, Properties&& properties)> setFp{nullptr};
+ std::function<void(const I* service, Properties&& properties)> addFp{nullptr};
+ std::function<void(const I* service, Properties&& properties)> removeFp{nullptr};
+
+ void setupCallbacks();
+ int invokeCallback(std::function<void(const I*, Properties&&)> fp, service_reference_pt ref, const void* service);
+
+ void setupService();
+ };
+
+ template<class T, class I>
+ class ServiceDependency : public TypedServiceDependency<T> {
+ using type = I;
+ public:
+ ServiceDependency(const std::string name = std::string{}, bool valid = true);
+ virtual ~ServiceDependency() = default;
+
+ /**
+ * Set the service name of the service dependency.
+ *
+ * @return the C++ service dependency reference for chaining (fluent API)
+ */
+ ServiceDependency<T,I>& setName(const std::string name);
+
+ /**
+ * Set the service filter of the service dependency.
+ *
+ * @return the C++ service dependency reference for chaining (fluent API)
+ */
+ ServiceDependency<T,I>& setFilter(const std::string filter);
+
+ /**
+ * Set the service version range of the service dependency.
+ *
+ * @return the C++ service dependency reference for chaining (fluent API)
+ */
+ ServiceDependency<T,I>& setVersionRange(const std::string versionRange);
+
+ /**
+ * Set the set callback for when the service dependency becomes available
+ *
+ * @return the C++ service dependency reference for chaining (fluent API)
+ */
+ ServiceDependency<T,I>& setCallbacks(void (T::*set)(I* service));
+
+ /**
+ * Set the set callback for when the service dependency becomes available
+ *
+ * @return the C++ service dependency reference for chaining (fluent API)
+ */
+ ServiceDependency<T,I>& setCallbacks(void (T::*set)(I* service, Properties&& properties));
+
+ /**
+ * Set the set callback for when the service dependency becomes available
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ ServiceDependency<T,I>& setCallbacks(std::function<void(I* service, Properties&& properties)> set);
+
+ /**
+ * Set the add and remove callback for when the services of service dependency are added or removed.
+ *
+ * @return the C++ service dependency reference for chaining (fluent API)
+ */
+ ServiceDependency<T,I>& setCallbacks(void (T::*add)(I* service), void (T::*remove)(I* service));
+
+ /**
+ * Set the add and remove callback for when the services of service dependency are added or removed.
+ *
+ * @return the C++ service dependency reference for chaining (fluent API)
+ */
+ ServiceDependency<T,I>& setCallbacks(
+ void (T::*add)(I* service, Properties&& properties),
+ void (T::*remove)(I* service, Properties&& properties)
+ );
+
+ /**
+ * Set the add and remove callback for when the services of service dependency are added or removed.
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ ServiceDependency<T,I>& setCallbacks(
+ std::function<void(I* service, Properties&& properties)> add,
+ std::function<void(I* service, Properties&& properties)> remove
+ );
+
+ /**
+ * Specify if the service dependency is required. Default is false
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ ServiceDependency<T,I>& setRequired(bool req);
+
+ /**
+ * Specify if the update strategy to use
+ *
+ * @return the C service dependency reference for chaining (fluent API)
+ */
+ ServiceDependency<T,I>& setStrategy(DependencyUpdateStrategy strategy);
+
+ /**
+ * Specify if the service dependency should add a service.lang filter part if it is not already present
+ * For C++ service dependencies 'service.lang=C++' will be added.
+ * Should be called before
+ */
+ ServiceDependency<T,I>& setAddLanguageFilter(bool addLang);
+ private:
+ bool addCxxLanguageFilter {true};
+ std::string name {};
+ std::string filter {};
+ std::string versionRange {};
+ std::string modifiedFilter {};
+
+ std::function<void(I* service, Properties&& properties)> setFp{nullptr};
+ std::function<void(I* service, Properties&& properties)> addFp{nullptr};
+ std::function<void(I* service, Properties&& properties)> removeFp{nullptr};
+
+ void setupService();
+ void setupCallbacks();
+ int invokeCallback(std::function<void(I*, Properties&&)> fp, service_reference_pt ref, const void* service);
+ };
+ }}
+
+ #include "celix/dm/ServiceDependency_Impl.h"
+
+
-#endif //CELIX_DM_SERVICEDEPENDENCY_H
++#endif //CXX_CELIX_DM_SERVICEDEPENDENCY_H
http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/dm/types.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/types.h
index 0000000,43f0f04..8b7b120
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/types.h
+++ b/libs/framework/include/celix/dm/types.h
@@@ -1,0 -1,90 +1,90 @@@
+ /**
+ * 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_DM_TYPES_H
-#define CELIX_DM_TYPES_H
++#ifndef CXX_CELIX_DM_TYPES_H
++#define CXX_CELIX_DM_TYPES_H
+
+ #include <map>
+ #include <string>
+ #include <list>
+ #include <tuple>
+ #include <typeinfo>
+ #include <memory>
+ #include <cxxabi.h>
+ #include <string.h>
+ #include "celix/dm/Properties.h"
+ #include <stdlib.h>
+ #include <iostream>
+
+ namespace celix { namespace dm {
+ //forward declarations
+ class DependencyManager;
+
+
+ class BaseServiceDependency;
+
+ template<class T, typename I>
+ class CServiceDependency;
+
+ template<class T, class I>
+ class ServiceDependency;
+
+ /**
+ * Returns the deferred type name for the template I
+ */
+ template<typename INTERFACE_TYPENAME>
+ const std::string typeName() {
+ std::string result;
+
+ #ifdef __GXX_RTTI
+ result = typeid(INTERFACE_TYPENAME).name();
+ int status = 0;
+ char* demangled_name {abi::__cxa_demangle(result.c_str(), NULL, NULL, &status)};
+ if(status == 0) {
+ result = std::string{demangled_name};
+ free(demangled_name);
+ }
+ #else
+ 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] == ':') {
+ epos += 1;
+ }
+ size_t len = epos - bpos;
+ result = result.substr(bpos, len);
+ #endif
+
+ // std::cout << "PRETTY IS '" << __PRETTY_FUNCTION__ << "'\n";
+ // std::cout << "RESULT IS '" << result << "'\n";
+
+ if (result.empty()) {
+ std::cerr << "Cannot infer type name in function call '" << __PRETTY_FUNCTION__ << "'\n'";
+ }
+
+
+ return result;
+ }
+
+ }}
+
-#endif //CELIX_DM_TYPES_H
++#endif //CXX_CELIX_DM_TYPES_H
http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/impl/BundleContextImpl.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/impl/BundleContextImpl.h
index 0000000,0000000..67f079b
new file mode 100644
--- /dev/null
+++ b/libs/framework/include/celix/impl/BundleContextImpl.h
@@@ -1,0 -1,0 +1,554 @@@
++/**
++ *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_BUNDLECONTEXTIMPL_H
++#define CELIX_IMPL_BUNDLECONTEXTIMPL_H
++
++#include <mutex>
++#include <cstring>
++#include <memory>
++
++#include "bundle_context.h"
++#include "service_tracker.h"
++
++#include "celix/impl/BundleImpl.h"
++#include "celix/dm/DependencyManager.h"
++#include "celix_service_factory.h"
++
++namespace celix {
++
++ namespace impl {
++ struct ServiceTrackingEntryFunctions {
++ std::function<void(void *)> set{};
++ std::function<void(void *, const celix::Properties &)> setWithProperties{};
++ std::function<void(void *, const celix::Properties &, const celix::Bundle &)> setWithOwner{};
++
++ std::function<void(void *)> add{};
++ std::function<void(void *, const celix::Properties &)> addWithProperties{};
++ std::function<void(void *, const celix::Properties &, const celix::Bundle &)> addWithOwner{};
++
++ std::function<void(void *)> remove{};
++ std::function<void(void *, const celix::Properties &)> removeWithProperties{};
++ std::function<void(void *, const celix::Properties &, const celix::Bundle &)> removeWithOwner{};
++ };
++
++ struct ServiceRegistrationEntry {
++ ServiceRegistrationEntry() {
++ std::memset(&this->cOpts, 0, sizeof(this->cOpts));
++ std::memset(&this->factory, 0, sizeof(this->factory));
++ }
++
++ celix_service_factory_t factory = {nullptr, nullptr, nullptr};
++ celix_service_registration_options_t cOpts = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
++ };
++
++ struct ServiceTrackingEntry {
++ celix_service_tracking_options_t cOpts{{nullptr, nullptr, nullptr, nullptr}, nullptr, nullptr, nullptr, nullptr,
++ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
++ std::unique_ptr<ServiceTrackingEntryFunctions> functions{nullptr};
++ };
++ }
++
++ struct BundleContext::Impl {
++ Impl(celix_bundle_context_t *_c_ctx, celix::Framework &_fw) : c_ctx(_c_ctx), fw(_fw), bnd(c_ctx), dm(c_ctx) {}
++ ~Impl() = default;
++
++ Impl(const Impl&) = delete;
++ Impl& operator=(const Impl&) = delete;
++ Impl(Impl&&) = delete;
++ Impl& operator=(Impl&&) = delete;
++
++ //initialized in ctor
++ bundle_context_t *c_ctx;
++ celix::Framework& fw;
++ celix::impl::BundleImpl bnd;
++ celix::dm::DependencyManager dm;
++
++ std::mutex mutex{};
++ std::map<long,celix::impl::ServiceTrackingEntry> trackingEntries{};
++ std::map<long,celix::impl::ServiceRegistrationEntry> registrationEntries{};
++
++ long registerServiceInternal(celix::impl::ServiceRegistrationEntry &&entry) noexcept;
++ long trackServicesInternal(celix::impl::ServiceTrackingEntry &&entry) noexcept;
++ bool useServiceInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept;
++ void useServicesInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept;
++ };
++}
++
++namespace {
++ 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;
++ }
++}
++
++inline celix::BundleContext::BundleContext(bundle_context_t *ctx, celix::Framework& fw) {
++ this->pimpl = std::unique_ptr<celix::BundleContext::Impl>{new celix::BundleContext::Impl(ctx, fw)};
++}
++
++inline celix::BundleContext::~BundleContext() {
++ //NOTE no need to destroy the c bundle context -> done by c framework
++ {
++ //clearing service registration
++ std::lock_guard<std::mutex> lock{this->pimpl->mutex};
++ for (auto &pair : this->pimpl->registrationEntries) {
++ celix_bundleContext_unregisterService(this->pimpl->c_ctx, pair.first);
++ }
++ this->pimpl->registrationEntries.clear();
++ }
++
++ {
++ //clearing tracker entries
++ std::lock_guard<std::mutex> lock{this->pimpl->mutex};
++ for (auto &pair : this->pimpl->trackingEntries) {
++ celix_bundleContext_stopTracker(this->pimpl->c_ctx, pair.first);
++ }
++ this->pimpl->trackingEntries.clear();
++ }
++
++ this->pimpl->c_ctx = nullptr;
++ this->pimpl = nullptr;
++}
++
++
++inline void celix::BundleContext::unregisterService(long serviceId) noexcept {
++ std::lock_guard<std::mutex> lock{this->pimpl->mutex};
++ celix_bundleContext_unregisterService(this->pimpl->c_ctx, serviceId);
++ auto it = this->pimpl->registrationEntries.find(serviceId);
++ if (it != this->pimpl->registrationEntries.end()) {
++ this->pimpl->registrationEntries.erase(it);
++ }
++}
++
++inline std::vector<long> celix::BundleContext::findServices(const std::string &/*serviceName*/, const std::string &/*versionRange*/, const std::string &/*filter*/, const std::string &/*lang = ""*/) noexcept {
++ 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);
++// }
++// };
++ //TODO useServicesWithOptions this->useServicesInternal(serviceName, versionRange, filter, use);
++ return result;
++}
++
++inline void celix::BundleContext::stopTracker(long trackerId) noexcept {
++ std::lock_guard<std::mutex> lock{this->pimpl->mutex};
++ celix_bundleContext_stopTracker(this->pimpl->c_ctx, trackerId);
++ auto it = this->pimpl->trackingEntries.find(trackerId);
++ if (it != this->pimpl->trackingEntries.end()) {
++ this->pimpl->trackingEntries.erase(it);
++ }
++}
++
++inline std::string celix::BundleContext::getProperty(const std::string &key, std::string defaultValue) noexcept {
++ const char *val = nullptr;
++ bundleContext_getPropertyWithDefault(this->pimpl->c_ctx, key.c_str(), defaultValue.c_str(), &val);
++ return std::string{val};
++}
++
++
++// long celix::BundleContext::registerEmbeddedBundle(
++// std::string /*id*/,
++// std::function<void(celix::BundleContext & ctx)> /*start*/,
++// std::function<void(celix::BundleContext & ctx)> /*stop*/,
++// celix::Properties /*manifest*/,
++// bool /*autoStart*/
++// ) noexcept {
++// return -1; //TODO
++// };
++//
++// void registerEmbeddedBundle(const celix::BundleRegistrationOptions &/*opts*/) noexcept override {
++// //TODO
++// }
++
++inline long celix::BundleContext::installBundle(const std::string &bundleLocation, bool autoStart) noexcept {
++ long bndId = -1;
++ if (this->pimpl->c_ctx != nullptr) {
++ bundle_t *bnd = nullptr;
++ bundleContext_installBundle(this->pimpl->c_ctx, bundleLocation.c_str(), &bnd);
++ if (bnd != nullptr) {
++ bundle_getBundleId(bnd, &bndId);
++ if (autoStart) {
++ bundle_start(bnd);
++ }
++ }
++ }
++ return bndId;
++}
++
++
++inline void celix::BundleContext::useBundles(const std::function<void(const celix::Bundle &bnd)> &use) noexcept {
++ 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->pimpl->c_ctx, (void*)(&use), c_use);
++}
++
++inline bool celix::BundleContext::useBundle(long bundleId, const std::function<void(const celix::Bundle &bnd)> &use) noexcept {
++ 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->pimpl->c_ctx, bundleId, (void*)(&use), c_use);
++}
++
++inline celix::Framework& celix::BundleContext::getFramework() noexcept {
++ return this->pimpl->fw;
++}
++
++inline celix::Bundle& celix::BundleContext::getBundle() noexcept {
++ return this->pimpl->bnd;
++};
++
++inline celix::dm::DependencyManager& celix::BundleContext::getDependencyManager() noexcept {
++ return this->pimpl->dm;
++}
++
++inline long celix::BundleContext::Impl::registerServiceInternal(celix::impl::ServiceRegistrationEntry&& entry) noexcept {
++ long svcId = celix_bundleContext_registerServiceWithOptions(this->c_ctx, &entry.cOpts);
++ if (svcId >= 0) {
++ std::lock_guard<std::mutex> lock{this->mutex};
++ this->registrationEntries[svcId] = std::move(entry);
++ }
++ return svcId;
++}
++
++inline long celix::BundleContext::Impl::trackServicesInternal(celix::impl::ServiceTrackingEntry &&entry) noexcept {
++ long trkId = celix_bundleContext_trackServicesWithOptions(this->c_ctx, &entry.cOpts);
++ if (trkId >= 0) {
++ std::lock_guard<std::mutex> lock{this->mutex};
++ this->trackingEntries[trkId] = std::move(entry);
++ }
++ return trkId;
++}
++
++inline bool celix::BundleContext::Impl::useServiceInternal(
++ const std::string &serviceName,
++ const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
++ 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 *m_bnd = const_cast<celix_bundle_t*>(c_svcOwner);
++ celix::impl::BundleImpl bnd{m_bnd};
++ (*fn)(svc, props, bnd);
++ };
++
++ celix_service_use_options_t opts;
++ std::memset(&opts, 0, sizeof(opts));
++
++ opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
++ opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG;
++ opts.callbackHandle = (void*)&use;
++ opts.useWithOwner = c_use;
++
++ return celix_bundleContext_useServiceWithOptions(this->c_ctx, &opts);
++}
++
++inline void celix::BundleContext::Impl::useServicesInternal(
++ const std::string &serviceName,
++ const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
++ 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 *m_bnd = const_cast<celix_bundle_t*>(c_svcOwner);
++ celix::impl::BundleImpl bnd{m_bnd};
++ (*fn)(svc, props, bnd);
++ };
++
++ celix_service_use_options_t opts;
++ std::memset(&opts, 0, sizeof(opts));
++
++ opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
++ opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG;
++ opts.callbackHandle = (void*)&use;
++ opts.useWithOwner = c_use;
++
++ celix_bundleContext_useServicesWithOptions(this->c_ctx, &opts);
++}
++
++
++template<typename I>
++long celix::BundleContext::registerService(I *svc, const std::string &serviceName, Properties props) noexcept {
++ celix::ServiceRegistrationOptions<I> opts{*svc, serviceName};
++ opts.properties = std::move(props);
++ return this->registerServiceWithOptions(opts);
++}
++
++template<typename I>
++long celix::BundleContext::registerCService(I *svc, const std::string &serviceName, Properties props) noexcept {
++ static_assert(std::is_pod<I>::value, "Service I must be a 'Plain Old Data' object");
++ celix::ServiceRegistrationOptions<I> opts{*svc, serviceName};
++ opts.properties = std::move(props);
++ opts.serviceLanguage = celix::Constants::SERVICE_C_LANG;
++ return this->registerServiceWithOptions(opts);
++}
++
++template<typename I>
++long celix::BundleContext::registerServiceFactory(celix::IServiceFactory<I> *factory, const std::string &serviceName, celix::Properties props) {
++ celix::ServiceRegistrationOptions<I> opts{factory, serviceName};
++ opts.properties = std::move(props);
++ return this->registerServiceWithOptions(opts);
++}
++
++template<typename I>
++long celix::BundleContext::registerCServiceFactory(IServiceFactory<I> *factory, const std::string &serviceName, celix::Properties props) {
++ static_assert(std::is_pod<I>::value, "Service I must be a 'Plain Old Data' object");
++ celix::ServiceRegistrationOptions<I> opts{factory, serviceName};
++ opts.properties = std::move(props);
++ opts.serviceLanguage = celix::Constants::SERVICE_C_LANG;
++ return this->registerServiceWithOptions(opts);
++}
++
++template<typename I>
++long celix::BundleContext::registerServiceWithOptions(const celix::ServiceRegistrationOptions<I>& opts) noexcept {
++ celix_properties_t *c_props = celix_properties_create();
++ for (auto &pair : opts.properties) {
++ celix_properties_set(c_props, pair.first.c_str(), pair.second.c_str());
++ }
++
++ celix::impl::ServiceRegistrationEntry re{};
++
++ re.cOpts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
++ if (opts.svc != nullptr) {
++ re.cOpts.svc = static_cast<void *>(opts.svc);
++ } else if (opts.factory != nullptr) {
++ auto c_getService = [](void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties) -> void* {
++ celix::IServiceFactory<I> *f = static_cast<celix::IServiceFactory<I>*>(handle);
++ auto mbnd = const_cast<celix_bundle_t*>(requestingBundle);
++ celix::impl::BundleImpl bundle{mbnd};
++ celix::Properties props = createFromCProps(svcProperties);
++ I *svc = f->getService(bundle, props);
++ return static_cast<void*>(svc);
++ };
++ auto c_ungetService = [](void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties) {
++ celix::IServiceFactory<I> *f = static_cast<celix::IServiceFactory<I>*>(handle);
++ auto mbnd = const_cast<celix_bundle_t*>(requestingBundle);
++ celix::impl::BundleImpl bundle{mbnd};
++ celix::Properties props = createFromCProps(svcProperties);
++ f->ungetService(bundle, props);
++ };
++ re.factory.handle = static_cast<void*>(opts.factory);
++ re.factory.getService = c_getService;
++ re.factory.ungetService = c_ungetService;
++ re.cOpts.factory = &re.factory;
++ }
++
++ re.cOpts.serviceName = opts.serviceName.c_str();
++ re.cOpts.serviceVersion = opts.serviceVersion.c_str();
++ re.cOpts.serviceLanguage = opts.serviceLanguage.c_str();
++ re.cOpts.properties = c_props;
++
++ return this->pimpl->registerServiceInternal(std::move(re));
++}
++
++template<typename I>
++long celix::BundleContext::trackService(const std::string &serviceName, std::function<void(I *svc)> set) noexcept {
++ celix::ServiceTrackingOptions<I> opts{serviceName};
++ opts.set = std::move(set);
++ return this->trackServicesWithOptions<I>(opts);
++}
++
++template<typename I>
++long celix::BundleContext::trackServices(const std::string &serviceName,
++ std::function<void(I *svc)> add, std::function<void(I *svc)> remove) noexcept {
++ celix::ServiceTrackingOptions<I> opts{serviceName};
++ opts.add = std::move(add);
++ opts.remove = std::move(remove);
++ return this->trackServicesWithOptions<I>(opts);
++}
++
++template<typename I>
++long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTrackingOptions<I>& opts) {
++ celix::impl::ServiceTrackingEntry entry{};
++ entry.functions = std::unique_ptr<celix::impl::ServiceTrackingEntryFunctions>{new celix::impl::ServiceTrackingEntryFunctions()};
++
++ auto set = opts.set;
++ if (set) {
++ auto voidfunc = [set](void *voidSvc) {
++ I *typedSvc = static_cast<I*>(voidSvc);
++ set(typedSvc);
++ };
++ entry.functions->set = voidfunc;
++ entry.cOpts.set = [](void *handle, void *svc) {
++ auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++ (fentry->set)(svc);
++ };
++ }
++
++ auto setWithProperties = opts.setWithProperties;
++ if (setWithProperties) {
++ auto voidfunc = [setWithProperties](void *voidSvc, const celix::Properties &props) {
++ I *typedSvc = static_cast<I*>(voidSvc);
++ setWithProperties(typedSvc, props);
++ };
++ entry.functions->setWithProperties = voidfunc;
++ entry.cOpts.setWithProperties = [](void *handle, void *svc, const celix_properties_t *c_props) {
++ auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++ celix::Properties props = createFromCProps(c_props);
++ (fentry->setWithProperties)(svc, props);
++ };
++ }
++
++ auto setWithOwner = opts.setWithOwner;
++ if (setWithOwner) {
++ auto voidfunc = [setWithOwner](void *voidSvc, const celix::Properties &props, const celix::Bundle &bnd) {
++ I *typedSvc = static_cast<I*>(voidSvc);
++ setWithOwner(typedSvc, props, bnd);
++ };
++ entry.functions->setWithOwner = voidfunc;
++ entry.cOpts.setWithOwner = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
++ auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++ celix::Properties props = createFromCProps(c_props);
++ auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
++ celix::impl::BundleImpl bnd{m_bnd};
++ (fentry->setWithOwner)(svc, props, bnd);
++ };
++ }
++
++ auto add = opts.add;
++ if (add) {
++ auto voidfunc = [add](void *voidSvc) {
++ I *typedSvc = static_cast<I*>(voidSvc);
++ add(typedSvc);
++ };
++ entry.functions->add = voidfunc;
++ entry.cOpts.add = [](void *handle, void *svc) {
++ auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++ (fentry->add)(svc);
++ };
++ }
++
++ auto addWithProperties = opts.addWithProperties;
++ if (addWithProperties) {
++ auto voidfunc = [addWithProperties](void *voidSvc, const celix::Properties &props) {
++ I *typedSvc = static_cast<I*>(voidSvc);
++ addWithProperties(typedSvc, props);
++ };
++ entry.functions->addWithProperties = voidfunc;
++ entry.cOpts.addWithProperties = [](void *handle, void *svc, const celix_properties_t *c_props) {
++ auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++ celix::Properties props = createFromCProps(c_props);
++ (fentry->addWithProperties)(svc, props);
++ };
++ }
++
++ auto addWithOwner = opts.setWithOwner;
++ if (addWithOwner) {
++ auto voidfunc = [addWithOwner](void *voidSvc, const celix::Properties &props, const celix::Bundle &bnd) {
++ I *typedSvc = static_cast<I*>(voidSvc);
++ addWithOwner(typedSvc, props, bnd);
++ };
++ entry.functions->addWithOwner = voidfunc;
++ entry.cOpts.addWithOwner = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
++ auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++ celix::Properties props = createFromCProps(c_props);
++ auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
++ celix::impl::BundleImpl bnd{m_bnd};
++ (fentry->addWithOwner)(svc, props, bnd);
++ };
++ }
++
++ auto remove = opts.remove;
++ if (remove) {
++ auto voidfunc = [remove](void *voidSvc) {
++ I *typedSvc = static_cast<I*>(voidSvc);
++ remove(typedSvc);
++ };
++ entry.functions->remove = voidfunc;
++ entry.cOpts.remove = [](void *handle, void *svc) {
++ auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++ (fentry->add)(svc);
++ };
++ }
++
++ auto removeWithProperties = opts.removeWithProperties;
++ if (removeWithProperties) {
++ auto voidfunc = [removeWithProperties](void *voidSvc, const celix::Properties &props) {
++ I *typedSvc = static_cast<I*>(voidSvc);
++ removeWithProperties(typedSvc, props);
++ };
++ entry.functions->removeWithProperties = voidfunc;
++ entry.cOpts.removeWithProperties = [](void *handle, void *svc, const celix_properties_t *c_props) {
++ auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++ celix::Properties props = createFromCProps(c_props);
++ (fentry->removeWithProperties)(svc, props);
++ };
++ }
++
++ auto removeWithOwner = opts.removeWithOwner;
++ if (removeWithOwner) {
++ auto voidfunc = [removeWithOwner](void *voidSvc, const celix::Properties &props, const celix::Bundle &bnd) {
++ I *typedSvc = static_cast<I*>(voidSvc);
++ removeWithOwner(typedSvc, props, bnd);
++ };
++ entry.functions->removeWithOwner = voidfunc;
++ entry.cOpts.removeWithOwner = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
++ auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++ celix::Properties props = createFromCProps(c_props);
++ auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
++ celix::impl::BundleImpl bnd{m_bnd};
++ (fentry->removeWithOwner)(svc, props, bnd);
++ };
++ }
++
++ entry.cOpts.filter.serviceName = opts.filter.serviceName.c_str();
++ entry.cOpts.filter.serviceLanguage = opts.filter.serviceLanguage.c_str();
++ entry.cOpts.filter.versionRange = opts.filter.versionRange.c_str();
++ entry.cOpts.filter.filter = opts.filter.filter.c_str();
++
++ entry.cOpts.callbackHandle = entry.functions.get();
++
++ return this->pimpl->trackServicesInternal(std::move(entry));
++}
++
++template<typename I>
++bool celix::BundleContext::useServiceWithId(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{")"};
++ //TODO use useServiceWithOptions return this->useService<I>(serviceName, "", filter, use);
++ return false;
++}
++
++template<typename I>
++bool celix::BundleContext::useService(const std::string &serviceName, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
++ return this->pimpl->useServiceInternal(serviceName, [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 celix::BundleContext::useServices(const std::string &serviceName, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
++ this->pimpl->useServicesInternal(serviceName, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) {
++ I *typedSvc = static_cast<I*>(voidSvc);
++ use(*typedSvc, props, svcOwner);
++ });
++}
++
++
++#endif //CELIX_IMPL_BUNDLECONTEXTIMPL_H
http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/impl/BundleImpl.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/impl/BundleImpl.h
index 0000000,0000000..e56a5b7
new file mode 100644
--- /dev/null
+++ b/libs/framework/include/celix/impl/BundleImpl.h
@@@ -1,0 -1,0 +1,180 @@@
++/**
++ *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"
++#include "celix_bundle_context.h"
++
++namespace celix {
++
++ //forward declaration
++
++ namespace impl {
++ class BundleImpl : public celix::Bundle {
++ public:
++ BundleImpl(celix_bundle_context_t *c_ctx) : c_bnd(nullptr) {
++ bundleContext_getBundle(c_ctx, &this->c_bnd);
++ }
++
++ BundleImpl(celix_bundle_t *b) : c_bnd(b) {
++ }
++
++ virtual ~BundleImpl() {
++ //no need to destroy the c bundle context -> done by c framework
++ this->c_bnd = nullptr;
++ }
++
++ BundleImpl(const BundleImpl&) = delete;
++ BundleImpl& operator=(const BundleImpl&) = delete;
++
++ BundleImpl(BundleImpl&& rhs) : c_bnd{nullptr} {
++ using std::swap;
++ swap(this->c_bnd, rhs.c_bnd);
++ }
++
++ BundleImpl& operator=(BundleImpl&& rhs) {
++ using std::swap;
++ swap(this->c_bnd, rhs.c_bnd);
++ return *this;
++ }
++
++ 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
++ }
++
++ 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;
++ };
++ }
++}
++
++#endif //CELIX_IMPL_BUNDLEIMPL_H
http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/impl/FrameworkImpl.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/impl/FrameworkImpl.h
index 0000000,0000000..45e5ea5
new file mode 100644
--- /dev/null
+++ b/libs/framework/include/celix/impl/FrameworkImpl.h
@@@ -1,0 -1,0 +1,127 @@@
++/**
++ *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_IMPL_FRAMEWORKIMPL_H
++#define CXX_CELIX_IMPL_FRAMEWORKIMPL_H
++
++#include "celix_framework_factory.h"
++#include "framework.h"
++
++#include "celix/impl/BundleContextImpl.h"
++#include "celix/impl/BundleImpl.h"
++
++namespace celix {
++
++ namespace impl {
++
++ class FrameworkImpl : public celix::Framework {
++ public:
++ FrameworkImpl(celix_bundle_context_t *c_ctx) : owner(false) {
++ bundleContext_getFramework(c_ctx, &this->c_fwm);
++ this->setFrameworkContext();
++ }
++
++ FrameworkImpl(framework_t *c_fw) : owner(false) {
++ //wrapper framework
++ this->c_fwm = c_fw;
++ //assume started framework
++ this->setFrameworkContext();
++ }
++
++ FrameworkImpl(const FrameworkImpl&) = delete;
++ FrameworkImpl& operator=(const FrameworkImpl&) = delete;
++ FrameworkImpl(FrameworkImpl&&) = delete;
++ FrameworkImpl& operator=(FrameworkImpl&&) = delete;
++
++ FrameworkImpl(celix::Properties config) : owner(true) {
++ //framework which also owns the underlining c framework
++ auto c_config = properties_create();
++ for (auto &pair : config) {
++ properties_set(c_config, pair.first.c_str(), pair.second.c_str());
++ }
++ this->c_fwm = frameworkFactory_newFramework(c_config); //should be started
++
++ this->setFrameworkContext();
++ };
++
++ virtual ~FrameworkImpl() {
++ if (this->owner && this->c_fwm != nullptr) {
++ framework_stop(this->c_fwm);
++ framework_waitForStop(this->c_fwm);
++ framework_destroy(this->c_fwm);
++ }
++ }
++
++ virtual void start() noexcept override {
++ framework_start(this->c_fwm);
++ }
++
++ virtual void stop() noexcept override {
++ framework_stop(this->c_fwm);
++ }
++
++ virtual void waitForStop() noexcept override {
++ framework_waitForStop(this->c_fwm);
++ }
++ //TODO also in c virtual void breakWaitForStops() noexcept = 0;
++
++ std::string getUUID() const noexcept override {
++ //TODO return std::string{celix_framework_getUUID(this->c_fwm)};
++ return "TODO";
++ }
++
++ celix::BundleContext& getFrameworkContext() noexcept override {
++ BundleContext &ctx = this->bundleContextsCache.at(0);
++ return ctx;
++ }
++
++ celix::Bundle& getFrameworkBundle() noexcept override {
++ if (this->fwBundle.size() == 0) {
++ celix_bundle_t* c_bnd = nullptr;
++ framework_getFrameworkBundle(this->c_fwm, &c_bnd);
++ this->fwBundle.emplace_back(c_bnd);
++
++ }
++ return this->fwBundle[0];
++ }
++
++ private:
++
++ void setFrameworkContext() {
++ //create and set framework bundle context (replace invalid bundle context)
++ bundle_t *fwmBundle = nullptr;
++ bundle_context_t *fwmCtx = nullptr;
++ framework_getFrameworkBundle(this->c_fwm, &fwmBundle);
++ bundle_getContext(fwmBundle, &fwmCtx);
++ this->bundleContextsCache.emplace(std::piecewise_construct,
++ std::forward_as_tuple(0L),
++ std::forward_as_tuple(fwmCtx, *this));
++ }
++
++
++ bool owner;
++ framework_t *c_fwm{nullptr};
++ std::map<long,celix::BundleContext> bundleContextsCache{};
++ std::vector<celix::impl::BundleImpl> fwBundle{}; //optional entry
++
++ };
++ }
++}
++
++#endif //CXX_CELIX_IMPL_FRAMEWORKIMPL_H