Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Core] Add methods to retrieve available sub-items and handle not found errors in Registry and RegistryItem #12943

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions kratos/includes/registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,17 @@ class KRATOS_API(KRATOS_CORE) Registry final
///@name Private Operations
///@{

/**
* @brief This method throws an error message for a not found item.
* @param rFullName The full name of the item.
* @param rItemName The name of the item.
* @param pCurrentItem The current item.
*/
static void NotFoundError(
const std::string& rFullName,
const std::string& rItemName,
RegistryItem* pCurrentItem
);

///@}
///@name Private Access
Expand Down
16 changes: 16 additions & 0 deletions kratos/includes/registry_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,16 @@ class KRATOS_API(KRATOS_CORE) RegistryItem
return true;
}

///@}
///@name Operations
///@{

/**
* @brief Returns the sub items name list available in the registry item (for error messaged).
* @return std::vector<std::string> The sub items name list.
*/
std::vector<std::string> GetSubItemAvailableList() const;

///@}
///@name Input and output
///@{
Expand Down Expand Up @@ -340,6 +350,12 @@ class KRATOS_API(KRATOS_CORE) RegistryItem
return buffer.str();
}

/**
* @brief This method throws an error message for a not found item.
* @param rItemName The name of the item.
*/
void NotFoundError(const std::string& rItemName) const;

///@}
///@name Private classes
///@{
Expand Down
30 changes: 21 additions & 9 deletions kratos/sources/registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ namespace
auto& r_item_name = item_path[i];
if(p_current_item->HasItem(r_item_name)){
p_current_item = &p_current_item->GetItem(r_item_name);
}
else{
KRATOS_ERROR << "The item \"" << rItemFullName << "\" is not found in the registry. The item \"" << p_current_item->Name() << "\" does not have \"" << r_item_name << "\"" << std::endl;
} else {
NotFoundError(rItemFullName, r_item_name, p_current_item);
}
}

Expand All @@ -65,18 +64,16 @@ namespace
auto& r_item_name = item_path[i];
if(p_current_item->HasItem(r_item_name)){
p_current_item = &p_current_item->GetItem(r_item_name);
}
else{
KRATOS_ERROR << "The item \"" << rItemFullName << "\" is not found in the registry. The item \"" << p_current_item->Name() << "\" does not have \"" << r_item_name << "\"" << std::endl;
} else {
NotFoundError(rItemFullName, r_item_name, p_current_item);
}
}

auto& r_item_name = item_path.back();
if(p_current_item->HasItem(r_item_name)){
p_current_item->RemoveItem(r_item_name);
}
else{
KRATOS_ERROR << "The item \"" << rItemFullName << "\" is not found in the registry. The item \"" << p_current_item->Name() << "\" does not have \"" << r_item_name << "\"" << std::endl;
} else {
NotFoundError(rItemFullName, r_item_name, p_current_item);
}
}

Expand Down Expand Up @@ -158,6 +155,21 @@ namespace
return GetRootRegistryItem().ToJson(Indentation);
}

void Registry::NotFoundError(
const std::string& rFullName,
const std::string& rItemName,
RegistryItem* pCurrentItem
)
{
const std::vector<std::string> available_list = pCurrentItem->GetSubItemAvailableList();
std::stringstream error_message_buffer;
error_message_buffer << "The item \"" << rFullName << "\" is not found in the registry. The item \"" << pCurrentItem->Name() << "\" does not have \"" << rItemName << "\". The available objects are: \n";
for (std::string const& item : available_list) {
error_message_buffer << "\t\t" << item << "\n";
}
KRATOS_ERROR << error_message_buffer.str() << std::endl;
}

RegistryItem& Registry::GetRootRegistryItem()
{
if (!mspRootRegistryItem) {
Expand Down
35 changes: 32 additions & 3 deletions kratos/sources/registry_item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,29 @@ namespace Kratos
}
}

std::vector<std::string> RegistryItem::GetSubItemAvailableList() const
{
std::vector<std::string> available_list;
auto it_item_begin = this->cbegin();
auto it_item_end = this->cend();
available_list.reserve(std::distance(it_item_begin, it_item_end));
for (auto it_item = it_item_begin; it_item != it_item_end; ++it_item) {
available_list.push_back((it_item->second)->Name());
}
return available_list;
}

void RegistryItem::NotFoundError(const std::string& rItemName) const
{
const std::vector<std::string> available_list = GetSubItemAvailableList();
std::stringstream error_message_buffer;
error_message_buffer << "The RegistryItem " << this->Name() << " does not have an item with name " << rItemName << ". The available objects are: \n";
for (std::string const& item : available_list) {
error_message_buffer << "\t\t" << item << "\n";
}
KRATOS_ERROR << error_message_buffer.str() << std::endl;
}

