This is an automated email from the ASF dual-hosted git repository. pnoltes pushed a commit to branch feature/685-refactor-manifest-format in repository https://gitbox.apache.org/repos/asf/celix.git
commit 26d14ff5970fbeddf5d65abdf647908b1469c860 Author: Pepijn Noltes <pnol...@apache.org> AuthorDate: Mon Jul 22 12:22:22 2024 +0200 gh-685: Refactor bundle manifest storage --- cmake/celix_project/CelixProject.cmake | 38 ------- cmake/cmake_celix/Generic.cmake | 38 +++++++ libs/framework/gtest/CMakeLists.txt | 4 +- ...{nop_activator.c => activator_with_exception.c} | 0 libs/framework/include/celix_types.h | 2 - libs/framework/src/bundle.c | 43 +++----- libs/framework/src/bundle_archive.c | 8 +- libs/framework/src/bundle_archive.h | 8 +- libs/framework/src/bundle_revision.c | 56 +++-------- libs/framework/src/bundle_revision.h | 112 --------------------- libs/framework/src/bundle_revision_private.h | 21 ++-- libs/framework/src/celix_module.h | 2 +- libs/framework/src/framework.c | 2 +- libs/framework/src/module.c | 74 ++++++-------- 14 files changed, 121 insertions(+), 287 deletions(-) diff --git a/cmake/celix_project/CelixProject.cmake b/cmake/celix_project/CelixProject.cmake index ddb7db240..9812155e6 100644 --- a/cmake/celix_project/CelixProject.cmake +++ b/cmake/celix_project/CelixProject.cmake @@ -85,44 +85,6 @@ MACRO(celix_subproject) ENDIF (${NAME}) ENDMACRO(celix_subproject) -#[[ -Internal function that converts a property string to a JSON field entry. -The result is stored in the OUTPUT_VAR_NAME variable. - -In the key the char `=` is not allowed and should be escaped as `\=` (in CMake this is `\\=`, because \ is already an -escape char in CMake). -In the value the char `=` is allowed. - -To handle \= string sequences the \= entries are replaced with a placeholder (__<CELIX_ESCAPED_EQUAL>__) and after the -split the placeholder is replaced with =. - -```CMake -_celix_convert_keyval_to_json("prop1=val1" "=" OUTPUT_VAR_NAME) # OUTPUT_VAR_NAME will be set to "\"prop1\":\"val1\"" -_celix_convert_keyval_to_json("prop1=va=l1" "=" OUTPUT_VAR_NAME) # OUTPUT_VAR_NAME will be set to "\"prop1\":\"va=l1\"" -_celix_convert_keyval_to_json("prop\\=1=val1" "=" OUTPUT_VAR_NAME) # OUTPUT_VAR_NAME will be set to "\"prop=1\":\"val1\"" - -_celix_convert_keyval_to_json(" prop1 = val1 " "=" OUTPUT_VAR_NAME) # OUTPUT_VAR_NAME will be set to "\"prop1\"":\"val1\"" -``` -]] -function(_celix_convert_keyval_to_json INPUT_STR SEPERATOR_CHAR OUTPUT_VAR_NAME) - set(PLACEHOLDER "__<CELIX_ESCAPED_EQUAL>__") - string(REPLACE "\\${SEPERATOR_CHAR}" "${PLACEHOLDER}" TEMP_INPUT_STR "${INPUT_STR}") - - string(REGEX MATCH "([^${SEPERATOR_CHAR}]+)${SEPERATOR_CHAR}(.*)" _ ${TEMP_INPUT_STR}) - set(KEY ${CMAKE_MATCH_1}) - set(VALUE ${CMAKE_MATCH_2}) - - #Replace replaced \= and \\ with = and \ - string(REPLACE "${PLACEHOLDER}" "${SEPERATOR_CHAR}" KEY "${KEY}") - string(REPLACE "${PLACEHOLDER}" "${SEPERATOR_CHAR}" VALUE "${VALUE}") - - #Strip leading and trailing spaces - string(STRIP "${KEY}" KEY) - string(STRIP "${VALUE}" VALUE) - - set(${OUTPUT_VAR_NAME} "\"${KEY}\":\"${VALUE}\"" PARENT_SCOPE) -endfunction() - #[[ Custom target which list the Celix CMake targets that are still using deprecated headers. ]] diff --git a/cmake/cmake_celix/Generic.cmake b/cmake/cmake_celix/Generic.cmake index f2a8782d7..6ea73ce15 100644 --- a/cmake/cmake_celix/Generic.cmake +++ b/cmake/cmake_celix/Generic.cmake @@ -162,3 +162,41 @@ function(celix_target_hide_symbols) VISIBILITY_INLINES_HIDDEN ON) endif () endfunction() + +#[[ +Internal function that converts a property string to a JSON field entry. +The result is stored in the OUTPUT_VAR_NAME variable. + +In the key the char `=` is not allowed and should be escaped as `\=` (in CMake this is `\\=`, because \ is already an +escape char in CMake). +In the value the char `=` is allowed. + +To handle \= string sequences the \= entries are replaced with a placeholder (__<CELIX_ESCAPED_EQUAL>__) and after the +split the placeholder is replaced with =. + +```CMake +_celix_convert_keyval_to_json("prop1=val1" "=" OUTPUT_VAR_NAME) # OUTPUT_VAR_NAME will be set to "\"prop1\":\"val1\"" +_celix_convert_keyval_to_json("prop1=va=l1" "=" OUTPUT_VAR_NAME) # OUTPUT_VAR_NAME will be set to "\"prop1\":\"va=l1\"" +_celix_convert_keyval_to_json("prop\\=1=val1" "=" OUTPUT_VAR_NAME) # OUTPUT_VAR_NAME will be set to "\"prop=1\":\"val1\"" + +_celix_convert_keyval_to_json(" prop1 = val1 " "=" OUTPUT_VAR_NAME) # OUTPUT_VAR_NAME will be set to "\"prop1\"":\"val1\"" +``` +]] +function(_celix_convert_keyval_to_json INPUT_STR SEPERATOR_CHAR OUTPUT_VAR_NAME) + set(PLACEHOLDER "__<CELIX_ESCAPED_EQUAL>__") + string(REPLACE "\\${SEPERATOR_CHAR}" "${PLACEHOLDER}" TEMP_INPUT_STR "${INPUT_STR}") + + string(REGEX MATCH "([^${SEPERATOR_CHAR}]+)${SEPERATOR_CHAR}(.*)" _ ${TEMP_INPUT_STR}) + set(KEY ${CMAKE_MATCH_1}) + set(VALUE ${CMAKE_MATCH_2}) + + #Replace replaced \= and \\ with = and \ + string(REPLACE "${PLACEHOLDER}" "${SEPERATOR_CHAR}" KEY "${KEY}") + string(REPLACE "${PLACEHOLDER}" "${SEPERATOR_CHAR}" VALUE "${VALUE}") + + #Strip leading and trailing spaces + string(STRIP "${KEY}" KEY) + string(STRIP "${VALUE}" VALUE) + + set(${OUTPUT_VAR_NAME} "\"${KEY}\":\"${VALUE}\"" PARENT_SCOPE) +endfunction() diff --git a/libs/framework/gtest/CMakeLists.txt b/libs/framework/gtest/CMakeLists.txt index bd0c62c86..6770f7e03 100644 --- a/libs/framework/gtest/CMakeLists.txt +++ b/libs/framework/gtest/CMakeLists.txt @@ -24,7 +24,7 @@ celix_bundle_headers(simple_test_bundle1 "Extra-Header3: value3") add_celix_bundle(simple_test_bundle2 NO_ACTIVATOR VERSION 1.0.0) add_celix_bundle(simple_test_bundle3 NO_ACTIVATOR VERSION 1.0.0) -add_celix_bundle(bundle_with_exception SOURCES src/nop_activator.c VERSION 1.0.0) +add_celix_bundle(bundle_with_exception SOURCES src/activator_with_exception.c VERSION 1.0.0) add_celix_bundle(bundle_with_bad_export NO_ACTIVATOR VERSION 1.0.0) celix_bundle_headers(bundle_with_bad_export "Export-Library: $<SEMICOLON>") add_celix_bundle(simple_cxx_bundle SOURCES src/HelloWorldCxxActivator.cc VERSION 1.0.0) @@ -35,7 +35,7 @@ add_celix_bundle(cond_test_bundle SOURCES src/CondTestBundleActivator.cc VERSION add_subdirectory(subdir) #simple_test_bundle4, simple_test_bundle5 and sublib add_celix_bundle(celix_err_test_bundle SOURCES src/activator_with_celix_err.c VERSION 1.0.0) -add_celix_bundle(unresolvable_bundle SOURCES src/nop_activator.c VERSION 1.0.0) +add_celix_bundle(unresolvable_bundle SOURCES src/activator_with_exception.c VERSION 1.0.0) if (CMAKE_BUILD_TYPE STREQUAL "Debug") set(POSTFIX ${CMAKE_DEBUG_POSTFIX}) endif() diff --git a/libs/framework/gtest/src/nop_activator.c b/libs/framework/gtest/src/activator_with_exception.c similarity index 100% rename from libs/framework/gtest/src/nop_activator.c rename to libs/framework/gtest/src/activator_with_exception.c diff --git a/libs/framework/include/celix_types.h b/libs/framework/include/celix_types.h index a73bac6f0..5ee3c32ee 100644 --- a/libs/framework/include/celix_types.h +++ b/libs/framework/include/celix_types.h @@ -65,8 +65,6 @@ typedef struct celix_bundle bundle_t CELIX_DEPRECATED_ATTR; // will be deprecated in the future typedef struct bundleArchive *bundle_archive_pt; typedef struct bundleArchive bundle_archive_t; -typedef struct bundleRevision *bundle_revision_pt; -typedef struct bundleRevision bundle_revision_t; typedef struct service_factory *service_factory_pt; typedef struct serviceReference * service_reference_pt; typedef struct serviceRegistration service_registration_t; diff --git a/libs/framework/src/bundle.c b/libs/framework/src/bundle.c index 7f8342328..c02ef2551 100644 --- a/libs/framework/src/bundle.c +++ b/libs/framework/src/bundle.c @@ -166,27 +166,14 @@ celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state) { } celix_status_t bundle_createModule(bundle_pt bundle, celix_module_t** moduleOut) { - celix_status_t status = CELIX_SUCCESS; - bundle_archive_pt archive = NULL; - bundle_revision_pt revision = NULL; - celix_bundle_manifest_t* manifest = NULL; - long bundleId = 0; - - 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, &manifest)); - status = bundleArchive_getId(bundle->archive, &bundleId); - - if (status != CELIX_SUCCESS) { - fw_logCode(bundle->framework->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot create module, cannot get bundle archive, revision, manifest or bundle id."); - return status; - } + celix_status_t status = CELIX_SUCCESS; + long bundleId = celix_bundle_getId(bundle); celix_module_t* module = NULL; if (bundleId == CELIX_FRAMEWORK_BUNDLE_ID) { module = module_createFrameworkModule(bundle->framework, bundle); } else { - module = module_create(manifest, bundle); + module = module_create(bundle); } if (!module) { status = CELIX_BUNDLE_EXCEPTION; @@ -194,8 +181,7 @@ celix_status_t bundle_createModule(bundle_pt bundle, celix_module_t** moduleOut) return status; } - - const char * symName = NULL; + const char* symName = NULL; status = module_getSymbolicName(module, &symName); assert(status == CELIX_SUCCESS); /* @@ -206,7 +192,11 @@ celix_status_t bundle_createModule(bundle_pt bundle, celix_module_t** moduleOut) bool alreadyInstalled = celix_framework_isBundleAlreadyInstalled(bundle->framework, symName); if (alreadyInstalled) { status = CELIX_BUNDLE_EXCEPTION; - fw_logCode(bundle->framework->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot create module, bundle with symbolic name '%s' already installed.", symName); + fw_logCode(bundle->framework->logger, + CELIX_LOG_LEVEL_ERROR, + status, + "Cannot create module, bundle with symbolic name '%s' already installed.", + symName); } if (status == CELIX_SUCCESS) { *moduleOut = module; @@ -487,24 +477,23 @@ char* celix_bundle_getDataFile(const celix_bundle_t* bnd, const char *path) { } const char* celix_bundle_getManifestValue(const celix_bundle_t* bnd, const char* attribute) { - const char* header = NULL; - if (bnd != NULL) { + const char* header = NULL; + if (bnd != NULL) { bundle_archive_t* arch = NULL; bundle_getArchive(bnd, &arch); if (arch != NULL) { - bundle_revision_t* rev = NULL; + celix_bundle_revision_t* rev = NULL; bundleArchive_getCurrentRevision(arch, &rev); if (rev != NULL) { - celix_bundle_manifest_t* man = NULL; - bundleRevision_getManifest(rev, &man); - if (man != NULL ) { + celix_bundle_manifest_t* man = celix_bundleRevision_getManifest(rev); + if (man != NULL) { const celix_properties_t* attr = celix_bundleManifest_getAttributes(man); header = celix_properties_getAsString(attr, attribute, NULL); } } } - } - return header; + } + return header; } const char* celix_bundle_getGroup(const celix_bundle_t *bnd) { diff --git a/libs/framework/src/bundle_archive.c b/libs/framework/src/bundle_archive.c index df594991b..bf6c1bbb7 100644 --- a/libs/framework/src/bundle_archive.c +++ b/libs/framework/src/bundle_archive.c @@ -53,7 +53,7 @@ struct bundleArchive { char* resourceCacheRoot; char* bundleSymbolicName; // read from the manifest char* bundleVersion; // read from the manifest - bundle_revision_t* revision; // the current revision + celix_bundle_revision_t* revision; // the current revision char* location; bool cacheValid; // is the cache valid (e.g. not deleted) bool valid; // is the archive valid (e.g. not deleted) @@ -345,7 +345,7 @@ void bundleArchive_destroy(bundle_archive_pt archive) { free(archive->storeRoot); free(archive->bundleSymbolicName); free(archive->bundleVersion); - bundleRevision_destroy(archive->revision); + celix_bundleRevision_destroy(archive->revision); free(archive); } } @@ -388,13 +388,13 @@ celix_status_t bundleArchive_getCurrentRevisionNumber(bundle_archive_pt archive, } //LCOV_EXCL_STOP -celix_status_t bundleArchive_getCurrentRevision(bundle_archive_pt archive, bundle_revision_pt* revision) { +celix_status_t bundleArchive_getCurrentRevision(bundle_archive_pt archive, celix_bundle_revision_t** revision) { *revision = archive->revision; return CELIX_SUCCESS; } //LCOV_EXCL_START -celix_status_t bundleArchive_getRevision(bundle_archive_pt archive, long revNr CELIX_UNUSED, bundle_revision_pt *revision) { +celix_status_t bundleArchive_getRevision(bundle_archive_pt archive, long revNr CELIX_UNUSED, celix_bundle_revision_t** revision) { return bundleArchive_getCurrentRevision(archive, revision); } diff --git a/libs/framework/src/bundle_archive.h b/libs/framework/src/bundle_archive.h index d6ceffd4f..bccee8efb 100644 --- a/libs/framework/src/bundle_archive.h +++ b/libs/framework/src/bundle_archive.h @@ -31,12 +31,12 @@ #include <time.h> #include <stdbool.h> +#include <stdlib.h> -#include "bundle_revision.h" +#include "bundle_revision_private.h" #include "celix_bundle_state.h" #include "celix_errno.h" #include "celix_log.h" -#include <stdlib.h> #include "bundle_context.h" #include "celix_bundle_context.h" @@ -64,10 +64,10 @@ bundleArchive_revise(bundle_archive_pt archive, const char *location, const char CELIX_FRAMEWORK_DEPRECATED celix_status_t bundleArchive_rollbackRevise(bundle_archive_pt archive, bool *rolledback); CELIX_FRAMEWORK_DEPRECATED celix_status_t -bundleArchive_getRevision(bundle_archive_pt archive, long revNr, bundle_revision_pt *revision); +bundleArchive_getRevision(bundle_archive_pt archive, long revNr, celix_bundle_revision_t** revision); CELIX_FRAMEWORK_DEPRECATED celix_status_t -bundleArchive_getCurrentRevision(bundle_archive_pt archive, bundle_revision_pt *revision); +bundleArchive_getCurrentRevision(bundle_archive_pt archive, celix_bundle_revision_t** revision); CELIX_FRAMEWORK_DEPRECATED celix_status_t bundleArchive_getCurrentRevisionNumber(bundle_archive_pt archive, long *revisionNumber) __attribute__((deprecated)); diff --git a/libs/framework/src/bundle_revision.c b/libs/framework/src/bundle_revision.c index 80707296a..a0e7c78f2 100644 --- a/libs/framework/src/bundle_revision.c +++ b/libs/framework/src/bundle_revision.c @@ -24,9 +24,17 @@ #include "bundle_revision_private.h" #include "framework_private.h" -celix_status_t celix_bundleRevision_create(celix_framework_t* fw, const char *root, const char *location, celix_bundle_manifest_t* manifest, bundle_revision_pt *bundle_revision) { +struct celix_bundle_revision { + celix_framework_t* fw; + char* root; + char* location; + celix_bundle_manifest_t* manifest; +}; + +celix_status_t celix_bundleRevision_create(celix_framework_t* fw, const char *root, const char *location, celix_bundle_manifest_t* manifest, + celix_bundle_revision_t** bundle_revision) { celix_status_t status = CELIX_SUCCESS; - bundle_revision_pt revision = calloc(1, sizeof(*revision)); + celix_bundle_revision_t* revision = calloc(1, sizeof(*revision)); if (revision != NULL) { revision->fw = fw; if (root != NULL) { @@ -42,7 +50,7 @@ celix_status_t celix_bundleRevision_create(celix_framework_t* fw, const char *ro status = CELIX_ENOMEM; fw_logCode(fw->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot create bundle revision, out of memory"); if (revision != NULL) { - bundleRevision_destroy(revision); + celix_bundleRevision_destroy(revision); } else { celix_bundleManifest_destroy(manifest); } @@ -53,10 +61,9 @@ celix_status_t celix_bundleRevision_create(celix_framework_t* fw, const char *ro return status; } -celix_status_t bundleRevision_destroy(bundle_revision_pt revision) { +celix_status_t celix_bundleRevision_destroy(celix_bundle_revision_t* revision) { if (revision != NULL) { - // TODO who is owner of the manifest?, for now treating this as a weak reference - // celix_bundleManifest_destroy(revision->manifest); + celix_bundleManifest_destroy(revision->manifest); free(revision->root); free(revision->location); free(revision); @@ -64,39 +71,6 @@ celix_status_t bundleRevision_destroy(bundle_revision_pt revision) { return CELIX_SUCCESS; } -celix_status_t bundleRevision_getManifest(const bundle_revision_t* revision, celix_bundle_manifest_t** manifest) { - *manifest = revision->manifest; - return CELIX_SUCCESS; -} - -//LCOV_EXCL_START -bundle_revision_t* bundleRevision_revise(const bundle_revision_t* rev, const char* updatedBundleUrl) { - fw_log(rev->fw->logger, CELIX_LOG_LEVEL_ERROR, "Revision revise unsupported."); - return NULL; -} - - -celix_status_t bundleRevision_getNumber(const bundle_revision_t* revision, long *revisionNr) { - *revisionNr = 1; //note revision nr is deprecated - return CELIX_SUCCESS; +celix_bundle_manifest_t* celix_bundleRevision_getManifest(celix_bundle_revision_t* revision) { + return revision->manifest; } - -celix_status_t bundleRevision_getLocation(const bundle_revision_t* revision, const char **location) { - *location = revision->location; - return CELIX_SUCCESS; -} - -celix_status_t bundleRevision_getRoot(const bundle_revision_t* revision, const char **root) { - *root = revision->root; - return CELIX_SUCCESS; -} - -celix_status_t bundleRevision_getHandles(const bundle_revision_t* revision CELIX_UNUSED, celix_array_list_t** handles) { - //nop, usage deprecated - if (handles) { - *handles = celix_arrayList_create(); - } - return CELIX_SUCCESS; -} -//LCOV_EXCL_STOP - diff --git a/libs/framework/src/bundle_revision.h b/libs/framework/src/bundle_revision.h deleted file mode 100644 index 50f41fe85..000000000 --- a/libs/framework/src/bundle_revision.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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 BUNDLE_REVISION_H_ -#define BUNDLE_REVISION_H_ - -#include <stdio.h> - -#include "celix_types.h" - -#include "celix_errno.h" -#include "celix_bundle_manifest.h" -#include "celix_log.h" -#include "celix_array_list.h" -#include "celix_framework_export.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * - * A bundle revision represents the content of a bundle. A revision is associated with a bundle archive. - * An archive can have multiple revisions, each update of a bundle results in a new one. - * - * In a revision the content of a bundle (ZIP file) is extracted to a specified location inside the archive. - * - * @note The bundle revision is immutable and thread safe. - */ - -/** - * Retrieves the revision number of the given revision. - * - * @param revision The revision to get the number for. - * @param[out] revisionNr The revision number. - * - * @return Status code indication failure or success: - * - CELIX_SUCCESS when no errors are encountered. - * - CELIX_ILLEGAL_ARGUMENT If <code>revision</code> is illegal. - */ -CELIX_FRAMEWORK_DEPRECATED celix_status_t bundleRevision_getNumber(const bundle_revision_t* revision, long *revisionNr) __attribute__((deprecated)); - -/** - * Retrieves the location of the given revision. - * - * @param revision The revision to get the location for. - * @param[out] location The location. - * - * @return Status code indication failure or success: - * - CELIX_SUCCESS when no errors are encountered. - * - CELIX_ILLEGAL_ARGUMENT If <code>revision</code> is illegal. - */ -CELIX_FRAMEWORK_DEPRECATED celix_status_t bundleRevision_getLocation(const bundle_revision_t* revision, const char **location); - -/** - * Retrieves the root of the given revision. - * - * @param revision The revision to get the location for. - * @param[out] root The root. - * - * @return Status code indication failure or success: - * - CELIX_SUCCESS when no errors are encountered. - * - CELIX_ILLEGAL_ARGUMENT If <code>revision</code> is illegal. - */ -CELIX_FRAMEWORK_DEPRECATED celix_status_t bundleRevision_getRoot(const bundle_revision_t* revision, const char **root); - -/** - * Retrieves the manifest of the given revision. - * - * @param revision The revision to get the manifest for. - * @param[out] manifest The manifest. - * - * @return Status code indication failure or success: - * - CELIX_SUCCESS when no errors are encountered. - * - CELIX_ILLEGAL_ARGUMENT If <code>revision</code> is illegal. - */ -CELIX_FRAMEWORK_DEPRECATED celix_status_t bundleRevision_getManifest(const bundle_revision_t* revision, - celix_bundle_manifest_t** manifest); - -/** - * Originally retrieved the handles of the installed libraries for this revision. - * Currently deprecated and will not return any handles. - * @return CELIX_SUCCESS and an empty list. - */ -CELIX_FRAMEWORK_EXPORT celix_status_t bundleRevision_getHandles(const bundle_revision_t* revision, celix_array_list_t **handles) - __attribute__((deprecated("Deprecated. Library handles are no now handled by the bundle module."))); - -#ifdef __cplusplus -} -#endif - -#endif /* BUNDLE_REVISION_H_ */ - -/** - * @} - */ diff --git a/libs/framework/src/bundle_revision_private.h b/libs/framework/src/bundle_revision_private.h index f0e18073f..d09836993 100644 --- a/libs/framework/src/bundle_revision_private.h +++ b/libs/framework/src/bundle_revision_private.h @@ -27,8 +27,9 @@ #ifndef BUNDLE_REVISION_PRIVATE_H_ #define BUNDLE_REVISION_PRIVATE_H_ -#include "bundle_revision.h" #include "celix_threads.h" +#include "celix_framework.h" +#include "celix_bundle_manifest.h" #ifdef __cplusplus extern "C" { @@ -38,13 +39,7 @@ extern "C" { * The bundle revision structure represents a revision of a bundle. * A bundle can have multiple revisions. A bundle revision is immutable. */ -struct bundleRevision { - celix_framework_t* fw; - long revisionNr; - char* root; - char* location; - celix_bundle_manifest_t* manifest; -}; +typedef struct celix_bundle_revision celix_bundle_revision_t; /** * Creates a new revision for the given inputFile or location. @@ -64,11 +59,15 @@ celix_status_t celix_bundleRevision_create(celix_framework_t* fw, const char* root, const char* location, celix_bundle_manifest_t* manifest, - bundle_revision_pt* bundle_revision); + celix_bundle_revision_t** bundle_revision); -bundle_revision_t* bundleRevision_revise(const bundle_revision_t* revision, const char* updatedBundleUrl); +celix_status_t celix_bundleRevision_destroy(celix_bundle_revision_t* revision); -celix_status_t bundleRevision_destroy(bundle_revision_pt revision); + +/** + * @brief Get the bundle manifest of the given revision. + */ +celix_bundle_manifest_t* celix_bundleRevision_getManifest(celix_bundle_revision_t* revision); #ifdef __cplusplus } diff --git a/libs/framework/src/celix_module.h b/libs/framework/src/celix_module.h index af83623b2..189d61bd0 100644 --- a/libs/framework/src/celix_module.h +++ b/libs/framework/src/celix_module.h @@ -36,7 +36,7 @@ extern "C" { * @return A new module or NULL if the module could not be created. If NULL is returned, an error log is written to * celix err. */ -celix_module_t* module_create(celix_bundle_manifest_t* manifest, celix_bundle_t* bundle); +celix_module_t* module_create(celix_bundle_t* bundle); celix_module_t* module_createFrameworkModule(celix_framework_t* fw, celix_bundle_t *bundle); diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c index ee64f89fe..459834532 100644 --- a/libs/framework/src/framework.c +++ b/libs/framework/src/framework.c @@ -1996,7 +1996,7 @@ static celix_status_t celix_framework_uninstallBundleEntryImpl(celix_framework_t celix_status_t status = CELIX_SUCCESS; celix_bundle_t *bnd = bndEntry->bnd; bundle_archive_t *archive = NULL; - bundle_revision_t *revision = NULL; + celix_bundle_revision_t*revision = NULL; celix_module_t* module = NULL; status = CELIX_DO_IF(status, bundle_getArchive(bnd, &archive)); status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision)); diff --git a/libs/framework/src/module.c b/libs/framework/src/module.c index 56512660c..269d711fa 100644 --- a/libs/framework/src/module.c +++ b/libs/framework/src/module.c @@ -49,14 +49,18 @@ struct celix_module { celix_framework_t* fw; bool resolved; celix_bundle_t* bundle; - celix_bundle_manifest_t* manifest; - celix_thread_mutex_t handlesLock; // protects libraryHandles and bundleActivatorHandle + celix_thread_mutex_t handlesLock; // protects libraryHandles celix_array_list_t* libraryHandles; - void* bundleActivatorHandle; }; -celix_module_t* module_create(celix_bundle_manifest_t* manifest, celix_bundle_t* bundle) { - assert(manifest != NULL); +static celix_bundle_manifest_t* celix_module_getManifestFromBundle(celix_bundle_t* bundle) { + bundle_archive_t* archive = celix_bundle_getArchive(bundle); + celix_bundle_revision_t* revision = NULL; + (void)bundleArchive_getCurrentRevision(archive, &revision); + return celix_bundleRevision_getManifest(revision); +} + +celix_module_t* module_create(celix_bundle_t* bundle) { assert(bundle != NULL); celix_framework_t* fw; @@ -82,20 +86,12 @@ celix_module_t* module_create(celix_bundle_manifest_t* manifest, celix_bundle_t* module->fw = fw; module->bundle = bundle; module->resolved = false; - module->manifest = manifest; module->libraryHandles = celix_steal_ptr(libraryHandles); return celix_steal_ptr(module); } celix_module_t* module_createFrameworkModule(celix_framework_t* fw, bundle_pt bundle) { - celix_autoptr(celix_bundle_manifest_t) manifest = NULL; - celix_status_t status = celix_bundleManifest_createFrameworkManifest(&manifest); - if (status != CELIX_SUCCESS) { - celix_framework_logTssErrors(fw->logger, CELIX_LOG_LEVEL_ERROR); - return NULL; - } - celix_autoptr(celix_module_t) module = calloc(1, sizeof(*module)); celix_autoptr(celix_array_list_t) libraryHandles = celix_arrayList_createPointerArray(); if (!module || !libraryHandles) { @@ -103,7 +99,7 @@ celix_module_t* module_createFrameworkModule(celix_framework_t* fw, bundle_pt bu return NULL; } - status = celixThreadMutex_create(&module->handlesLock, NULL); + celix_status_t status = celixThreadMutex_create(&module->handlesLock, NULL); if (status != CELIX_SUCCESS) { fw_log(fw->logger, CELIX_LOG_LEVEL_ERROR, @@ -116,7 +112,6 @@ celix_module_t* module_createFrameworkModule(celix_framework_t* fw, bundle_pt bu module->fw = fw; module->bundle = bundle; module->resolved = false; - module->manifest = celix_steal_ptr(manifest); module->libraryHandles = celix_steal_ptr(libraryHandles); return celix_steal_ptr(module); @@ -124,7 +119,6 @@ celix_module_t* module_createFrameworkModule(celix_framework_t* fw, bundle_pt bu void module_destroy(celix_module_t* module) { if (module) { - celix_bundleManifest_destroy(module->manifest); celix_arrayList_destroy(module->libraryHandles); celixThreadMutex_destroy(&module->handlesLock); free(module); @@ -132,7 +126,8 @@ void module_destroy(celix_module_t* module) { } const celix_version_t* module_getVersion(celix_module_t* module) { - return celix_bundleManifest_getBundleVersion(module->manifest); + celix_bundle_manifest_t* man = celix_module_getManifestFromBundle(module->bundle); + return celix_bundleManifest_getBundleVersion(man); } celix_status_t module_getSymbolicName(celix_module_t* module, const char** symbolicName) { @@ -140,7 +135,8 @@ celix_status_t module_getSymbolicName(celix_module_t* module, const char** symbo if (module == NULL) { status = CELIX_ILLEGAL_ARGUMENT; } else { - *symbolicName = celix_bundleManifest_getBundleSymbolicName(module->manifest); + celix_bundle_manifest_t* man = celix_module_getManifestFromBundle(module->bundle); + *symbolicName = celix_bundleManifest_getBundleSymbolicName(man); } return status; } @@ -150,7 +146,8 @@ celix_status_t module_getName(celix_module_t* module, const char **name) { if (module == NULL) { status = CELIX_ILLEGAL_ARGUMENT; } else { - *name = celix_bundleManifest_getBundleName(module->manifest); + celix_bundle_manifest_t* man = celix_module_getManifestFromBundle(module->bundle); + *name = celix_bundleManifest_getBundleName(man); } return status; } @@ -160,7 +157,8 @@ celix_status_t module_getGroup(celix_module_t* module, const char **group) { if (module == NULL) { status = CELIX_ILLEGAL_ARGUMENT; } else { - *group = celix_bundleManifest_getBundleGroup(module->manifest); + celix_bundle_manifest_t* man = celix_module_getManifestFromBundle(module->bundle); + *group = celix_bundleManifest_getBundleGroup(man); } return status; } @@ -170,7 +168,8 @@ celix_status_t module_getDescription(celix_module_t* module, const char **descri if (module == NULL) { status = CELIX_ILLEGAL_ARGUMENT; } else { - *description = celix_bundleManifest_getBundleDescription(module->manifest); + celix_bundle_manifest_t* man = celix_module_getManifestFromBundle(module->bundle); + *description = celix_bundleManifest_getBundleDescription(man); } return status; } @@ -197,7 +196,6 @@ celix_status_t celix_module_closeLibraries(celix_module_t* module) { celix_libloader_close(fwCtx, handle); } celix_arrayList_clear(module->libraryHandles); - module->bundleActivatorHandle = NULL; celixThreadMutex_unlock(&module->handlesLock); return status; } @@ -284,29 +282,16 @@ static celix_status_t celix_module_loadLibrariesInManifestEntry(celix_module_t* celix_status_t celix_module_loadLibraries(celix_module_t* module) { celix_status_t status = CELIX_SUCCESS; celix_library_handle_t* activatorHandle = NULL; - bundle_archive_pt archive = NULL; - bundle_revision_pt revision = NULL; - celix_bundle_manifest_t* manifest = NULL; - - status = CELIX_DO_IF(status, bundle_getArchive(module->bundle, &archive)); - status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision)); - status = CELIX_DO_IF(status, bundleRevision_getManifest(revision, &manifest)); - if (status == CELIX_SUCCESS) { - const char* activator = celix_bundleManifest_getBundleActivatorLibrary(manifest); - const celix_array_list_t* privateLibraries = celix_bundleManifest_getBundlePrivateLibraries(manifest); - - if (privateLibraries != NULL) { - status = CELIX_DO_IF(status, - celix_module_loadLibrariesInManifestEntry( - module, privateLibraries, activator, archive, &activatorHandle)); - } + bundle_archive_t* archive = celix_bundle_getArchive(module->bundle); - if (status == CELIX_SUCCESS) { - bundle_setHandle(module->bundle, activatorHandle); // note deprecated - celixThreadMutex_lock(&module->handlesLock); - module->bundleActivatorHandle = activatorHandle; - celixThreadMutex_unlock(&module->handlesLock); - } + celix_bundle_manifest_t* man = celix_module_getManifestFromBundle(module->bundle); + const char* activator = celix_bundleManifest_getBundleActivatorLibrary(man); + const celix_array_list_t* privateLibraries = celix_bundleManifest_getBundlePrivateLibraries(man); + + if (privateLibraries != NULL) { + status = CELIX_DO_IF( + status, + celix_module_loadLibrariesInManifestEntry(module, privateLibraries, activator, archive, &activatorHandle)); } if (status != CELIX_SUCCESS) { @@ -318,5 +303,6 @@ celix_status_t celix_module_loadLibraries(celix_module_t* module) { (void)celix_module_closeLibraries(module); } + bundle_setHandle(module->bundle, activatorHandle); return status; }