Merge branch 'develop' into feature/CELIX-426-cxx-api
Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/8464f3d5 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/8464f3d5 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/8464f3d5 Branch: refs/heads/feature/CELIX-426-cxx-api Commit: 8464f3d5c653af8076fc76e45c4b6f6ddf9b5e24 Parents: e3339ca 03df0ed Author: Pepijn Noltes <[email protected]> Authored: Mon May 14 19:45:56 2018 +0200 Committer: Pepijn Noltes <[email protected]> Committed: Mon May 14 19:45:56 2018 +0200 ---------------------------------------------------------------------- examples/celix-examples/CMakeLists.txt | 8 +- .../best_practice_example_c/CMakeLists.txt | 40 + .../best_practice_example_c/api/example.h | 34 + .../best_practice_example_c/bar/CMakeLists.txt | 39 + .../bar/private/include/bar.h | 32 + .../bar/private/src/bar.c | 58 + .../bar/private/src/bar_activator.c | 70 + .../best_practice_example_c/foo1/CMakeLists.txt | 39 + .../foo1/private/include/foo1.h | 36 + .../foo1/private/src/foo1.c | 102 + .../foo1/private/src/foo1_activator.c | 88 + .../best_practice_example_c/foo2/CMakeLists.txt | 39 + .../foo2/private/include/foo2.h | 36 + .../foo2/private/src/foo2.c | 113 + .../foo2/private/src/foo2_activator.c | 88 + .../services_example_c/CMakeLists.txt | 83 +- .../celix-examples/services_example_c/README.md | 58 + .../services_example_c/api/example.h | 34 - .../services_example_c/api/example_calc.h | 33 + .../services_example_c/bar/CMakeLists.txt | 39 - .../bar/private/include/bar.h | 32 - .../services_example_c/bar/private/src/bar.c | 58 - .../bar/private/src/bar_activator.c | 70 - .../services_example_c/foo1/CMakeLists.txt | 39 - .../foo1/private/include/foo1.h | 36 - .../services_example_c/foo1/private/src/foo1.c | 102 - .../foo1/private/src/foo1_activator.c | 88 - .../services_example_c/foo2/CMakeLists.txt | 39 - .../foo2/private/include/foo2.h | 36 - .../services_example_c/foo2/private/src/foo2.c | 113 - .../foo2/private/src/foo2_activator.c | 88 - .../src/dynamic_consumer_example.c | 187 ++ .../src/dynamic_provider_example.c | 133 + .../src/simple_consumer_example.c | 85 + .../src/simple_provider_example.c | 73 + framework/include/bundle.h | 115 +- framework/include/bundle_activator.h | 1 + framework/include/bundle_context.h | 640 +---- framework/include/celix/dm/DependencyManager.h | 80 +- framework/include/celix_api.h | 13 +- framework/include/celix_bundle.h | 139 +- framework/include/celix_bundle_context.h | 691 +++++ framework/include/celix_service_factory.h | 44 + framework/include/celix_types.h | 2 + framework/include/service_factory.h | 22 +- framework/include/service_registry.h | 14 +- framework/include/service_tracker.h | 9 +- framework/private/mock/bundle_context_mock.c | 59 +- framework/private/mock/framework_mock.c | 10 +- .../private/mock/service_registration_mock.c | 17 + framework/private/mock/service_registry_mock.c | 18 + .../private/test/service_registration_test.cpp | 9 +- framework/src/BundleImpl.c | 8 +- framework/src/bundle_context.c | 167 +- framework/src/bundle_context_private.h | 3 +- framework/src/bundle_private.h | 9 +- framework/src/framework.c | 2566 +++++++++--------- framework/src/framework_private.h | 5 +- framework/src/service_registration.c | 65 +- framework/src/service_registration_private.h | 22 +- framework/src/service_registry.c | 29 +- framework/src/service_registry_private.h | 2 +- framework/src/service_tracker.c | 65 +- framework/tst/bundle_context_bundles_tests.cpp | 4 +- framework/tst/bundle_context_services_test.cpp | 147 +- shell/src/activator.c | 12 +- shell/src/dm_shell_list_command.c | 2 +- utils/include/array_list.h | 36 +- utils/include/celix_array_list.h | 84 + utils/include/celix_properties.h | 78 + utils/include/properties.h | 40 - utils/src/array_list.c | 157 +- utils/src/array_list_private.h | 2 +- utils/src/properties.c | 1 + 74 files changed, 4533 insertions(+), 3102 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/examples/celix-examples/CMakeLists.txt ---------------------------------------------------------------------- diff --cc examples/celix-examples/CMakeLists.txt index bd70065,2ade793..426e854 --- a/examples/celix-examples/CMakeLists.txt +++ b/examples/celix-examples/CMakeLists.txt @@@ -21,16 -21,14 +21,18 @@@ else ( set(EXAMPLES true) #celix_subproject is only available in the celix project -> using examples dir in other project is also supported endif () if (EXAMPLES) - add_subdirectory(hello_world) - add_subdirectory(hello_world_test) + add_subdirectory(bundle_example_cxx) + add_subdirectory(services_example_c) + add_subdirectory(services_example_cxx) + - add_subdirectory(hello_world) - add_subdirectory(hello_world_test) - add_subdirectory(services_example_c) + add_subdirectory(best_practice_example_c) - add_subdirectory(services_example_cxx) + add_subdirectory(best_practice_example_cxx) + ++ add_subdirectory(hello_world) ++ add_subdirectory(hello_world_test) + add_subdirectory(dm_example) add_subdirectory(dm_example_cxx) http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/include/bundle.h ---------------------------------------------------------------------- diff --cc framework/include/bundle.h index d33a96d,b105615..95ba61f --- a/framework/include/bundle.h +++ b/framework/include/bundle.h @@@ -16,5 -16,125 +16,118 @@@ *specific language governing permissions and limitations *under the License. */ -/* - * bundle.h - * - * \date Mar 23, 2010 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - #include "celix_bundle.h" + #ifndef BUNDLE_H_ + #define BUNDLE_H_ + + #include "celix_types.h" + + #include "celix_errno.h" + #include "bundle_state.h" + #include "bundle_archive.h" + #include "framework.h" + #include "wire.h" + #include "module.h" + #include "service_reference.h" + #include "bundle_context.h" + #include "celix_log.h" + #include "celix_threads.h" + + #ifdef __cplusplus + extern "C" { + #endif + + FRAMEWORK_EXPORT celix_status_t bundle_create(bundle_pt *bundle); + + FRAMEWORK_EXPORT celix_status_t + bundle_createFromArchive(bundle_pt *bundle, framework_pt framework, bundle_archive_pt archive); + + FRAMEWORK_EXPORT celix_status_t bundle_destroy(bundle_pt bundle); + + FRAMEWORK_EXPORT celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle); + + FRAMEWORK_EXPORT celix_status_t bundle_getArchive(bundle_pt bundle, bundle_archive_pt *archive); + + FRAMEWORK_EXPORT celix_status_t bundle_getCurrentModule(bundle_pt bundle, module_pt *module); + + FRAMEWORK_EXPORT array_list_pt bundle_getModules(bundle_pt bundle); + + FRAMEWORK_EXPORT void *bundle_getHandle(bundle_pt bundle); + + FRAMEWORK_EXPORT void bundle_setHandle(bundle_pt bundle, void *handle); + + FRAMEWORK_EXPORT activator_pt bundle_getActivator(bundle_pt bundle); + + FRAMEWORK_EXPORT celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator); + + FRAMEWORK_EXPORT celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context); + + FRAMEWORK_EXPORT celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context); + + FRAMEWORK_EXPORT celix_status_t bundle_getEntry(bundle_pt bundle, const char *name, char **entry); + + FRAMEWORK_EXPORT celix_status_t bundle_start(bundle_pt bundle); + + FRAMEWORK_EXPORT celix_status_t bundle_startWithOptions(bundle_pt bundle, int options); + + FRAMEWORK_EXPORT celix_status_t bundle_update(bundle_pt bundle, const char *inputFile); + + FRAMEWORK_EXPORT celix_status_t bundle_stop(bundle_pt bundle); + + FRAMEWORK_EXPORT celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options); + + FRAMEWORK_EXPORT celix_status_t bundle_uninstall(bundle_pt bundle); + + FRAMEWORK_EXPORT celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state); + + FRAMEWORK_EXPORT celix_status_t bundle_setPersistentStateInactive(bundle_pt bundle); + + FRAMEWORK_EXPORT celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle); + + FRAMEWORK_EXPORT void uninstallBundle(bundle_pt bundle); + + FRAMEWORK_EXPORT celix_status_t bundle_revise(bundle_pt bundle, const char *location, const char *inputFile); + + FRAMEWORK_EXPORT celix_status_t bundle_addModule(bundle_pt bundle, module_pt module); + + FRAMEWORK_EXPORT celix_status_t bundle_closeModules(bundle_pt bundle); + + // Service Reference Functions + FRAMEWORK_EXPORT array_list_pt getUsingBundles(service_reference_pt reference); + + FRAMEWORK_EXPORT int compareTo(service_reference_pt a, service_reference_pt b); + + FRAMEWORK_EXPORT celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state); + + FRAMEWORK_EXPORT celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable); + + FRAMEWORK_EXPORT celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread); + + FRAMEWORK_EXPORT celix_status_t bundle_lock(bundle_pt bundle, bool *locked); + + FRAMEWORK_EXPORT celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked); + + FRAMEWORK_EXPORT celix_status_t bundle_closeAndDelete(bundle_pt bundle); + + FRAMEWORK_EXPORT celix_status_t bundle_close(bundle_pt bundle); + + FRAMEWORK_EXPORT celix_status_t bundle_refresh(bundle_pt bundle); + + FRAMEWORK_EXPORT celix_status_t bundle_getBundleId(bundle_pt bundle, long *id); + + FRAMEWORK_EXPORT celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt *list); + + FRAMEWORK_EXPORT celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list); + + FRAMEWORK_EXPORT celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework); + + FRAMEWORK_EXPORT celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework); + + FRAMEWORK_EXPORT celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location); + + + #ifdef __cplusplus + } + #endif + + #endif /* BUNDLE_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/include/bundle_context.h ---------------------------------------------------------------------- diff --cc framework/include/bundle_context.h index 3611e23,cf42314..74f904e --- a/framework/include/bundle_context.h +++ b/framework/include/bundle_context.h @@@ -40,546 -41,129 +41,129 @@@ #ifdef __cplusplus extern "C" { #endif -- --celix_status_t --bundleContext_create(framework_pt framework, framework_logger_pt, bundle_pt bundle, bundle_context_pt *bundle_context); -- --celix_status_t bundleContext_destroy(bundle_context_pt context); -- --FRAMEWORK_EXPORT celix_status_t bundleContext_getBundle(bundle_context_pt context, bundle_pt *bundle); -- --FRAMEWORK_EXPORT celix_status_t bundleContext_getFramework(bundle_context_pt context, framework_pt *framework); -- --FRAMEWORK_EXPORT celix_status_t --bundleContext_installBundle(bundle_context_pt context, const char *location, bundle_pt *bundle); -- --FRAMEWORK_EXPORT celix_status_t --bundleContext_installBundle2(bundle_context_pt context, const char *location, const char *inputFile, bundle_pt *bundle); -- --FRAMEWORK_EXPORT celix_status_t --bundleContext_registerService(bundle_context_pt context, const char *serviceName, const void *svcObj, -- properties_pt properties, service_registration_pt *service_registration); -- --FRAMEWORK_EXPORT celix_status_t --bundleContext_registerServiceFactory(bundle_context_pt context, const char *serviceName, service_factory_pt factory, -- properties_pt properties, service_registration_pt *service_registration); -- --/** -- * Get a service reference for the bundle context. When the service reference is no longer needed use bundleContext_ungetServiceReference. -- * ServiceReference are coupled to a bundle context. Do not share service reference between bundles. Exchange the service.id instead. -- * -- * @param context The bundle context -- * @param serviceName The name of the service (objectClass) to get -- * @param service_reference _output_ The found service reference, or NULL when no service is found. -- * @return CELIX_SUCCESS on success -- */ --FRAMEWORK_EXPORT celix_status_t bundleContext_getServiceReference(bundle_context_pt context, const char *serviceName, -- service_reference_pt *service_reference); -- --/** Same as bundleContext_getServiceReference, but than for a optional serviceName combined with a optional filter. -- * The resulting array_list should be destroyed by the caller. For all service references return a unget should be called. -- * -- * @param context the bundle context -- * @param serviceName the serviceName, can be NULL -- * @param filter the filter, can be NULL. If present will be combined (and) with the serviceName -- * @param service_references _output_ a array list, can be size 0. -- * @return CELIX_SUCCESS on success -- */ --FRAMEWORK_EXPORT celix_status_t --bundleContext_getServiceReferences(bundle_context_pt context, const char *serviceName, const char *filter, -- array_list_pt *service_references); -- --/** -- * Retains (increases the ref count) the provided service reference. Can be used to retain a service reference. -- * Note that this is a deviation from the OSGi spec, due to the fact that C has no garbage collect. -- * -- * @param context the bundle context -- * @param reference the service reference to retain -- * @return CELIX_SUCCES on success -- */ --FRAMEWORK_EXPORT celix_status_t --bundleContext_retainServiceReference(bundle_context_pt context, service_reference_pt reference); -- --/** -- * Ungets the service references. If the ref counter of the service refernce goes to 0, the reference will be destroyed. -- * This is coupled with the bundleContext_getServiceReference(s) and bundleContext_retainServiceReferenc. -- * Note: That this is a deviation from the OSGi standard, due to the fact that C has no garbage collect. -- * -- * @param context The bundle context. -- * @param reference the service reference to unget -- * @return CELIX_SUCCESS on success. -- */ --FRAMEWORK_EXPORT celix_status_t --bundleContext_ungetServiceReference(bundle_context_pt context, service_reference_pt reference); -- --FRAMEWORK_EXPORT celix_status_t --bundleContext_getService(bundle_context_pt context, service_reference_pt reference, void **service_instance); -- --FRAMEWORK_EXPORT celix_status_t --bundleContext_ungetService(bundle_context_pt context, service_reference_pt reference, bool *result); -- --FRAMEWORK_EXPORT celix_status_t bundleContext_getBundles(bundle_context_pt context, array_list_pt *bundles); -- --FRAMEWORK_EXPORT celix_status_t bundleContext_getBundleById(bundle_context_pt context, long id, bundle_pt *bundle); -- --FRAMEWORK_EXPORT celix_status_t --bundleContext_addServiceListener(bundle_context_pt context, service_listener_pt listener, const char *filter); -- --FRAMEWORK_EXPORT celix_status_t --bundleContext_removeServiceListener(bundle_context_pt context, service_listener_pt listener); -- --FRAMEWORK_EXPORT celix_status_t bundleContext_addBundleListener(bundle_context_pt context, bundle_listener_pt listener); -- --FRAMEWORK_EXPORT celix_status_t --bundleContext_removeBundleListener(bundle_context_pt context, bundle_listener_pt listener); -- --FRAMEWORK_EXPORT celix_status_t --bundleContext_addFrameworkListener(bundle_context_pt context, framework_listener_pt listener); -- --FRAMEWORK_EXPORT celix_status_t --bundleContext_removeFrameworkListener(bundle_context_pt context, framework_listener_pt listener); -- --/** -- * Gets the config property - or environment variable if the config property does not exist - for the provided name. -- * -- * @param context The bundle context. -- * @param name The name of the config property / environment variable to get. -- * @param value A ptr to the output value. This will be set when a value is found or else will be set to NULL. -- * @return 0 if successful. -- */ --FRAMEWORK_EXPORT celix_status_t --bundleContext_getProperty(bundle_context_pt context, const char *name, const char **value); -- --/** -- * Gets the config property - or environment variable if the config property does not exist - for the provided name. -- * -- * @param context The bundle context. -- * @param name The name of the config property / environment variable to get. -- * @param defaultValue The default value to return if no value is found. -- * @param value A ptr to the output value. This will be set when a value is found or else will be set to NULL. -- * @return 0 if successful. -- */ --FRAMEWORK_EXPORT celix_status_t --bundleContext_getPropertyWithDefault(bundle_context_pt context, const char *name, const char *defaultValue, const char **value); - - - - - - - - - - - - - - - - - - - - - - /********************************************************************************************************************** - ********************************************************************************************************************** - * Updated API - ********************************************************************************************************************** - **********************************************************************************************************************/ - - /** - * Gets the dependency manager for this bundle context. - * - * @return the dependency manager or NULL if unsuccessful. - */ - dm_dependency_manager_t* celix_bundleContext_getDependencyManager(celix_bundle_context_t *ctx); - - /** - * Register a C lang service to the framework. - * - * @param ctx The bundle context - * @param serviceName the service name, cannot be NULL - * @param svc the service object. Normally a pointer to a service struct (e.g. a struct with function pointers) - * @param properties The meta properties assiated with the service. The service registration will take ownership of the properties (e.g. no destroy needed) - * @return The serviceId, which should be >= 0. If < 0 then the registration was unsuccessful. - */ - long celix_bundleContext_registerService(celix_bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, celix_properties_t *properties); - - /** - * Register a service for the specified language to the framework. - * - * @param ctx The bundle context - * @param serviceName the service name, cannot be NULL - * @param svc the service object. Normally a pointer to a service struct (e.g. a struct with function pointers) - * @param properties The meta properties assiated with the service. The service registration will take ownership of the properties - * @return The serviceId, which should >= 0. If < 0 then the registration was unsuccessful. - */ - long celix_bundleContext_registerServiceForLang(celix_bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, const char* lang, celix_properties_t *properties); - - //TODO register service factory - - /** - * Unregister the service with service id. The service will only be unregistered if the bundle of the bundle context - * is the owner of the service. - * - * Will log an error if service id is unknown. Will silently ignore services ids < 0. - * - * @param ctx The bundle context - * @param serviceId The service id - */ - void celix_bundleContext_unregisterService(celix_bundle_context_t *ctx, long serviceId); - - /** - * track service for the provided serviceName and/or filter. - * The highest ranking services will used for the callback. - * If a new and higher ranking services the callback with be called again with the new service. - * If a service is removed a the callback with be called with next highest ranking service or NULL as service. - * - * @param ctx The bundle context. - * @param serviceName The required service name to track - * @param versionRange Optional the service version range to track - * @param filter Optional the LDAP filter to use - * @param callbackHandle The data pointer, which will be used in the callbacks - * @param set is a required callback, which will be called when a new highest ranking service is set. - * @return the tracker id or < 0 if unsuccessful. - */ - long celix_bundleContext_trackService( - celix_bundle_context_t* ctx, - const char* serviceName, - void* callbackHandle, - void (*set)(void* handle, void* svc) - ); - - /** - * track services for the provided serviceName and/or filter. - * - * @param ctx The bundle context. - * @param serviceName The required service name to track - * @param versionRange Optional the service version range to track - * @param filter Optional the LDAP filter to use - * @param callbackHandle The data pointer, which will be used in the callbacks - * @param add is a required callback, which will be called when a service is added and initially for the existing service. - * @param remove is a required callback, which will be called when a service is removed - * @return the tracker id or < 0 if unsuccessful. - */ - long celix_bundleContext_trackServices( - celix_bundle_context_t* ctx, - const char* serviceName, - void* callbackHandle, - void (*add)(void* handle, void* svc), - void (*remove)(void* handle, void* svc) - ); - - typedef struct celix_service_tracker_options { - //service filter options - const char* serviceName; - const char* versionRange; - const char* filter; - const char* lang; //NULL -> 'CELIX_LANG_C' - - //callback options - void* callbackHandle; - - void (*set)(void *handle, void *svc); //highest ranking - void (*add)(void *handle, void *svc); - void (*remove)(void *handle, void *svc); - void (*modified)(void *handle, void *svc); - - void (*setWithProperties)(void *handle, void *svc, const celix_properties_t *props); //highest ranking - void (*addWithProperties)(void *handle, void *svc, const celix_properties_t *props); - void (*removeWithProperties)(void *handle, void *svc, const celix_properties_t *props); - void (*modifiedWithProperties)(void *handle, void *svc, const celix_properties_t *props); - - void (*setWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); //highest ranking - void (*addWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); - void (*removeWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); - void (*modifiedWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); - } celix_service_tracking_options_t; - - /** - * Tracks services using the provided tracker options. - * The tracker options are only using during this call and can safely be freed/reused after this call returns. - * - * @param ctx The bundle context. - * @param opts The pointer to the tracker options. - * @return the tracker id or < 0 if unsuccessful. - */ - long celix_bundleContext_trackServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_tracking_options_t *opts); - - - //TODO find services -> list of service ids. - celix_array_list_t* celix_bundleContext_findServices( - celix_bundle_context_t *ctx, - const char *serviceName, - const char *versionRange, - const char *filter, - const char *lang - ); - - /** - * Get and lock the service with the provided service id - * Invokes the provided callback with the found service. - * The svc, props and owner in the callback are only valid during the callback. - * If no service is found the callback will not be invoked - * - * This function will block till the callback is finished. As result it is possible to provide callback data from the - * stack. - * - * @param ctx The bundle context - * @param serviceId the service id. - * @param serviceName the service name of the service. Should match with the registered service name of the provided service id (sanity check) - * @param callbackHandle The data pointer, which will be used in the callbacks - * @param use The callback, which will be called when service is retrieved. - * @param bool returns true if a service was found. - */ - bool celix_bundleContext_useServiceWithId( - celix_bundle_context_t *ctx, - long serviceId, - const char *serviceName /*sanity check*/, - void *callbackHandle, - void (*use)(void *handle, void* svc, const celix_properties_t *props, const celix_bundle_t *svcOwner) - ); - - /** - * Get and lock the current highest ranking service conform serviceName, versionRange an filter. - * Invokes the provided callback with the found service. - * The svc, props and owner in the callback are only valid during the callback. - * If no service is found the callback will not be invoked. - * - * This function will block till the callback is finished. As result it is possible to provide callback data from the - * stack. - * - * @param ctx The bundle context - * @param serviceName the required service name. - * @param callbackHandle The data pointer, which will be used in the callbacks - * @param use The callback, which will be called when service is retrieved. - * @return True if a service was found. - */ - bool celix_bundleContext_useService( - celix_bundle_context_t *ctx, - const char* serviceName, - void *callbackHandle, - void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner) - ); - - /** - * Get and lock the current services conform serviceName, versionRange an filter. - * Invokes the provided callback with the found services. - * The svc, props and owner in the callback are only valid during the callback. - * If no services are found the callback will not be invoked. - * - * This function will block till the callback is finished. As result it is possible to provide callback data from the - * stack. - * - * @param ctx The bundle context - * @param serviceName the required service name. - * @param serviceRange the optional service version range (e.g. '[1.0.0,2.0.0)' ) - * @param filter the optional filter. - * @param callbackHandle The data pointer, which will be used in the callbacks - * @param use The callback, which will be called for every service found. - */ - void celix_bundleContext_useServices( - celix_bundle_context_t *ctx, - const char* serviceName, - void *callbackHandle, - void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner) - ); -- -- - typedef struct celix_service_use_options { ++ ++ celix_status_t ++ bundleContext_create(framework_pt framework, framework_logger_pt, bundle_pt bundle, bundle_context_pt *bundle_context); ++ ++ celix_status_t bundleContext_destroy(bundle_context_pt context); ++ ++ FRAMEWORK_EXPORT celix_status_t bundleContext_getBundle(bundle_context_pt context, bundle_pt *bundle); ++ ++ FRAMEWORK_EXPORT celix_status_t bundleContext_getFramework(bundle_context_pt context, framework_pt *framework); ++ ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_installBundle(bundle_context_pt context, const char *location, bundle_pt *bundle); ++ ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_installBundle2(bundle_context_pt context, const char *location, const char *inputFile, bundle_pt *bundle); ++ ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_registerService(bundle_context_pt context, const char *serviceName, const void *svcObj, ++ properties_pt properties, service_registration_pt *service_registration); ++ ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_registerServiceFactory(bundle_context_pt context, const char *serviceName, service_factory_pt factory, ++ properties_pt properties, service_registration_pt *service_registration); ++ + /** - * service filter options. Note the serviceName is required. ++ * Get a service reference for the bundle context. When the service reference is no longer needed use bundleContext_ungetServiceReference. ++ * ServiceReference are coupled to a bundle context. Do not share service reference between bundles. Exchange the service.id instead. ++ * ++ * @param context The bundle context ++ * @param serviceName The name of the service (objectClass) to get ++ * @param service_reference _output_ The found service reference, or NULL when no service is found. ++ * @return CELIX_SUCCESS on success + */ - const char *serviceName; //REQUIRED - const char *versionRange; //default will be empty - const char *filter; //default will be empty - const char *lang; //default will be LANG_C - - /** - * Callback info ++ FRAMEWORK_EXPORT celix_status_t bundleContext_getServiceReference(bundle_context_pt context, const char *serviceName, ++ service_reference_pt *service_reference); ++ ++ /** Same as bundleContext_getServiceReference, but than for a optional serviceName combined with a optional filter. ++ * The resulting array_list should be destroyed by the caller. For all service references return a unget should be called. ++ * ++ * @param context the bundle context ++ * @param serviceName the serviceName, can be NULL ++ * @param filter the filter, can be NULL. If present will be combined (and) with the serviceName ++ * @param service_references _output_ a array list, can be size 0. ++ * @return CELIX_SUCCESS on success + */ - void *callbackHandle; - void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); - } celix_service_use_options_t; - - /** - * Get and lock the current highest ranking service conform the service filter info from the provided options. - * - * Invokes the provided callback with the found service. - * The svc, props and owner in the callback are only valid during the callback. - * If no service is found the callback will not be invoked. - * - * This function will block till the callback is finished. As result it is possible to provide callback data from the - * stack. - * - * @param ctx The bundle context. - * @param serviceName the required service name. - * @param opts The required options. Note that the serviceName is required. - * @return True if a service was found. - */ - bool celix_bundleContext_useServiceWithOptions( - celix_bundle_context_t *ctx, - const celix_service_use_options_t *opts); - - - /** - * Get and lock the current services conform the service filter info from the provided options. - * - * Invokes the provided callback with the found services. - * The svc, props and owner in the callback are only valid during the callback. - * If no services are found the callback will not be invoked. - * At least a serviceName needs to be provided, if not the callback is not invoked. - * - * This function will block till all the callbacks are finished. As result it is possible to provide callback data from the - * stack. - * - * @param ctx The bundle context. - * @param serviceName the required service name. - * @param opts The required options. Note that the serviceName is required. - * @param callbackHandle The data pointer, which will be used in the callbacks. - * @param use The callback, which will be called for every service found. - */ - void celix_bundleContext_useServicesWithOptions( - celix_bundle_context_t *ctx, - const celix_service_use_options_t *opts); - - - /** - * Install and optional start a bundle. - * - * @param ctx The bundle context - * @param bundleLoc The bundle location to the bundle zip file. - * @param autoStart If the bundle should also be started. - * @return the bundleId >= 0 or < 0 if the bundle could not be installed and possibly started. - */ - long celix_bundleContext_installBundle(celix_bundle_context_t *ctx, const char *bundleLoc, bool autoStart); - - /** - * Uninstall the bundle with the provided bundle id. If needed the bundle will be stopped first. - * - * @param ctx The bundle context - * @param bundleId The bundle id to stop - * @return true if the bundle is correctly uninstalled. False if not. - */ - bool celix_bundleContext_uninstallBundle(celix_bundle_context_t *ctx, long bundleId); - - - /** - * Service tracker options. This struct can be used to fine grained tune the - * requested bundle tracker ootions. - */ - typedef struct celix_bundle_tracker_options { - //TODO options to track framework & own bundle - ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_getServiceReferences(bundle_context_pt context, const char *serviceName, const char *filter, ++ array_list_pt *service_references); ++ + /** - * Handle used in the tracker callbacks. ++ * Retains (increases the ref count) the provided service reference. Can be used to retain a service reference. ++ * Note that this is a deviation from the OSGi spec, due to the fact that C has no garbage collect. ++ * ++ * @param context the bundle context ++ * @param reference the service reference to retain ++ * @return CELIX_SUCCES on success + */ - void* callbackHandle; - ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_retainServiceReference(bundle_context_pt context, service_reference_pt reference); ++ + /** - * Tracker callback when a bundle is installed. - * @param handle The handle, contains the value of the callbackHandle. - * @param bundle The bundle which has been started. - * The bundle pointer is only guaranteed to be valid during the callback. ++ * Ungets the service references. If the ref counter of the service refernce goes to 0, the reference will be destroyed. ++ * This is coupled with the bundleContext_getServiceReference(s) and bundleContext_retainServiceReferenc. ++ * Note: That this is a deviation from the OSGi standard, due to the fact that C has no garbage collect. ++ * ++ * @param context The bundle context. ++ * @param reference the service reference to unget ++ * @return CELIX_SUCCESS on success. + */ - void (*onStarted)(void *handle, const celix_bundle_t *bundle); //highest ranking - ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_ungetServiceReference(bundle_context_pt context, service_reference_pt reference); ++ ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_getService(bundle_context_pt context, service_reference_pt reference, void **service_instance); ++ ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_ungetService(bundle_context_pt context, service_reference_pt reference, bool *result); ++ ++ FRAMEWORK_EXPORT celix_status_t bundleContext_getBundles(bundle_context_pt context, array_list_pt *bundles); ++ ++ FRAMEWORK_EXPORT celix_status_t bundleContext_getBundleById(bundle_context_pt context, long id, bundle_pt *bundle); ++ ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_addServiceListener(bundle_context_pt context, service_listener_pt listener, const char *filter); ++ ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_removeServiceListener(bundle_context_pt context, service_listener_pt listener); ++ ++ FRAMEWORK_EXPORT celix_status_t bundleContext_addBundleListener(bundle_context_pt context, bundle_listener_pt listener); ++ ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_removeBundleListener(bundle_context_pt context, bundle_listener_pt listener); ++ ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_addFrameworkListener(bundle_context_pt context, framework_listener_pt listener); ++ ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_removeFrameworkListener(bundle_context_pt context, framework_listener_pt listener); ++ + /** - * Tracker callback when a bundle is removed. - * @param handle The handle, contains the value of the callbackHandle. - * @param bundle The bundle which has been started. - * The bundle pointer is only guaranteed to be valid during the callback. ++ * Gets the config property - or environment variable if the config property does not exist - for the provided name. ++ * ++ * @param context The bundle context. ++ * @param name The name of the config property / environment variable to get. ++ * @param value A ptr to the output value. This will be set when a value is found or else will be set to NULL. ++ * @return 0 if successful. + */ - void (*onStopped)(void *handle, const celix_bundle_t *bundle); - ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_getProperty(bundle_context_pt context, const char *name, const char **value); ++ + /** ++ * Gets the config property - or environment variable if the config property does not exist - for the provided name. + * - * @param handle The handle, contains the value of the callbackHandle. - * @param event The bundle event. Is only valid during the callback. ++ * @param context The bundle context. ++ * @param name The name of the config property / environment variable to get. ++ * @param defaultValue The default value to return if no value is found. ++ * @param value A ptr to the output value. This will be set when a value is found or else will be set to NULL. ++ * @return 0 if successful. + */ - void (*onBundleEvent)(void *handle, const celix_bundle_event_t *event); - } celix_bundle_tracker_options_t; - - /** - * Tracks bundles using the provided bundle tracker options. - * The tracker options are only using during this call and can safely be freed/reused after this call returns. - * (i.e. can be on the stack) - * - * @param ctx The bundle context. - * @param opts The pointer to the bundle tracker options. - * @return The bundle tracker id or < 0 if unsuccessful. - */ - long celix_bundleContext_trackBundlesWithOptions( - celix_bundle_context_t* ctx, - const celix_bundle_tracker_options_t *opts - ); - - //TODO except framework & own bundle - /** - * track bundles - * The add bundle callback will also be called for already installed bundles. - * - * @param ctx The bundle context. - * @param callbackHandle The data pointer, which will be used in the callbacks - * @param add The callback which will be called for started bundles. - * @param remove The callback which will be called when bundles are stopped. - * @return The bundle tracker id or < 0 if unsuccessful. - */ - long celix_bundleContext_trackBundles( - celix_bundle_context_t* ctx, - void* callbackHandle, - void (*onStarted)(void* handle, const celix_bundle_t *bundle), - void (*onStopped)(void *handle, const celix_bundle_t *bundle) - ); - - /** - * Use the bundle with the provided bundle id if it is in the active (started) state - * The provided callback will be called if the bundle is found and in the active (started) state. - * - * @param ctx The bundle context. - * @param bundleId The bundle id. - * @param callbackHandle The data pointer, which will be used in the callbacks - * @param use The callback which will be called for the currently started bundles. - * The bundle pointers are only guaranteed to be valid during the callback. - */ - bool celix_bundleContext_useBundle( - celix_bundle_context_t *ctx, - long bundleId, - void *callbackHandle, - void (*use)(void *handle, const celix_bundle_t *bundle) - ); - - //TODO except framework & own bundle - /** - * Use the currently active (started) bundles. - * The provided callback will be called for all the currently started bundles. - * - * @param ctx The bundle context. - * @param callbackHandle The data pointer, which will be used in the callbacks - * @param use The callback which will be called for the currently started bundles. - * The bundle pointers are only guaranteed to be valid during the callback. - */ - void celix_bundleContext_useBundles( - celix_bundle_context_t *ctx, - void *callbackHandle, - void (*use)(void *handle, const celix_bundle_t *bundle) - ); - - - //TODO trackerServiceTracker - - /** - * Stop the tracker with the provided track id. - * Could be a service tracker, bundle tracker or service tracker tracker. - * Only works for the trackers owned by the bundle of the bundle context. - * - * Will log a error if the provided tracker id is unknown. Will silently ignore trackerId < 0. - */ - void celix_bundleContext_stopTracker(celix_bundle_context_t *ctx, long trackerId); - - - ++ FRAMEWORK_EXPORT celix_status_t ++ bundleContext_getPropertyWithDefault(bundle_context_pt context, const char *name, const char *defaultValue, const char **value); ++ ++ #ifdef __cplusplus } #endif http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/include/celix/dm/DependencyManager.h ---------------------------------------------------------------------- diff --cc framework/include/celix/dm/DependencyManager.h index e9a74a4,f90a03c..5a4dd99 --- a/framework/include/celix/dm/DependencyManager.h +++ b/framework/include/celix/dm/DependencyManager.h @@@ -31,36 -29,39 +31,36 @@@ #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. * @@@ -68,7 -69,7 +68,7 @@@ */ 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. @@@ -77,7 -78,7 +77,7 @@@ */ 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. @@@ -86,7 -87,7 +86,7 @@@ */ 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. @@@ -95,29 -96,29 +95,29 @@@ */ 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 */ @@@ -125,14 -126,14 +125,14 @@@ 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}; @@@ -141,7 -142,7 +141,7 @@@ dm_dependency_manager_pt cDepMan {nullptr}; std::recursive_mutex componentsMutex{}; }; -- ++ }} #include "celix/dm/DependencyManager_Impl.h" http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/include/celix_bundle.h ---------------------------------------------------------------------- diff --cc framework/include/celix_bundle.h index 6013635,74ea9bf..9b38627 --- a/framework/include/celix_bundle.h +++ b/framework/include/celix_bundle.h @@@ -36,116 -26,19 +26,19 @@@ #ifdef __cplusplus extern "C" { #endif - - FRAMEWORK_EXPORT celix_status_t bundle_create(bundle_pt *bundle); - - FRAMEWORK_EXPORT celix_status_t - bundle_createFromArchive(bundle_pt *bundle, framework_pt framework, bundle_archive_pt archive); - - FRAMEWORK_EXPORT celix_status_t bundle_destroy(bundle_pt bundle); - - FRAMEWORK_EXPORT celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle); - - FRAMEWORK_EXPORT celix_status_t bundle_getArchive(bundle_pt bundle, bundle_archive_pt *archive); - - FRAMEWORK_EXPORT celix_status_t bundle_getCurrentModule(bundle_pt bundle, module_pt *module); - - FRAMEWORK_EXPORT array_list_pt bundle_getModules(bundle_pt bundle); - - FRAMEWORK_EXPORT void *bundle_getHandle(bundle_pt bundle); - - FRAMEWORK_EXPORT void bundle_setHandle(bundle_pt bundle, void *handle); - - FRAMEWORK_EXPORT activator_pt bundle_getActivator(bundle_pt bundle); - - FRAMEWORK_EXPORT celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator); - - FRAMEWORK_EXPORT celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context); - - FRAMEWORK_EXPORT celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context); - - FRAMEWORK_EXPORT celix_status_t bundle_getEntry(bundle_pt bundle, const char *name, char **entry); - - FRAMEWORK_EXPORT celix_status_t bundle_start(bundle_pt bundle); - - FRAMEWORK_EXPORT celix_status_t bundle_startWithOptions(bundle_pt bundle, int options); - - FRAMEWORK_EXPORT celix_status_t bundle_update(bundle_pt bundle, const char *inputFile); - - FRAMEWORK_EXPORT celix_status_t bundle_stop(bundle_pt bundle); - - FRAMEWORK_EXPORT celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options); - - FRAMEWORK_EXPORT celix_status_t bundle_uninstall(bundle_pt bundle); - - FRAMEWORK_EXPORT celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state); - - FRAMEWORK_EXPORT celix_status_t bundle_setPersistentStateInactive(bundle_pt bundle); - - FRAMEWORK_EXPORT celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle); - - FRAMEWORK_EXPORT void uninstallBundle(bundle_pt bundle); - - FRAMEWORK_EXPORT celix_status_t bundle_revise(bundle_pt bundle, const char *location, const char *inputFile); - - FRAMEWORK_EXPORT celix_status_t bundle_addModule(bundle_pt bundle, module_pt module); - - FRAMEWORK_EXPORT celix_status_t bundle_closeModules(bundle_pt bundle); - - // Service Reference Functions - FRAMEWORK_EXPORT array_list_pt getUsingBundles(service_reference_pt reference); - - FRAMEWORK_EXPORT int compareTo(service_reference_pt a, service_reference_pt b); - - FRAMEWORK_EXPORT celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state); - - FRAMEWORK_EXPORT celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable); - - FRAMEWORK_EXPORT celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread); - - FRAMEWORK_EXPORT celix_status_t bundle_lock(bundle_pt bundle, bool *locked); - - FRAMEWORK_EXPORT celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked); - - FRAMEWORK_EXPORT celix_status_t bundle_closeAndDelete(bundle_pt bundle); - - FRAMEWORK_EXPORT celix_status_t bundle_close(bundle_pt bundle); - - FRAMEWORK_EXPORT celix_status_t bundle_refresh(bundle_pt bundle); - - FRAMEWORK_EXPORT celix_status_t bundle_getBundleId(bundle_pt bundle, long *id); - - FRAMEWORK_EXPORT celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt *list); - - FRAMEWORK_EXPORT celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list); - - FRAMEWORK_EXPORT celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework); - - FRAMEWORK_EXPORT celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework); - - FRAMEWORK_EXPORT celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location); - - -- --/********************************************************************************************************************** -- ********************************************************************************************************************** -- * Updated API -- ********************************************************************************************************************** -- **********************************************************************************************************************/ -- --long celix_bundle_getId(const bundle_t *bnd); -- --celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd); -- - /** - * Note returned string pointer is owned by the caller. - * @param bnd - * @param relPath - * @return - */ - char* celix_bundle_getEntry(const bundle_t *bnd, const char *relPath); -- -- ++ ++ /********************************************************************************************************************** ++ ********************************************************************************************************************** ++ * Updated API ++ ********************************************************************************************************************** ++ **********************************************************************************************************************/ ++ ++ long celix_bundle_getId(const bundle_t *bnd); ++ ++ celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd); ++ ++ ++ #ifdef __cplusplus } #endif http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/private/mock/bundle_context_mock.c ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/private/mock/framework_mock.c ---------------------------------------------------------------------- diff --cc framework/private/mock/framework_mock.c index 5aa06d3,7bbd752..86a2791 --- a/framework/private/mock/framework_mock.c +++ b/framework/private/mock/framework_mock.c @@@ -333,7 -333,14 +333,15 @@@ bool celix_framework_useBundle(framewor ->withLongIntParameters("bundleId", bundleId) ->withPointerParameters("callbackHandle", callbackHandle) ->withPointerParameters("use", use); + return mock_c()->returnValue().value.boolValue; } - + service_registration_t* celix_framework_registerServiceFactory(framework_t *fw , const celix_bundle_t *bnd, const char* serviceName, celix_service_factory_t *factory, celix_properties_t *properties) { + mock_c()->actualCall("celix_framework_registerServiceFactory") + ->withPointerParameters("fw", fw) + ->withConstPointerParameters("bnd", bnd) + ->withStringParameters("serviceName", serviceName) + ->withPointerParameters("factory", factory) + ->withPointerParameters("properties", properties); + return mock_c()->returnValue().value.pointerValue; + } http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/src/BundleImpl.c ---------------------------------------------------------------------- diff --cc framework/src/BundleImpl.c index fccabae,0000000..0fcba53 mode 100644,000000..100644 --- a/framework/src/BundleImpl.c +++ b/framework/src/BundleImpl.c @@@ -1,771 -1,0 +1,765 @@@ +/** + *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. + */ - /* - * bundle.c - * - * \date Mar 23, 2010 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ ++ +#include <stdlib.h> +#include <string.h> + +#include "framework_private.h" +#include "bundle_private.h" +#include "resolver.h" +#include "utils.h" + +celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module); +celix_status_t bundle_closeRevisions(bundle_pt bundle); + +celix_status_t bundle_create(bundle_pt * bundle) { + celix_status_t status; + bundle_archive_pt archive = NULL; + + *bundle = (bundle_pt) malloc(sizeof(**bundle)); + if (*bundle == NULL) { + return CELIX_ENOMEM; + } + status = bundleArchive_createSystemBundleArchive(&archive); + if (status == CELIX_SUCCESS) { + module_pt module; + + (*bundle)->archive = archive; + (*bundle)->activator = NULL; + (*bundle)->context = NULL; + (*bundle)->framework = NULL; + (*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED; + (*bundle)->modules = NULL; + arrayList_create(&(*bundle)->modules); + (*bundle)->handle = NULL; + (*bundle)->manifest = NULL; + + module = module_createFrameworkModule((*bundle)); + bundle_addModule(*bundle, module); + + status = celixThreadMutex_create(&(*bundle)->lock, NULL); + if (status != CELIX_SUCCESS) { + status = CELIX_ILLEGAL_STATE; + } else { + (*bundle)->lockCount = 0; + (*bundle)->lockThread = celix_thread_default; + } + } + framework_logIfError(logger, status, NULL, "Failed to create bundle"); + + return status; +} + +celix_status_t bundle_createFromArchive(bundle_pt * bundle, framework_pt framework, bundle_archive_pt archive) { + module_pt module; + + celix_status_t status; + + *bundle = (bundle_pt) malloc(sizeof(**bundle)); + if (*bundle == NULL) { + return CELIX_ENOMEM; + } + (*bundle)->archive = archive; + (*bundle)->activator = NULL; + (*bundle)->context = NULL; + (*bundle)->handle = NULL; + (*bundle)->manifest = NULL; + (*bundle)->framework = framework; + (*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED; + (*bundle)->modules = NULL; + arrayList_create(&(*bundle)->modules); + + status = bundle_createModule(*bundle, &module); + if (status == CELIX_SUCCESS) { + bundle_addModule(*bundle, module); + status = celixThreadMutex_create(&(*bundle)->lock, NULL); + if (status != CELIX_SUCCESS) { + status = CELIX_ILLEGAL_STATE; + } else { + (*bundle)->lockCount = 0; + (*bundle)->lockThread = celix_thread_default; + } + } else { + status = CELIX_FILE_IO_EXCEPTION; + } + + framework_logIfError(logger, status, NULL, "Failed to create bundle"); + + return status; +} + +celix_status_t bundle_destroy(bundle_pt bundle) { + array_list_iterator_pt iter = arrayListIterator_create(bundle->modules); + while (arrayListIterator_hasNext(iter)) { + module_pt module = arrayListIterator_next(iter); + module_destroy(module); + } + arrayListIterator_destroy(iter); + arrayList_destroy(bundle->modules); + celixThreadMutex_destroy(&bundle->lock); + + free(bundle); + + return CELIX_SUCCESS; +} + +celix_status_t bundle_getArchive(bundle_pt bundle, bundle_archive_pt *archive) { + celix_status_t status = CELIX_SUCCESS; + + if (bundle != NULL && *archive == NULL) { + *archive = bundle->archive; + } else { + status = CELIX_ILLEGAL_ARGUMENT; + } + + framework_logIfError(logger, status, NULL, "Failed to get bundle archive"); + + return status; +} + +celix_status_t bundle_getCurrentModule(bundle_pt bundle, module_pt *module) { + celix_status_t status = CELIX_SUCCESS; + + if (bundle == NULL || arrayList_size(bundle->modules)==0 ) { + status = CELIX_ILLEGAL_ARGUMENT; + } else { + *module = arrayList_get(bundle->modules, arrayList_size(bundle->modules) - 1); + } + + return status; +} + +array_list_pt bundle_getModules(bundle_pt bundle) { + return bundle->modules; +} + +void * bundle_getHandle(bundle_pt bundle) { + return bundle->handle; +} + +void bundle_setHandle(bundle_pt bundle, void * handle) { + bundle->handle = handle; +} + +activator_pt bundle_getActivator(bundle_pt bundle) { + return bundle->activator; +} + +celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator) { + bundle->activator = activator; + return CELIX_SUCCESS; +} + +celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context) { + *context = bundle->context; + return CELIX_SUCCESS; +} + +celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context) { + bundle->context = context; + return CELIX_SUCCESS; +} + +celix_status_t bundle_getEntry(bundle_pt bundle, const char* name, char** out) { + char *entry = celix_bundle_getEntry(bundle, name); + if (out != NULL ) { + *out = entry; + } + return CELIX_SUCCESS; +} + +celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state) { + if(bundle==NULL){ + *state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN; + return CELIX_BUNDLE_EXCEPTION; + } + *state = bundle->state; + return CELIX_SUCCESS; +} + +celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state) { + bundle->state = state; + return CELIX_SUCCESS; +} + +celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module) { + celix_status_t status = CELIX_SUCCESS; + bundle_archive_pt archive = NULL; + bundle_revision_pt revision = NULL; + manifest_pt headerMap = NULL; + + status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive)); + status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision)); + status = CELIX_DO_IF(status, bundleRevision_getManifest(revision, &headerMap)); + if (status == CELIX_SUCCESS) { + long bundleId = 0; + status = bundleArchive_getId(bundle->archive, &bundleId); + if (status == CELIX_SUCCESS) { + int revision = 0; + char moduleId[512]; + + snprintf(moduleId, sizeof(moduleId), "%ld.%d", bundleId, revision); + *module = module_create(headerMap, moduleId, bundle); + + if (*module != NULL) { + version_pt bundleVersion = module_getVersion(*module); + const char * symName = NULL; + status = module_getSymbolicName(*module, &symName); + if (status == CELIX_SUCCESS) { + array_list_pt bundles = framework_getBundles(bundle->framework); + unsigned int i; + for (i = 0; i < arrayList_size(bundles); i++) { + bundle_pt check = (bundle_pt) arrayList_get(bundles, i); + + long id; + if (bundleArchive_getId(check->archive, &id) == CELIX_SUCCESS) { + if (id != bundleId) { + module_pt mod = NULL; + const char * sym = NULL; + version_pt version; + int cmp; + status = bundle_getCurrentModule(check, &mod); + status = module_getSymbolicName(mod, &sym); + + version = module_getVersion(mod); + version_compareTo(bundleVersion, version, &cmp); + if ((symName != NULL) && (sym != NULL) && !strcmp(symName, sym) && + !cmp) { + char *versionString = NULL; + version_toString(version, &versionString); + printf("Bundle symbolic name and version are not unique: %s:%s\n", sym, versionString); + free(versionString); + status = CELIX_BUNDLE_EXCEPTION; + break; + } + } + } + } + arrayList_destroy(bundles); + } + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to create module"); + + return status; +} + +celix_status_t bundle_start(bundle_pt bundle) { + return bundle_startWithOptions(bundle, 0); +} + +celix_status_t bundle_startWithOptions(bundle_pt bundle, int options) { + celix_status_t status = CELIX_SUCCESS; + if (bundle != NULL) { + bool systemBundle = false; + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (systemBundle) { + framework_start(bundle->framework); + } else { + status = fw_startBundle(bundle->framework, bundle, options); + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to start bundle"); + + return status; +} + +celix_status_t bundle_update(bundle_pt bundle, const char *inputFile) { + celix_status_t status = CELIX_SUCCESS; + if (bundle != NULL) { + bool systemBundle = false; + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (systemBundle) { + // #TODO: Support framework update + status = CELIX_BUNDLE_EXCEPTION; + } else { + status = framework_updateBundle(bundle->framework, bundle, inputFile); + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to update bundle"); + + return status; +} + +celix_status_t bundle_stop(bundle_pt bundle) { + return bundle_stopWithOptions(bundle, 0); +} + +celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options) { + celix_status_t status = CELIX_SUCCESS; + if (bundle != NULL) { + bool systemBundle = false; + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (systemBundle) { + framework_stop(bundle->framework); + } else { + status = fw_stopBundle(bundle->framework, bundle, options); + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to stop bundle"); + + return status; +} + +celix_status_t bundle_uninstall(bundle_pt bundle) { + celix_status_t status = CELIX_SUCCESS; + if (bundle != NULL) { + bool systemBundle = false; + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (systemBundle) { + status = CELIX_BUNDLE_EXCEPTION; + } else { + status = fw_uninstallBundle(bundle->framework, bundle); + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to uninstall bundle"); + + return status; +} + +celix_status_t bundle_setPersistentStateInactive(bundle_pt bundle) { + celix_status_t status; + bool systemBundle; + + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (!systemBundle) { + status = bundleArchive_setPersistentState(bundle->archive, OSGI_FRAMEWORK_BUNDLE_INSTALLED); + } + } + + framework_logIfError(logger, status, NULL, "Failed to set persistent state to inactive"); + + return status; +} + +celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle) { + celix_status_t status; + bool systemBundle; + + status = bundle_isSystemBundle(bundle, &systemBundle); + if (status == CELIX_SUCCESS) { + if (!systemBundle) { + status = bundleArchive_setPersistentState(bundle->archive, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED); + } + } + + framework_logIfError(logger, status, NULL, "Failed to set persistent state to uninstalled"); + + return status; +} + +celix_status_t bundle_revise(bundle_pt bundle, const char * location, const char *inputFile) { + celix_status_t status; + + bundle_archive_pt archive = NULL; + status = bundle_getArchive(bundle, &archive); + if (status == CELIX_SUCCESS) { + status = bundleArchive_revise(archive, location, inputFile); + if (status == CELIX_SUCCESS) { + module_pt module; + status = bundle_createModule(bundle, &module); + if (status == CELIX_SUCCESS) { + status = bundle_addModule(bundle, module); + } else { + bool rolledback; + status = bundleArchive_rollbackRevise(archive, &rolledback); + if (status == CELIX_SUCCESS) { + status = CELIX_BUNDLE_EXCEPTION; + } + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to revise bundle"); + + return status; +} + +//bool bundle_rollbackRevise(bundle_pt bundle) { +// module_pt module = arrayList_remove(bundle->modules, arrayList_set(bundle->modules) - 1); +// return resolver_removeModule(module); +//} + +celix_status_t bundle_addModule(bundle_pt bundle, module_pt module) { + arrayList_add(bundle->modules, module); + resolver_addModule(module); + return CELIX_SUCCESS; +} + +celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle) { + celix_status_t status; + long bundleId; + bundle_archive_pt archive = NULL; + + status = bundle_getArchive(bundle, &archive); + if (status == CELIX_SUCCESS) { + status = bundleArchive_getId(archive, &bundleId); + if (status == CELIX_SUCCESS) { + *systemBundle = (bundleId == 0); + } + } + + framework_logIfError(logger, status, NULL, "Failed to check if bundle is the systembundle"); + + return status; +} + +celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable) { + celix_status_t status; + + status = celixThreadMutex_lock(&bundle->lock); + if (status != CELIX_SUCCESS) { + status = CELIX_BUNDLE_EXCEPTION; + } else { + bool equals; + status = thread_equalsSelf(bundle->lockThread, &equals); + if (status == CELIX_SUCCESS) { + *lockable = (bundle->lockCount == 0) || (equals); + } + + status = celixThreadMutex_unlock(&bundle->lock); + if (status != CELIX_SUCCESS) { + status = CELIX_BUNDLE_EXCEPTION; + } + } + + framework_logIfError(logger, status, NULL, "Failed to check if bundle is lockable"); + + return status; +} + +celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread) { + celix_status_t status; + + status = celixThreadMutex_lock(&bundle->lock); + if (status != CELIX_SUCCESS) { + status = CELIX_BUNDLE_EXCEPTION; + } else { + *thread = bundle->lockThread; + + status = celixThreadMutex_unlock(&bundle->lock); + if (status != CELIX_SUCCESS) { + status = CELIX_BUNDLE_EXCEPTION; + } + } + + framework_logIfError(logger, status, NULL, "Failed to get locking thread"); + + return status; +} + +celix_status_t bundle_lock(bundle_pt bundle, bool *locked) { + celix_status_t status; + bool equals; + + celixThreadMutex_lock(&bundle->lock); + + status = thread_equalsSelf(bundle->lockThread, &equals); + if (status == CELIX_SUCCESS) { + if ((bundle->lockCount > 0) && !equals) { + *locked = false; + } else { + bundle->lockCount++; + bundle->lockThread = celixThread_self(); + *locked = true; + } + } + + celixThreadMutex_unlock(&bundle->lock); + + framework_logIfError(logger, status, NULL, "Failed to lock bundle"); + + return status; +} + +celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked) { + celix_status_t status = CELIX_SUCCESS; + + bool equals; + + celixThreadMutex_lock(&bundle->lock); + + if (bundle->lockCount == 0) { + *unlocked = false; + } else { + status = thread_equalsSelf(bundle->lockThread, &equals); + if (status == CELIX_SUCCESS) { + if ((bundle->lockCount > 0) && !equals) { + *unlocked = false; + } + else{ + bundle->lockCount--; + if (bundle->lockCount == 0) { + bundle->lockThread = celix_thread_default; + } + *unlocked = true; + } + } + } + + celixThreadMutex_unlock(&bundle->lock); + + framework_logIfError(logger, status, NULL, "Failed to unlock bundle"); + + return status; +} + +celix_status_t bundle_close(bundle_pt bundle) { + bundle_archive_pt archive = NULL; + + celix_status_t status; + + bundle_closeModules(bundle); + bundle_closeRevisions(bundle); + status = bundle_getArchive(bundle, &archive); + if (status == CELIX_SUCCESS) { + bundleArchive_close(archive); + } + + framework_logIfError(logger, status, NULL, "Failed to close bundle"); + + return status; +} + +celix_status_t bundle_closeAndDelete(bundle_pt bundle) { + celix_status_t status; + + bundle_archive_pt archive = NULL; + + bundle_closeModules(bundle); + bundle_closeRevisions(bundle); + status = bundle_getArchive(bundle, &archive); + if (status == CELIX_SUCCESS) { + bundleArchive_closeAndDelete(archive); + } + + framework_logIfError(logger, status, NULL, "Failed to close and delete bundle"); + + return status; +} + +celix_status_t bundle_closeRevisions(bundle_pt bundle) { + celix_status_t status = CELIX_SUCCESS; + + // TODO implement this + return status; +} + +celix_status_t bundle_closeModules(bundle_pt bundle) { + celix_status_t status = CELIX_SUCCESS; + + unsigned int i = 0; + for (i = 0; i < arrayList_size(bundle->modules); i++) { + module_pt module = (module_pt) arrayList_get(bundle->modules, i); + resolver_removeModule(module); + module_setWires(module, NULL); + } + + return status; +} + +celix_status_t bundle_refresh(bundle_pt bundle) { + celix_status_t status; + module_pt module; + + status = bundle_closeModules(bundle); + if (status == CELIX_SUCCESS) { + arrayList_clear(bundle->modules); + status = bundle_createModule(bundle, &module); + if (status == CELIX_SUCCESS) { + status = bundle_addModule(bundle, module); + if (status == CELIX_SUCCESS) { + bundle->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED; + } + } + } + + framework_logIfError(logger, status, NULL, "Failed to refresh bundle"); + + return status; +} + +celix_status_t bundle_getBundleId(bundle_t *bundle, long *bndId) { + celix_status_t status = CELIX_SUCCESS; + long id = celix_bundle_getId(bundle); + if (id >= 0) { + *bndId = id; + } else { + status = CELIX_BUNDLE_EXCEPTION; + *bndId = -1; + } + return status; +} + +celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt *list) { + celix_status_t status; + + status = fw_getBundleRegisteredServices(bundle->framework, bundle, list); + + framework_logIfError(bundle->framework->logger, status, NULL, "Failed to get registered services"); + + return status; +} + +celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list) { + celix_status_t status; + + status = fw_getBundleServicesInUse(bundle->framework, bundle, list); + + framework_logIfError(logger, status, NULL, "Failed to get in use services"); + + return status; +} + +celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework) { + celix_status_t status = CELIX_SUCCESS; + + if (bundle != NULL && framework != NULL) { + bundle->framework = framework; + } else { + status = CELIX_ILLEGAL_ARGUMENT; + } + + framework_logIfError(logger, status, NULL, "Failed to set framework"); + + return status; +} + +celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework) { + celix_status_t status = CELIX_SUCCESS; + + if (bundle != NULL && *framework == NULL) { + *framework = bundle->framework; + } else { + status = CELIX_ILLEGAL_ARGUMENT; + } + + framework_logIfError(logger, status, NULL, "Failed to get framework"); + + return status; +} + +celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location){ + celix_status_t status; + + bundle_archive_pt archive = NULL; + + status = bundle_getArchive(bundle, &archive); + if (status != CELIX_SUCCESS){ + printf("[ ERROR ]: Bundle - getBundleLocation (BundleArchive) \n"); + return status; + } + + status = bundleArchive_getLocation(archive, location); + if (status != CELIX_SUCCESS){ + printf("[ ERROR ]: Bundle - getBundleLocation (BundleArchiveLocation) \n"); + return status; + } + + return CELIX_SUCCESS; +} + + +celix_status_t bundle_getBundleCache(bundle_pt bundle, const char **out) { + celix_status_t status; + + const char *cache = NULL; + bundle_archive_pt archive = NULL; + bundle_revision_pt rev = NULL; + + status = bundle_getArchive(bundle, &archive); + if (status != CELIX_SUCCESS){ + printf("[ ERROR ]: Bundle - bundle_getBundleCache (BundleArchive) \n"); + return status; + } + + status = bundleArchive_getCurrentRevision(archive, &rev); + if (status != CELIX_SUCCESS){ + printf("[ ERROR ]: Bundle - bundle_getBundleCache (BundleArchiveRevision) \n"); + return status; + } + + status = bundleRevision_getRoot(rev, &cache); + if (status != CELIX_SUCCESS){ + printf("[ ERROR ]: Bundle - bundle_getBundleCache (BundleArchiveRevision) \n"); + return status; + } + + if (out != NULL) { + *out = cache; + } + + return CELIX_SUCCESS; +} + + + + +/********************************************************************************************************************** + ********************************************************************************************************************** + * Updated API + ********************************************************************************************************************** + **********************************************************************************************************************/ + +long celix_bundle_getId(const bundle_t* bnd) { + long bndId = -1; + bundle_archive_pt archive = NULL; + if (bnd != NULL) { + bundle_getArchive((bundle_t *) bnd, &archive); + } + if (archive != NULL) { + bundleArchive_getId(archive, &bndId); + } + if (bndId < 0) { + framework_logIfError(logger, CELIX_BUNDLE_EXCEPTION, NULL, "Failed to get bundle id"); + } + return bndId; +} + +celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd) { + celix_bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN; + if (bnd != NULL) { + state = bnd->state; + } + return state; +} + +char* celix_bundle_getEntry(const bundle_t *bnd, const char *relPath) { + char *entry = NULL; + if (bnd != NULL) { + framework_getBundleEntry(bnd->framework, (bundle_t*)bnd, relPath, &entry); + } + return entry; +} + http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/src/bundle_context.c ----------------------------------------------------------------------