std::string RegistryItem::GetValueString() const
{
return (this->*(this->mGetValueStringMethod))();
Expand Down Expand Up @@ -163,23 +186,29 @@ namespace Kratos
{
SubRegistryItemType& r_map = GetSubRegistryItemMap();
auto iterator = r_map.find(rItemName);
KRATOS_ERROR_IF(iterator == r_map.end()) << "The RegistryItem " << this->Name() << " does not have an item with name " << rItemName << std::endl;
if (iterator == r_map.end()) {
NotFoundError(rItemName);
}
return *(iterator->second);
}

RegistryItem& RegistryItem::GetItem(std::string const& rItemName)
{
SubRegistryItemType& r_map = GetSubRegistryItemMap();
auto iterator = r_map.find(rItemName);
KRATOS_ERROR_IF(iterator == r_map.end()) << "The RegistryItem " << this->Name() << " does not have an item with name " << rItemName << std::endl;
if (iterator == r_map.end()) {
NotFoundError(rItemName);
}
return *(iterator->second);
}

void RegistryItem::RemoveItem(std::string const& rItemName)
{
SubRegistryItemType& r_map = GetSubRegistryItemMap();
auto iterator = r_map.find(rItemName);
KRATOS_ERROR_IF(iterator == r_map.end()) << "The RegistryItem " << this->Name() << " does not have an item with name " << rItemName << std::endl;
if (iterator == r_map.end()) {
NotFoundError(rItemName);
}
r_map.erase(iterator);
}

Expand Down
8 changes: 3 additions & 5 deletions kratos/tests/cpp_tests/sources/test_registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
#include "includes/expect.h"
#include "includes/registry.h"

namespace Kratos {

namespace Testing {
namespace Kratos::Testing {

namespace
{
Expand Down Expand Up @@ -141,6 +139,7 @@ KRATOS_TEST_CASE_IN_SUITE(RegistrySubValue, KratosCoreFastSuite)

registry_item.AddItem<double>("sub_value_item", value);
auto& sub_item = registry_item.GetItem("sub_value_item");
KRATOS_EXPECT_EXCEPTION_IS_THROWN(registry_item.GetItem("sub_value_item_2"), "");

KRATOS_EXPECT_EQ(sub_item.Name(),"sub_value_item");
KRATOS_EXPECT_TRUE(sub_item.HasValue());
Expand Down Expand Up @@ -315,5 +314,4 @@ KRATOS_TEST_CASE_IN_SUITE(RegistryIsSameType, KratosCoreFastSuite) {
KRATOS_EXPECT_FALSE(Registry::GetItem("variables.all.VELOCITY").IsSameType(test_double));
}

}
} // namespace Kratos.
} // namespace Kratos::Testing.
2 changes: 2 additions & 0 deletions kratos/tests/cpp_tests/sources/test_registry_access.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ KRATOS_TEST_CASE_IN_SUITE(RegistryItemGetValueDerivedAsBase, KratosCoreFastSuite
auto pProcess = Registry::GetValue<Process>("Processes.KratosMultiphysics.OutputProcess.Prototype");

KRATOS_EXPECT_TRUE((std::is_same<Process,decltype(pProcess)>::value))

KRATOS_EXPECT_EXCEPTION_IS_THROWN(Registry::GetValue<Process>("Processes.KratosMultiphysics.output_process.Prototype"), "");
}


Expand Down
14 changes: 13 additions & 1 deletion kratos/tests/test_python_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ def testHasItemCpp(self):
# Check that base Process is registered in its corresponding module as well as in the All block
self.assertTrue(KratosMultiphysics.Registry.HasItem("Processes.All.Process"))
self.assertTrue(KratosMultiphysics.Registry.HasItem("Processes.KratosMultiphysics.Process"))
self.assertFalse(KratosMultiphysics.Registry.HasItem("Processes.KratosMultiphysics.ProcessPikachu"))

def testGetItemCpp(self):
# Check that base Process is registered in its corresponding module as well as in the All block
base_process = KratosMultiphysics.Registry["Processes.All.Process.Prototype"]
self.assertTrue(isinstance(base_process, KratosMultiphysics.Process))
base_process = KratosMultiphysics.Registry["Processes.KratosMultiphysics.Process.Prototype"]
self.assertTrue(isinstance(base_process, KratosMultiphysics.Process))

@KratosUnittest.expectedFailure
def testHasItemCppFail(self):
KratosMultiphysics.Registry["Processes.All.ProcessPikachu.Prototype"]

def testHasItemPython(self):
# Add a fake entity to the Python registry
Expand Down Expand Up @@ -39,7 +51,6 @@ def testNumberOfItems(self):
# Remove the auxiliary testing tentities from the Python registry
KratosMultiphysics.Registry.RemoveItem("FakeEntities")


def testAddItem(self):
# Add some fake entities to the Python registry
KratosMultiphysics.Registry.AddItem("Processes.KratosMultiphysics.NewProcess1", KratosMultiphysics.Process())
Expand Down Expand Up @@ -217,4 +228,5 @@ def getA(self):
KratosMultiphysics.Registry.RemoveItem("Processes")

if __name__ == "__main__":
KratosMultiphysics.Logger.GetDefaultOutput().SetSeverity(KratosMultiphysics.Logger.Severity.WARNING)
KratosUnittest.main()
Loading