Skip to content

Commit

Permalink
gh-685: Refactor bundle manifest storage
Browse files Browse the repository at this point in the history
  • Loading branch information
pnoltes committed Jul 22, 2024
1 parent 4678197 commit 26d14ff
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 287 deletions.
38 changes: 0 additions & 38 deletions cmake/celix_project/CelixProject.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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.
]]
Expand Down
38 changes: 38 additions & 0 deletions cmake/cmake_celix/Generic.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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()
4 changes: 2 additions & 2 deletions libs/framework/gtest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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()
Expand Down
File renamed without changes.
2 changes: 0 additions & 2 deletions libs/framework/include/celix_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
43 changes: 16 additions & 27 deletions libs/framework/src/bundle.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,36 +166,22 @@ 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;
fw_logCode(bundle->framework->logger, CELIX_LOG_LEVEL_ERROR, status, "Cannot create module.");
return status;
}


const char * symName = NULL;
const char* symName = NULL;
status = module_getSymbolicName(module, &symName);
assert(status == CELIX_SUCCESS);
/*
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
8 changes: 4 additions & 4 deletions libs/framework/src/bundle_archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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);
}

Expand Down
8 changes: 4 additions & 4 deletions libs/framework/src/bundle_archive.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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));

Expand Down
56 changes: 15 additions & 41 deletions libs/framework/src/bundle_revision.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
Expand All @@ -53,50 +61,16 @@ 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);
}
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

Loading

0 comments on commit 26d14ff

Please sign in to comment.