From 9b812c08e0f8f8b46292992f41d7d28ff6b5d1d5 Mon Sep 17 00:00:00 2001 From: Erjan Altena Date: Thu, 25 Nov 2021 21:18:24 +0100 Subject: [PATCH 1/2] Added an extra output to the DM shell command which generates plantuml output to quickly see the resolved and not-resolved dependencies --- .../shell/shell/src/dm_shell_list_command.c | 174 ++++++++++++++---- .../dm_example_cxx/api/include/IPhase1.h | 1 + 2 files changed, 140 insertions(+), 35 deletions(-) diff --git a/bundles/shell/shell/src/dm_shell_list_command.c b/bundles/shell/shell/src/dm_shell_list_command.c index df1fdcac0..ce8b72274 100644 --- a/bundles/shell/shell/src/dm_shell_list_command.c +++ b/bundles/shell/shell/src/dm_shell_list_command.c @@ -30,7 +30,20 @@ static const char * const WARNING_COLOR = "\033[93m"; static const char * const NOK_COLOR = "\033[91m"; static const char * const END_COLOR = "\033[m"; -static void parseCommandLine(const char*line, celix_array_list_t **requestedBundleIds, bool *fullInfo, bool *wtf, FILE *err) { +void printInactiveBundles(FILE *out, celix_dependency_manager_t *mng, bool useColors); + +void printSpecifiedBundles(FILE *out, celix_dependency_manager_t *mng, bool useColors, bool fullInfo, bool plantUmlInfo); + +void printAllBundles(FILE *out, celix_dependency_manager_t *mng, bool useColors, const celix_array_list_t *bundleIds, + bool fullInfo, bool plantUmlInfo); + +static void printPlantUmlInfo(FILE *out, celix_dependency_manager_t *mng); +static void printUmlComponents(FILE *out, const celix_array_list_t *infos); + +static void printUmlDependencies(FILE *out, const celix_array_list_t *infos); + + +static void parseCommandLine(const char*line, celix_array_list_t **requestedBundleIds, bool *fullInfo, bool *plantUmlInfo, bool *wtf, FILE *err) { *fullInfo = false; *wtf = false; char *str = strdup(line); @@ -43,6 +56,8 @@ static void parseCommandLine(const char*line, celix_array_list_t **requestedBund *wtf = true; } else if (tok[0] == 'f') { // f or full argument => show full info *fullInfo = true; + } else if (tok[0] == 'u') { // u or full plant UML syntax output =>copy paste in a file java -jar plantuml.jar gives a nice dependency graph + *plantUmlInfo = true; } else if ( (tok[0] >= '0') && (tok[0] <= '9')) { // bundle id long id = strtol(tok, NULL, 10); celix_arrayList_addLong(*requestedBundleIds, id); @@ -102,6 +117,74 @@ static void printFullInfo(FILE *out, bool colors, long bundleId, const char* bnd fprintf(out, "\n"); } +static void printPlantUmlInfo(FILE *out, celix_dependency_manager_t *mng) { + + celix_array_list_t *infos = celix_dependencyManager_createInfos(mng); + + fprintf(out, "@startuml\n"); + + printUmlComponents(out, infos); + printUmlDependencies(out, infos); + + fprintf(out, "@enduml\n"); +} + +static void printUmlComponents(FILE *out, const celix_array_list_t *infos) { + unsigned int nof_bundles = celix_arrayList_size(infos); + for (int bnd = 0; bnd < nof_bundles; ++bnd) { + celix_dependency_manager_info_t *info = celix_arrayList_get(infos, bnd); + for (int cmpCnt = 0; cmpCnt < celix_arrayList_size(info->components); ++cmpCnt) { + celix_dm_component_info_t *compInfo = celix_arrayList_get(info->components, cmpCnt); + fprintf(out, "class %s\n", compInfo->name); + for (int interfCnt = 0; interfCnt < celix_arrayList_size(compInfo->interfaces); interfCnt++) { + dm_interface_info_pt intfInfo = celix_arrayList_get(compInfo->interfaces, interfCnt); + fprintf(out, "interface %s\n", intfInfo->name); + } + } + } + // depdencies at last, since the type overwrites the interface for a nice graph + for (int bnd = 0; bnd < nof_bundles; ++bnd) { + celix_dependency_manager_info_t *info = celix_arrayList_get(infos, bnd); + for (int cmpCnt = 0; cmpCnt < celix_arrayList_size(info->components); ++cmpCnt) { + celix_dm_component_info_t *compInfo = celix_arrayList_get(info->components, cmpCnt); + for (int depCnt = 0; depCnt < celix_arrayList_size(compInfo->dependency_list); ++depCnt) { + dm_service_dependency_info_pt dependency; + dependency = celix_arrayList_get(compInfo->dependency_list, depCnt); + fprintf(out, "interface %s\n", dependency->serviceName); + } + } + } + fprintf(out, "\n"); +} + + +static void printUmlDependencies(FILE *out, const celix_array_list_t *infos) { + unsigned int nof_bundles = celix_arrayList_size(infos); + + // Now print the UML relations + for (int bnd = 0; bnd < nof_bundles; ++bnd) { + celix_dependency_manager_info_t *info = celix_arrayList_get(infos, bnd); + for (int cmpCnt = 0; cmpCnt < celix_arrayList_size(info->components); ++cmpCnt) { + celix_dm_component_info_t *compInfo = celix_arrayList_get(info->components, cmpCnt); + for (int interfCnt = 0; interfCnt < celix_arrayList_size(compInfo->interfaces); interfCnt++) { + dm_interface_info_pt intfInfo = celix_arrayList_get(compInfo->interfaces, interfCnt); + fprintf(out, "%s --|> %s\n", compInfo->name, intfInfo->name); + } + for (int depCnt = 0; depCnt < celix_arrayList_size(compInfo->dependency_list); ++depCnt) { + dm_service_dependency_info_pt dependency; + dependency = celix_arrayList_get(compInfo->dependency_list, depCnt); + if (dependency->available) { + fprintf(out, "%s *--> %s\n", compInfo->name, dependency->serviceName); + } else if (dependency->required) { + fprintf(out, "%s *..> %s\n", compInfo->name, dependency->serviceName); + } else { + fprintf(out, "%s ..> %s\n", compInfo->name, dependency->serviceName); + } + } + } + } +} + static void printBasicInfo(FILE *out, bool colors, long bundleId, const char* bndName, dm_component_info_pt compInfo) { const char *startColors = ""; @@ -119,7 +202,7 @@ static void dm_printInfo(FILE *out, bool useColors, bool fullInfo, celix_depende if (info != NULL) { int size = celix_arrayList_size(info->components); if (size > 0) { - for (unsigned int cmpCnt = 0; cmpCnt < size; cmpCnt++) { + for ( int cmpCnt = 0; cmpCnt < size; cmpCnt++) { dm_component_info_pt compInfo = celix_arrayList_get(info->components, cmpCnt); if (fullInfo) { printFullInfo(out, useColors, info->bndId, info->bndSymbolicName, compInfo); @@ -128,6 +211,7 @@ static void dm_printInfo(FILE *out, bool useColors, bool fullInfo, celix_depende } } fprintf(out, "\n"); + } } } @@ -142,48 +226,68 @@ celix_status_t dmListCommand_execute(void* handle, char * line, FILE *out, FILE celix_array_list_t *bundleIds = NULL; bool fullInfo = false; + bool plantUmlInfo = false; bool wtf = false; - parseCommandLine(line, &bundleIds, &fullInfo, &wtf, err); + parseCommandLine(line, &bundleIds, &fullInfo, &plantUmlInfo, &wtf, err); if (wtf) { - //only print dm that are not active - bool allActive = true; - int nrOfComponents = 0; - celix_array_list_t *infos = celix_dependencyManager_createInfos(mng); - for (int i = 0; i < celix_arrayList_size(infos); ++i) { - celix_dependency_manager_info_t *info = celix_arrayList_get(infos, i); - for (int k = 0; k < celix_arrayList_size(info->components); ++k) { - celix_dm_component_info_t *cmpInfo = celix_arrayList_get(info->components, k); - nrOfComponents += 1; - if (!cmpInfo->active) { - allActive = false; - printFullInfo(out, useColors, info->bndId, info->bndSymbolicName, cmpInfo); - } - } - } - celix_dependencyManager_destroyInfos(mng, infos); - if (allActive) { - fprintf(out, "No problem all %i dependency manager components are active\n", nrOfComponents); - } + printInactiveBundles(out, mng, useColors); + } else if (plantUmlInfo) { + printPlantUmlInfo(out, mng); } else if (celix_arrayList_size(bundleIds) == 0) { - celix_array_list_t *infos = celix_dependencyManager_createInfos(mng); + printSpecifiedBundles(out, mng, useColors, fullInfo, plantUmlInfo); + } else { + printAllBundles(out, mng, useColors, bundleIds, fullInfo, plantUmlInfo); + } + + celix_arrayList_destroy(bundleIds); + + return CELIX_SUCCESS; +} + +void printAllBundles(FILE *out, celix_dependency_manager_t *mng, bool useColors, const celix_array_list_t *bundleIds, + bool fullInfo, bool plantUmlInfo) { + for (int i = 0; i < celix_arrayList_size(bundleIds); ++i) { + long bndId = celix_arrayList_getLong(bundleIds, i); + celix_dependency_manager_info_t *info = celix_dependencyManager_createInfo(mng, bndId); + if (info != NULL) { + dm_printInfo(out, useColors, fullInfo, info); + celix_dependencyManager_destroyInfo(mng, info); + } + } +} + +void printSpecifiedBundles(FILE *out, celix_dependency_manager_t *mng, bool useColors, bool fullInfo, bool plantUmlInfo) { + celix_array_list_t *infos = celix_dependencyManager_createInfos(mng); + if (plantUmlInfo) { + printPlantUmlInfo(out, mng); + } else { for (int i = 0; i < celix_arrayList_size(infos); ++i) { celix_dependency_manager_info_t *info = celix_arrayList_get(infos, i); dm_printInfo(out, useColors, fullInfo, info); } - celix_dependencyManager_destroyInfos(mng, infos); - } else { - for (int i = 0; i < celix_arrayList_size(bundleIds); ++i) { - long bndId = celix_arrayList_getLong(bundleIds, i); - celix_dependency_manager_info_t *info = celix_dependencyManager_createInfo(mng, bndId); - if (info != NULL) { - dm_printInfo(out, useColors, fullInfo, info); - celix_dependencyManager_destroyInfo(mng, info); + } + celix_dependencyManager_destroyInfos(mng, infos); +} + +void +printInactiveBundles(FILE *out, celix_dependency_manager_t *mng, bool useColors) {//only print dm that are not active + bool allActive = true; + int nrOfComponents = 0; + celix_array_list_t *infos = celix_dependencyManager_createInfos(mng); + for (int i = 0; i < celix_arrayList_size(infos); ++i) { + celix_dependency_manager_info_t *info = celix_arrayList_get(infos, i); + for (int k = 0; k < celix_arrayList_size(info->components); ++k) { + celix_dm_component_info_t *cmpInfo = celix_arrayList_get(info->components, k); + nrOfComponents += 1; + if (!cmpInfo->active) { + allActive = false; + printFullInfo(out, useColors, info->bndId, info->bndSymbolicName, cmpInfo); } } } - - celix_arrayList_destroy(bundleIds); - - return CELIX_SUCCESS; + celix_dependencyManager_destroyInfos(mng, infos); + if (allActive) { + fprintf(out, "No problem all %i dependency manager components are active\n", nrOfComponents); + } } diff --git a/examples/celix-examples/dm_example_cxx/api/include/IPhase1.h b/examples/celix-examples/dm_example_cxx/api/include/IPhase1.h index c9db5e43b..eb3ebd630 100644 --- a/examples/celix-examples/dm_example_cxx/api/include/IPhase1.h +++ b/examples/celix-examples/dm_example_cxx/api/include/IPhase1.h @@ -30,4 +30,5 @@ class IPhase1 { virtual int getData() = 0; }; + #endif //CELIX_PHASE1_H From 372e30f1004ec1fe4d0b443b146a39a00a65deb3 Mon Sep 17 00:00:00 2001 From: Erjan Altena Date: Thu, 25 Nov 2021 21:52:41 +0100 Subject: [PATCH 2/2] Fix introduced mem leak --- bundles/shell/shell/src/dm_shell_list_command.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bundles/shell/shell/src/dm_shell_list_command.c b/bundles/shell/shell/src/dm_shell_list_command.c index ce8b72274..1e3c18b74 100644 --- a/bundles/shell/shell/src/dm_shell_list_command.c +++ b/bundles/shell/shell/src/dm_shell_list_command.c @@ -127,6 +127,9 @@ static void printPlantUmlInfo(FILE *out, celix_dependency_manager_t *mng) { printUmlDependencies(out, infos); fprintf(out, "@enduml\n"); + + celix_dependencyManager_destroyInfos(mng, infos); + } static void printUmlComponents(FILE *out, const celix_array_list_t *infos) {