1 #include "otsdaq-core/ConfigurationInterface/ConfigurationTree.h"
5 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
6 #include "otsdaq-core/Macros/StringMacros.h"
7 #include "otsdaq-core/TableCore/TableBase.h"
12 #define __MF_SUBJECT__ "ConfigurationTree"
14 const std::string ConfigurationTree::DISCONNECTED_VALUE =
"X";
15 const std::string ConfigurationTree::VALUE_TYPE_DISCONNECTED =
"Disconnected";
16 const std::string ConfigurationTree::VALUE_TYPE_NODE =
"Node";
19 ConfigurationTree::ConfigurationTree()
23 , linkParentConfig_(0)
28 , disconnectedTargetName_(
"")
29 , disconnectedLinkID_(
"")
65 const std::string& groupId,
67 const std::string& linkColName,
68 const std::string& linkColValue,
69 const unsigned int linkBackRow,
70 const unsigned int linkBackCol,
71 const std::string& disconnectedTargetName,
72 const std::string& disconnectedLinkID,
73 const std::string& childLinkIndex,
74 const unsigned int row,
75 const unsigned int col)
76 : configMgr_(configMgr)
79 , linkParentConfig_(linkParentConfig)
80 , linkColName_(linkColName)
81 , linkColValue_(linkColValue)
82 , linkBackRow_(linkBackRow)
83 , linkBackCol_(linkBackCol)
84 , disconnectedTargetName_(disconnectedTargetName)
85 , disconnectedLinkID_(disconnectedLinkID)
86 , childLinkIndex_(childLinkIndex)
96 __SS__ <<
"Invalid empty pointer given to tree!\n"
97 <<
"\n\tconfigMgr_=" << configMgr_ <<
"\n\tconfiguration_=" << table_
98 <<
"\n\tconfigView_=" << tableView_ << __E__;
100 ss << nodeDump() << __E__;
105 tableView_ = &(table_->getView());
108 if(tableView_ && tableView_->getColumnInfo(tableView_->getColUID()).getType() !=
109 TableViewColumnInfo::TYPE_UID)
111 __SS__ <<
"Missing UID column (must column of type "
112 << TableViewColumnInfo::TYPE_UID
113 <<
") in config view : " << tableView_->getTableName() << __E__;
115 ss << nodeDump() << __E__;
122 ConfigurationTree::~ConfigurationTree(
void)
133 void ConfigurationTree::print(
const unsigned int& depth, std::ostream& out)
const
135 recursivePrint(*
this, depth, out,
"\t");
145 out << space << t.getValueName() <<
" :\t" << t.getValueAsString() << __E__;
150 out << space << t.getValueName();
151 if(t.isDisconnected())
153 out <<
" :\t" << t.getValueAsString() << __E__;
156 out <<
" (" << (t.isGroupLinkNode() ?
"Group" :
"U")
157 <<
"ID=" << t.getValueAsString() <<
") : " << __E__;
160 out << space << t.getValueAsString() <<
" : " << __E__;
166 auto C = t.getChildren();
168 out << space <<
"{" << __E__;
170 recursivePrint(c.second, depth - 1, out, space +
" ");
172 out << space <<
"}" << __E__;
178 std::string ConfigurationTree::handleValidateValueForColumn(
186 __SS__ <<
"Null configView" << __E__;
188 ss << nodeDump() << __E__;
191 __COUT__ <<
"handleValidateValueForColumn<string>" << __E__;
192 return configView->validateValueForColumn(value, col);
200 void ConfigurationTree::getValue(std::string& value)
const
204 if(row_ != TableView::INVALID &&
205 col_ != TableView::INVALID)
212 __COUT__ <<
"Success following path to tree node!" << __E__;
220 value = tableView_->validateValueForColumn(valueAsTreeNode.getValueAsString(),
223 __COUT__ <<
"Successful value!" << __E__;
237 tableView_->getValue(value, row_, col_);
239 else if(row_ == TableView::INVALID &&
240 col_ == TableView::INVALID)
242 if(isLinkNode() && isDisconnected())
244 (groupId_ ==
"") ? getValueName() : groupId_;
248 value = (groupId_ ==
"") ? table_->getTableName() : groupId_;
250 else if(row_ == TableView::INVALID)
252 __SS__ <<
"Malformed ConfigurationTree" << __E__;
255 else if(col_ == TableView::INVALID)
256 tableView_->getValue(value, row_, tableView_->getColUID());
259 __SS__ <<
"Impossible." << __E__;
277 std::string ConfigurationTree::getValue()
const
280 ConfigurationTree::getValue(value);
293 if(row_ != TableView::INVALID &&
294 col_ != TableView::INVALID)
296 std::string bitmapString;
297 tableView_->getValue(bitmapString, row_, col_);
299 __COUTV__(bitmapString);
300 if(bitmapString == TableViewColumnInfo::DATATYPE_STRING_DEFAULT)
302 bitmap.isDefault_ =
true;
306 bitmap.isDefault_ =
false;
310 bitmap.bitmap_.clear();
312 bool openRow =
false;
313 unsigned int startInt = -1;
314 for(
unsigned int i = 0; i < bitmapString.length(); i++)
316 __COUTV__(bitmapString[i]);
324 if(bitmapString[i] ==
'[')
328 bitmap.bitmap_.push_back(std::vector<uint64_t>());
330 else if(bitmapString[i] ==
']')
334 else if(bitmapString[i] ==
',')
338 <<
"Too many ']' or ',' characters in bit map configuration"
341 ss << nodeDump() << __E__;
345 else if(startInt == (
unsigned int)-1)
347 if(bitmapString[i] ==
']')
352 else if(bitmapString[i] >=
'0' &&
353 bitmapString[i] <=
'9')
357 else if(bitmapString[i] ==
',')
359 __SS__ <<
"Too many ',' characters in bit map configuration"
362 ss << nodeDump() << __E__;
370 if(bitmapString[i] ==
374 bitmap.bitmap_[row].push_back(strtoul(
375 bitmapString.substr(startInt, i - startInt).c_str(), 0, 0));
378 else if(bitmapString[i] ==
',')
380 bitmap.bitmap_[row].push_back(strtoul(
381 bitmapString.substr(startInt, i - startInt).c_str(), 0, 0));
387 for(
unsigned int r = 0; r < bitmap.bitmap_.size(); ++r)
389 for(
unsigned int c = 0; c < bitmap.bitmap_[r].size(); ++c)
391 __COUT__ << r <<
"," << c <<
" = " << bitmap.bitmap_[r][c] << __E__;
393 __COUT__ <<
"================" << __E__;
399 __SS__ <<
"Requesting getValue must be on a value node." << __E__;
401 ss << nodeDump() << __E__;
413 ConfigurationTree::getValueAsBitMap(value);
420 std::string ConfigurationTree::getEscapedValue()
const
422 if(row_ != TableView::INVALID &&
423 col_ != TableView::INVALID)
424 return tableView_->getEscapedValueAsString(row_, col_);
426 __SS__ <<
"Can not get escaped value except from a value node!"
427 <<
" This node is type '" << getNodeType() <<
"." << __E__;
429 ss << nodeDump() << __E__;
435 const std::string& ConfigurationTree::getTableName(
void)
const
439 __SS__ <<
"Can not get configuration name of node with no configuration pointer! "
440 <<
"Is there a broken link? " << __E__;
441 if(linkParentConfig_)
443 ss <<
"Error occurred traversing from " << linkParentConfig_->getTableName()
445 << linkParentConfig_->getView().getValueAsString(
446 linkBackRow_, linkParentConfig_->getView().getColUID())
447 <<
"' at row " << linkBackRow_ <<
" col '"
448 << linkParentConfig_->getView().getColumnInfo(linkBackCol_).getName()
451 ss << StringMacros::stackTrace() << __E__;
456 return table_->getTableName();
464 const std::string& ConfigurationTree::getFieldTableName(
void)
const
469 if(!linkParentConfig_)
471 __SS__ <<
"Can not get configuration name of link node field with no parent "
472 "configuration pointer!"
474 ss << nodeDump() << __E__;
477 return linkParentConfig_->getTableName();
480 return getTableName();
485 const std::string& ConfigurationTree::getDisconnectedTableName(
void)
const
487 if(isLinkNode() && isDisconnected())
488 return disconnectedTargetName_;
490 __SS__ <<
"Can not get disconnected target name of node unless it is a disconnected "
494 ss << nodeDump() << __E__;
500 const std::string& ConfigurationTree::getDisconnectedLinkID(
void)
const
502 if(isLinkNode() && isDisconnected())
503 return disconnectedLinkID_;
505 __SS__ <<
"Can not get disconnected target name of node unless it is a disconnected "
509 ss << nodeDump() << __E__;
515 const TableVersion& ConfigurationTree::getTableVersion(
void)
const
519 __SS__ <<
"Can not get configuration version of node with no config view pointer!"
522 ss << nodeDump() << __E__;
525 return tableView_->getVersion();
530 const time_t& ConfigurationTree::getTableCreationTime(
void)
const
534 __SS__ <<
"Can not get configuration creation time of node with no config view "
538 ss << nodeDump() << __E__;
541 return tableView_->getCreationTime();
548 std::vector<std::string> ConfigurationTree::getFixedChoices(
void)
const
550 if(getValueType() != TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA &&
551 getValueType() != TableViewColumnInfo::TYPE_BITMAP_DATA && !isLinkNode())
553 __SS__ <<
"Can not get fixed choices of node with value type of '"
554 << getValueType() <<
".' Node must be a link or a value node with type '"
555 << TableViewColumnInfo::TYPE_BITMAP_DATA <<
"' or '"
556 << TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA <<
".'" << __E__;
558 ss << nodeDump() << __E__;
562 std::vector<std::string> retVec;
566 if(!linkParentConfig_)
569 <<
"Can not get fixed choices of node with no parent config view pointer!"
572 ss << nodeDump() << __E__;
582 const TableView* parentView = &(linkParentConfig_->getView());
583 int c = parentView->findCol(linkColName_);
585 std::pair<
unsigned int ,
unsigned int > linkPair;
587 parentView->getChildLink(c, isGroupLink, linkPair);
590 std::vector<std::string> choices = parentView->getColumnInfo(c).getDataChoices();
591 for(
const auto& choice : choices)
592 retVec.push_back(choice);
599 __SS__ <<
"Can not get fixed choices of node with no config view pointer!"
602 ss << nodeDump() << __E__;
607 retVec.push_back(tableView_->getColumnInfo(col_).getDefaultValue());
608 std::vector<std::string> choices = tableView_->getColumnInfo(col_).getDataChoices();
609 for(
const auto& choice : choices)
610 retVec.push_back(choice);
623 const std::string& ConfigurationTree::getValueAsString(
bool returnLinkTableValue)
const
627 if(returnLinkTableValue)
628 return linkColValue_;
629 else if(isDisconnected())
630 return ConfigurationTree::DISCONNECTED_VALUE;
631 else if(row_ == TableView::INVALID &&
632 col_ == TableView::INVALID)
633 return (groupId_ ==
"") ? table_->getTableName() : groupId_;
634 else if(col_ == TableView::INVALID)
635 return tableView_->getDataView()[row_][tableView_->getColUID()];
638 __SS__ <<
"Impossible Link." << __E__;
640 ss << nodeDump() << __E__;
644 else if(row_ != TableView::INVALID &&
645 col_ != TableView::INVALID)
646 return tableView_->getDataView()[row_][col_];
647 else if(row_ == TableView::INVALID &&
648 col_ == TableView::INVALID)
649 return (groupId_ ==
"") ? table_->getTableName() : groupId_;
650 else if(row_ == TableView::INVALID)
652 __SS__ <<
"Malformed ConfigurationTree" << __E__;
654 ss << nodeDump() << __E__;
657 else if(col_ == TableView::INVALID)
658 return tableView_->getDataView()[row_][tableView_->getColUID()];
661 __SS__ <<
"Impossible." << __E__;
663 ss << nodeDump() << __E__;
672 const std::string& ConfigurationTree::getUIDAsString(
void)
const
674 if(isValueNode() || isUIDLinkNode())
675 return tableView_->getDataView()[row_][tableView_->getColUID()];
678 __SS__ <<
"Can not get UID of node with type '" << getNodeType()
679 <<
".' Node type must be '" << ConfigurationTree::NODE_TYPE_VALUE
680 <<
"' or '" << ConfigurationTree::NODE_TYPE_UID_LINK <<
".'" << __E__;
682 ss << nodeDump() << __E__;
690 const std::string& ConfigurationTree::getValueDataType(
void)
const
693 return tableView_->getColumnInfo(col_).getDataType();
695 return TableViewColumnInfo::DATATYPE_STRING;
701 bool ConfigurationTree::isDefaultValue(
void)
const
706 if(getValueDataType() == TableViewColumnInfo::DATATYPE_STRING)
708 if(getValueType() == TableViewColumnInfo::TYPE_ON_OFF ||
709 getValueType() == TableViewColumnInfo::TYPE_TRUE_FALSE ||
710 getValueType() == TableViewColumnInfo::TYPE_YES_NO)
711 return getValueAsString() ==
712 TableViewColumnInfo::DATATYPE_BOOL_DEFAULT;
714 else if(getValueType() == TableViewColumnInfo::TYPE_COMMENT)
715 return getValueAsString() == TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT ||
716 getValueAsString() ==
719 return getValueAsString() == TableViewColumnInfo::DATATYPE_STRING_DEFAULT;
721 else if(getValueDataType() == TableViewColumnInfo::DATATYPE_NUMBER)
722 return getValueAsString() == TableViewColumnInfo::DATATYPE_NUMBER_DEFAULT;
723 else if(getValueDataType() == TableViewColumnInfo::DATATYPE_TIME)
724 return getValueAsString() == TableViewColumnInfo::DATATYPE_TIME_DEFAULT;
732 const std::string& ConfigurationTree::getValueType(
void)
const
735 return tableView_->getColumnInfo(col_).getType();
736 else if(isLinkNode() && isDisconnected())
737 return ConfigurationTree::VALUE_TYPE_DISCONNECTED;
739 return ConfigurationTree::VALUE_TYPE_NODE;
748 return tableView_->getColumnInfo(col_);
751 __SS__ <<
"Can only get column info from a value node! "
752 <<
"The node type is " << getNodeType() << __E__;
754 ss << nodeDump() << __E__;
761 const unsigned int& ConfigurationTree::getRow(
void)
const {
return row_; }
765 const unsigned int& ConfigurationTree::getColumn(
void)
const {
return col_; }
770 const unsigned int& ConfigurationTree::getFieldRow(
void)
const
784 const unsigned int& ConfigurationTree::getFieldColumn(
void)
const
797 const std::string& ConfigurationTree::getChildLinkIndex(
void)
const
801 __SS__ <<
"Can only get link ID from a link! "
802 <<
"The node type is " << getNodeType() << __E__;
804 ss << nodeDump() << __E__;
807 return childLinkIndex_;
813 const std::string& ConfigurationTree::getValueName(
void)
const
816 return tableView_->getColumnInfo(col_).getName();
817 else if(isLinkNode())
821 __SS__ <<
"Can only get value name of a value node!" << __E__;
823 ss << nodeDump() << __E__;
832 const std::string& childPath,
833 bool doNotThrowOnBrokenUIDLinks,
834 const std::string& originalNodeString)
838 if(childPath.length() <= 1)
840 return tree.recursiveGetNode(
841 childPath, doNotThrowOnBrokenUIDLinks, originalNodeString);
880 bool doNotThrowOnBrokenUIDLinks)
const
882 return recursiveGetNode(
883 nodeString, doNotThrowOnBrokenUIDLinks,
"" );
886 const std::string& nodeString,
887 bool doNotThrowOnBrokenUIDLinks,
888 const std::string& originalNodeString)
const
895 if(nodeString.length() < 1)
897 __SS__ <<
"Invalid empty node name! Looking for child node from node '"
898 << getValue() <<
"'..." << __E__;
900 ss << nodeDump() << __E__;
904 bool startingSlash = nodeString[0] ==
'/';
906 std::string nodeName = nodeString.substr(
907 startingSlash ? 1 : 0, nodeString.find(
'/', 1) - (startingSlash ? 1 : 0));
910 std::string childPath =
911 nodeString.substr(nodeName.length() + (startingSlash ? 1 : 0));
924 return recurse(configMgr_->getNode(nodeName),
926 doNotThrowOnBrokenUIDLinks,
929 else if(row_ == TableView::INVALID && col_ == TableView::INVALID)
935 __SS__ <<
"Missing configView pointer! Likely attempting to access a "
936 "child node through a disconnected link node."
939 ss << nodeDump() << __E__;
959 ? tableView_->findRow(tableView_->getColUID(), nodeName)
960 : tableView_->findRowInGroup(tableView_->getColUID(),
965 doNotThrowOnBrokenUIDLinks,
968 else if(row_ == TableView::INVALID)
970 __SS__ <<
"Malformed ConfigurationTree" << __E__;
972 ss << nodeDump() << __E__;
975 else if(col_ == TableView::INVALID)
991 __SS__ <<
"Missing configView pointer! Likely attempting to access a "
992 "child node through a disconnected link node."
995 ss << nodeDump() << __E__;
999 unsigned int c = tableView_->findCol(nodeName);
1000 std::pair<
unsigned int ,
unsigned int > linkPair;
1001 bool isGroupLink, isLink;
1002 if((isLink = tableView_->getChildLink(c, isGroupLink, linkPair)) &&
1013 childConfig = configMgr_->getTableByName(
1014 tableView_->getDataView()[row_][linkPair.first]);
1015 childConfig->getView();
1017 if(doNotThrowOnBrokenUIDLinks)
1019 childConfig->getView().findRow(
1020 childConfig->getView().getColUID(),
1021 tableView_->getDataView()[row_][linkPair.second]);
1040 tableView_->getDataView()[row_][c],
1045 tableView_->getDataView()[row_][linkPair.first],
1048 tableView_->getDataView()[row_][linkPair.second],
1051 tableView_->getColumnInfo(c).getChildLinkIndex());
1061 tableView_->getDataView()[row_][c],
1068 tableView_->getColumnInfo(c).getChildLinkIndex(),
1069 childConfig->getView().findRow(
1070 childConfig->getView().getColUID(),
1071 tableView_->getDataView()[row_][linkPair.second])),
1073 doNotThrowOnBrokenUIDLinks,
1074 originalNodeString);
1086 childConfig = configMgr_->getTableByName(
1087 tableView_->getDataView()[row_][linkPair.first]);
1088 childConfig->getView();
1092 if(tableView_->getDataView()[row_][linkPair.first] !=
1093 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
1095 <<
"Found disconnected node! Failed link target "
1097 << nodeName <<
" to table:id="
1098 << tableView_->getDataView()[row_][linkPair.first] <<
":"
1099 << tableView_->getDataView()[row_][linkPair.second] << __E__;
1105 tableView_->getDataView()[row_][linkPair.second],
1108 tableView_->getDataView()[row_][c],
1113 tableView_->getDataView()[row_][linkPair.first],
1116 tableView_->getDataView()[row_][linkPair.second],
1119 tableView_->getColumnInfo(c).getChildLinkIndex());
1127 ->getDataView()[row_][linkPair.second],
1130 tableView_->getDataView()[row_][c],
1137 tableView_->getColumnInfo(c).getChildLinkIndex()),
1139 doNotThrowOnBrokenUIDLinks,
1140 originalNodeString);
1152 TableView::INVALID ,
1153 TableView::INVALID ,
1162 catch(std::runtime_error& e)
1164 __SS__ <<
"\n\nError occurred descending from node '" << getValue()
1165 <<
"' in table '" << getTableName() <<
"' looking for child '" << nodeName
1168 ss <<
"The original node search string was '" << originalNodeString <<
".'"
1170 ss <<
"--- Additional error detail: \n\n" << e.what() << __E__;
1172 ss << nodeDump() << __E__;
1177 __SS__ <<
"\n\nError occurred descending from node '" << getValue()
1178 <<
"' in table '" << getTableName() <<
"' looking for child '" << nodeName
1181 ss <<
"The original node search string was '" << originalNodeString <<
".'"
1184 ss << nodeDump() << __E__;
1190 <<
"\n\nError occurred descending from node '" << getValue() <<
"' in table '"
1191 << getTableName() <<
"' looking for child '" << nodeName <<
"'\n\n"
1192 <<
"Invalid depth! getNode() called from a value point in the Configuration Tree."
1194 ss <<
"The original node search string was '" << originalNodeString <<
".'" << __E__;
1196 ss << nodeDump() << __E__;
1203 std::string ConfigurationTree::nodeDump(
void)
const
1205 __SS__ <<
"ConfigurationTree::nodeDump() "
1206 "=====================================\nConfigurationTree::nodeDump():"
1213 <<
"Error occurred from node '" << getValueAsString() <<
"'..." << __E__;
1221 <<
"Error occurred from node '" << getValue() <<
"' in table '"
1222 << getTableName() <<
".'" << __E__;
1229 auto children = getChildrenNames();
1231 <<
"Here is the list of possible children (count = " << children.size()
1233 for(
auto& child : children)
1234 ss <<
"\t\t" << child << __E__;
1237 ss <<
"\n\nHere is the culprit table printout:\n\n";
1238 tableView_->print(ss);
1247 ss <<
"\n\n" << StringMacros::stackTrace() << __E__;
1253 ss <<
"end ConfigurationTree::nodeDump() ====================================="
1261 unsigned int backSteps)
const
1263 for(
unsigned int i = 0; i < backSteps; i++)
1264 nodeName = nodeName.substr(0, nodeName.find_last_of(
'/'));
1266 return getNode(nodeName);
1271 unsigned int forwardSteps)
const
1276 while(s < nodeName.length() && nodeName[s] ==
'/')
1279 for(
unsigned int i = 0; i < forwardSteps; i++)
1280 s = nodeName.find(
'/', s) + 1;
1282 return getNode(nodeName.substr(0, s));
1288 bool ConfigurationTree::isValueNode(
void)
const
1290 return (row_ != TableView::INVALID && col_ != TableView::INVALID);
1296 bool ConfigurationTree::isValueBoolType(
void)
const
1298 return isValueNode() && tableView_->getColumnInfo(col_).isBoolType();
1304 bool ConfigurationTree::isValueNumberDataType(
void)
const
1306 return isValueNode() && tableView_->getColumnInfo(col_).isNumberDataType();
1314 bool ConfigurationTree::isDisconnected(
void)
const
1318 __SS__ <<
"\n\nError occurred testing link connection at node with value '"
1319 << getValue() <<
"' in table '" << getTableName() <<
"'\n\n"
1321 ss <<
"This is not a Link node! It is node type '" << getNodeType()
1322 <<
".' Only a Link node can be disconnected." << __E__;
1324 ss << nodeDump() << __E__;
1328 return !table_ || !tableView_;
1334 bool ConfigurationTree::isLinkNode(
void)
const {
return linkColName_ !=
""; }
1339 const std::string ConfigurationTree::NODE_TYPE_GROUP_TABLE =
"GroupTableNode";
1340 const std::string ConfigurationTree::NODE_TYPE_TABLE =
"TableNode";
1341 const std::string ConfigurationTree::NODE_TYPE_GROUP_LINK =
"GroupLinkNode";
1342 const std::string ConfigurationTree::NODE_TYPE_UID_LINK =
"UIDLinkNode";
1343 const std::string ConfigurationTree::NODE_TYPE_VALUE =
"ValueNode";
1344 const std::string ConfigurationTree::NODE_TYPE_UID =
"UIDNode";
1345 const std::string ConfigurationTree::NODE_TYPE_ROOT =
"RootNode";
1347 std::string ConfigurationTree::getNodeType(
void)
const
1350 return ConfigurationTree::NODE_TYPE_ROOT;
1351 if(isConfigurationNode() && groupId_ !=
"")
1352 return ConfigurationTree::NODE_TYPE_GROUP_TABLE;
1353 if(isConfigurationNode())
1354 return ConfigurationTree::NODE_TYPE_TABLE;
1355 if(isGroupLinkNode())
1356 return ConfigurationTree::NODE_TYPE_GROUP_LINK;
1358 return ConfigurationTree::NODE_TYPE_UID_LINK;
1360 return ConfigurationTree::NODE_TYPE_VALUE;
1361 return ConfigurationTree::NODE_TYPE_UID;
1367 bool ConfigurationTree::isGroupLinkNode(
void)
const
1369 return (isLinkNode() && groupId_ !=
"");
1375 bool ConfigurationTree::isUIDLinkNode(
void)
const
1377 return (isLinkNode() && groupId_ ==
"");
1383 bool ConfigurationTree::isUIDNode(
void)
const
1385 return (row_ != TableView::INVALID && col_ == TableView::INVALID);
1404 std::vector<ConfigurationTree::RecordField> ConfigurationTree::getCommonFields(
1405 const std::vector<std::string /*uid*/>& recordList,
1406 const std::vector<std::string /*relative-path*/>& fieldAcceptList,
1407 const std::vector<std::string /*relative-path*/>& fieldRejectList,
1409 bool autoSelectFilterFields)
const
1412 if(!isRootNode() && !isConfigurationNode())
1414 __SS__ <<
"Can only get getCommonFields from a root or table node! "
1415 <<
"The node type is " << getNodeType() << __E__;
1417 ss << nodeDump() << __E__;
1421 std::vector<ConfigurationTree::RecordField> fieldCandidateList;
1422 std::vector<int> fieldCount;
1465 for(
unsigned int i = 0; i < recordList.size(); ++i)
1469 auto recordChildren = getNode(recordList[i]).getChildren();
1470 for(
const auto& fieldNode : recordChildren)
1475 if(fieldNode.second.isValueNode() || fieldNode.second.isGroupLinkNode())
1478 if(fieldNode.second.isValueNode())
1480 if(fieldNode.second.getColumnInfo().getType() ==
1481 TableViewColumnInfo::TYPE_AUTHOR ||
1482 fieldNode.second.getColumnInfo().getType() ==
1483 TableViewColumnInfo::TYPE_TIMESTAMP)
1492 found = fieldAcceptList.size() ?
false
1494 for(
const auto& fieldFilter : fieldAcceptList)
1495 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1506 for(
const auto& fieldFilter : fieldRejectList)
1507 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1518 if(fieldNode.second.isGroupLinkNode())
1524 std::pair<
unsigned int ,
1528 tableView_->getChildLink(tableView_->findCol(fieldNode.first),
1535 table_->getTableName(),
1537 tableView_->getColumnInfo(linkPair.first).getName(),
1539 &tableView_->getColumnInfo(linkPair.first)));
1540 fieldCount.push_back(-1);
1543 table_->getTableName(),
1545 tableView_->getColumnInfo(linkPair.second).getName(),
1547 &tableView_->getColumnInfo(linkPair.second)));
1548 fieldCount.push_back(-1);
1553 fieldNode.second.getTableName(),
1557 &fieldNode.second.getColumnInfo()));
1558 fieldCount.push_back(-1);
1565 else if(depth > 0 && fieldNode.second.isUIDLinkNode())
1575 found = fieldAcceptList.size() ?
false
1577 for(
const auto& fieldFilter : fieldAcceptList)
1578 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1589 for(
const auto& fieldFilter : fieldRejectList)
1590 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1601 std::pair<
unsigned int ,
unsigned int >
1604 tableView_->getChildLink(
1605 tableView_->findCol(fieldNode.first), isGroupLink, linkPair);
1610 table_->getTableName(),
1612 tableView_->getColumnInfo(linkPair.first).getName(),
1614 &tableView_->getColumnInfo(linkPair.first)));
1615 fieldCount.push_back(-1);
1618 table_->getTableName(),
1620 tableView_->getColumnInfo(linkPair.second).getName(),
1622 &tableView_->getColumnInfo(linkPair.second)));
1623 fieldCount.push_back(-1);
1629 if(!fieldNode.second.isDisconnected())
1630 fieldNode.second.recursiveGetCommonFields(
1636 fieldNode.first +
"/",
1648 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1653 if(fieldCount[i] != -1 && fieldCount[i] != (
int)recordList.size())
1658 fieldCount.erase(fieldCount.begin() + i);
1659 fieldCandidateList.erase(fieldCandidateList.begin() + i);
1668 if(autoSelectFilterFields)
1672 std::set<std::pair<
unsigned int ,
unsigned int >>
1675 unsigned int highestPriority = 0;
1676 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1684 if(fieldCandidateList[i].columnInfo_->isBoolType())
1685 prioritySet.emplace(
1686 std::make_pair(0 , i ));
1687 else if(fieldCandidateList[i].columnInfo_->isGroupID())
1689 prioritySet.emplace(
1690 std::make_pair(1 , i ));
1691 if(highestPriority < 1)
1692 highestPriority = 1;
1694 else if(fieldCandidateList[i].columnInfo_->getType() ==
1695 TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA)
1697 prioritySet.emplace(
1698 std::make_pair(3 , i ));
1699 if(highestPriority < 3)
1700 highestPriority = 3;
1702 else if(fieldCandidateList[i].columnInfo_->getType() ==
1703 TableViewColumnInfo::TYPE_DATA)
1705 prioritySet.emplace(
1706 std::make_pair(10 , i ));
1707 if(highestPriority < 10)
1708 highestPriority = 10;
1712 fieldCandidateList[i].tableName_ =
1719 __COUTV__(StringMacros::setToString(prioritySet));
1724 unsigned int cnt = 0;
1725 for(
const auto& priorityFieldIndex : prioritySet)
1735 fieldCandidateList[priorityFieldIndex.second].tableName_ =
1740 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1742 if(fieldCandidateList[i].tableName_ ==
"")
1747 fieldCandidateList.erase(fieldCandidateList.begin() + i);
1753 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1754 __COUT__ <<
"Final " << fieldCandidateList[i].relativePath_
1755 << fieldCandidateList[i].columnName_ << __E__;
1757 return fieldCandidateList;
1765 std::set<std::string > ConfigurationTree::getUniqueValuesForField(
1766 const std::vector<std::string /*relative-path*/>& recordList,
1767 const std::string& fieldName)
const
1770 if(!isConfigurationNode())
1772 __SS__ <<
"Can only get getCommonFields from a table node! "
1773 <<
"The node type is " << getNodeType() << __E__;
1775 ss << nodeDump() << __E__;
1779 std::set<std::string > uniqueValues;
1786 for(
unsigned int i = 0; i < recordList.size(); ++i)
1788 __COUT__ <<
"Checking " << recordList[i] << __E__;
1796 uniqueValues.emplace(
1797 getNode(recordList[i]).getNode(fieldName).getValueAsString(
true));
1800 return uniqueValues;
1806 void ConfigurationTree::recursiveGetCommonFields(
1807 std::vector<ConfigurationTree::RecordField>& fieldCandidateList,
1808 std::vector<int>& fieldCount,
1809 const std::vector<std::string /*relative-path*/>& fieldAcceptList,
1810 const std::vector<std::string /*relative-path*/>& fieldRejectList,
1812 const std::string& relativePathBase,
1813 bool inFirstRecord)
const
1837 auto tableName = getTableName();
1838 auto uid = getUIDAsString();
1841 auto recordChildren = getChildren();
1842 for(
const auto& fieldNode : recordChildren)
1847 if(fieldNode.second.isValueNode())
1850 if(fieldNode.second.getColumnInfo().getType() ==
1851 TableViewColumnInfo::TYPE_AUTHOR ||
1852 fieldNode.second.getColumnInfo().getType() ==
1853 TableViewColumnInfo::TYPE_TIMESTAMP)
1860 found = fieldAcceptList.size() ?
false :
true;
1862 for(
const auto& fieldFilter : fieldAcceptList)
1863 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1874 for(
const auto& fieldFilter : fieldRejectList)
1875 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1892 &fieldNode.second.getColumnInfo()));
1893 fieldCount.push_back(1);
1900 for(j = 0; j < fieldCandidateList.size(); ++j)
1902 if((relativePathBase + fieldNode.first) ==
1903 (fieldCandidateList[j].relativePath_ +
1904 fieldCandidateList[j].columnName_))
1915 else if(depth > 0 && fieldNode.second.isUIDLinkNode() &&
1916 !fieldNode.second.isDisconnected())
1920 fieldNode.second.recursiveGetCommonFields(
1926 (relativePathBase + fieldNode.first) +
"/",
1939 std::vector<std::vector<std::pair<std::string, ConfigurationTree>>>
1940 ConfigurationTree::getChildrenByPriority(
1941 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
1942 bool onlyStatusTrue)
const
1944 std::vector<std::vector<std::pair<std::string, ConfigurationTree>>> retVector;
1948 bool filtering = filterMap.size();
1950 std::string fieldValue;
1952 bool createContainer;
1954 std::vector<std::vector<std::string>> childrenNamesByPriority =
1955 getChildrenNamesByPriority(onlyStatusTrue);
1957 for(
auto& childNamesAtPriority : childrenNamesByPriority)
1959 createContainer =
true;
1961 for(
auto& childName : childNamesAtPriority)
1971 for(
const auto& filterPair : filterMap)
1973 std::string filterPath = childName +
"/" + filterPair.first;
1974 __COUTV__(filterPath);
1978 std::vector<std::string> fieldValues;
1979 StringMacros::getVectorFromString(
1982 std::set<char>({
','}) );
1984 __COUTV__(fieldValues.size());
1988 for(
const auto& fieldValue : fieldValues)
1999 __COUT__ <<
"\t\tCheck: " << filterPair.first
2000 <<
" == " << fieldValue <<
" => "
2001 << StringMacros::decodeURIComponent(fieldValue)
2003 << this->getNode(filterPath).getValueAsString(
true)
2006 if(StringMacros::wildCardMatch(
2007 StringMacros::decodeURIComponent(fieldValue),
2008 this->getNode(filterPath).getValueAsString(
true)))
2018 __SS__ <<
"Failed to access filter path '" << filterPath
2019 <<
"' - aborting." << __E__;
2021 ss << nodeDump() << __E__;
2038 retVector.push_back(
2039 std::vector<std::pair<std::string, ConfigurationTree>>());
2040 createContainer =
false;
2043 retVector[retVector.size() - 1].push_back(
2044 std::pair<std::string, ConfigurationTree>(
2045 childName, this->getNode(childName,
true)));
2059 std::vector<std::pair<std::string, ConfigurationTree>> ConfigurationTree::getChildren(
2060 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
2062 bool onlyStatusTrue)
const
2064 std::vector<std::pair<std::string, ConfigurationTree>> retVector;
2068 bool filtering = filterMap.size();
2070 std::string fieldValue;
2072 std::vector<std::string> childrenNames = getChildrenNames(byPriority, onlyStatusTrue);
2073 for(
auto& childName : childrenNames)
2083 for(
const auto& filterPair : filterMap)
2085 std::string filterPath = childName +
"/" + filterPair.first;
2086 __COUTV__(filterPath);
2090 std::vector<std::string> fieldValues;
2091 StringMacros::getVectorFromString(
2094 std::set<char>({
','}) );
2096 __COUTV__(fieldValues.size());
2100 for(
const auto& fieldValue : fieldValues)
2111 <<
"\t\tCheck: " << filterPair.first <<
" == " << fieldValue
2112 <<
" => " << StringMacros::decodeURIComponent(fieldValue)
2113 <<
" ??? " << this->getNode(filterPath).getValueAsString(
true)
2116 if(StringMacros::wildCardMatch(
2117 StringMacros::decodeURIComponent(fieldValue),
2118 this->getNode(filterPath).getValueAsString(
true)))
2128 __SS__ <<
"Failed to access filter path '" << filterPath
2129 <<
"' - aborting." << __E__;
2131 ss << nodeDump() << __E__;
2146 retVector.push_back(std::pair<std::string, ConfigurationTree>(
2147 childName, this->getNode(childName,
true)));
2157 std::map<std::string, ConfigurationTree> ConfigurationTree::getChildrenMap(
void)
const
2159 std::map<std::string, ConfigurationTree> retMap;
2163 std::vector<std::string> childrenNames = getChildrenNames();
2164 for(
auto& childName : childrenNames)
2167 retMap.insert(std::pair<std::string, ConfigurationTree>(
2168 childName, this->getNode(childName)));
2176 bool ConfigurationTree::isRootNode(
void)
const {
return (!table_); }
2179 bool ConfigurationTree::isConfigurationNode(
void)
const
2181 return (table_ && row_ == TableView::INVALID && col_ == TableView::INVALID);
2187 std::vector<std::vector<std::string>> ConfigurationTree::getChildrenNamesByPriority(
2188 bool onlyStatusTrue)
const
2190 std::vector<std::vector<std::string >> retVector;
2194 __SS__ <<
"Can not get children names of '" << getValueAsString()
2195 <<
"' with null configuration view pointer!" << __E__;
2196 if(isLinkNode() && isDisconnected())
2197 ss <<
" This node is a disconnected link to " << getDisconnectedTableName()
2200 ss << nodeDump() << __E__;
2204 if(row_ == TableView::INVALID && col_ == TableView::INVALID)
2215 std::map<uint64_t , std::vector<
unsigned int >>
2217 std::vector<std::string > retPrioritySet;
2219 unsigned int col = tableView_->getColPriority();
2221 uint64_t tmpPriority;
2223 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2224 if(groupId_ ==
"" ||
2225 tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2230 tableView_->getValue(
2231 tmpStatus, r, tableView_->getColStatus());
2236 tableView_->getValue(tmpPriority, r, col);
2238 orderedByPriority[tmpPriority ? tmpPriority : 100].push_back(r);
2244 for(
const auto& priorityChildRowVector : orderedByPriority)
2246 retVector.push_back(std::vector<std::string /*child name*/>());
2247 for(
const auto& priorityChildRow : priorityChildRowVector.second)
2248 retVector[retVector.size() - 1].push_back(
2249 tableView_->getDataView()[priorityChildRow]
2250 [tableView_->getColUID()]);
2253 __COUT__ <<
"Returning priority children list." << __E__;
2256 catch(std::runtime_error& e)
2258 __COUT_WARN__ <<
"Error identifying priority. Assuming all children have "
2259 "equal priority (Error: "
2260 << e.what() << __E__;
2266 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2267 if(groupId_ ==
"" || tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2272 tableView_->getValue(tmpStatus, r, tableView_->getColStatus());
2277 retVector.push_back(std::vector<std::string /*child name*/>());
2278 retVector[retVector.size() - 1].push_back(
2279 tableView_->getDataView()[r][tableView_->getColUID()]);
2282 else if(row_ == TableView::INVALID)
2284 __SS__ <<
"Malformed ConfigurationTree" << __E__;
2286 ss << nodeDump() << __E__;
2289 else if(col_ == TableView::INVALID)
2294 for(
unsigned int c = 0; c < tableView_->getNumberOfColumns(); ++c)
2295 if(c == tableView_->getColUID() ||
2297 tableView_->getColumnInfo(c).isChildLinkGroupID() ||
2298 tableView_->getColumnInfo(c).isChildLinkUID())
2302 retVector.push_back(std::vector<std::string /*child name*/>());
2303 retVector[retVector.size() - 1].push_back(
2304 tableView_->getColumnInfo(c).getName());
2310 __SS__ <<
"\n\nError occurred looking for children of nodeName=" << getValueName()
2312 <<
"Invalid depth! getChildrenValues() called from a value point in the "
2313 "Configuration Tree."
2316 ss << nodeDump() << __E__;
2326 std::vector<std::string> ConfigurationTree::getChildrenNames(
bool byPriority,
2327 bool onlyStatusTrue)
const
2329 std::vector<std::string > retVector;
2333 __SS__ <<
"Can not get children names of '" << getValueAsString()
2334 <<
"' with null configuration view pointer!" << __E__;
2335 if(isLinkNode() && isDisconnected())
2336 ss <<
" This node is a disconnected link to " << getDisconnectedTableName()
2341 if(row_ == TableView::INVALID && col_ == TableView::INVALID)
2352 std::map<uint64_t , std::vector<
unsigned int >>
2354 std::vector<std::string > retPrioritySet;
2356 unsigned int col = tableView_->getColPriority();
2358 uint64_t tmpPriority;
2360 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2361 if(groupId_ ==
"" ||
2362 tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2367 tableView_->getValue(
2368 tmpStatus, r, tableView_->getColStatus());
2374 tableView_->getValue(tmpPriority, r, col);
2376 orderedByPriority[tmpPriority ? tmpPriority : 100].push_back(r);
2382 for(
const auto& priorityChildRowVector : orderedByPriority)
2383 for(
const auto& priorityChildRow : priorityChildRowVector.second)
2384 retVector.push_back(
2385 tableView_->getDataView()[priorityChildRow]
2386 [tableView_->getColUID()]);
2388 __COUT__ <<
"Returning priority children list." << __E__;
2391 catch(std::runtime_error& e)
2393 __COUT_WARN__ <<
"Priority configuration not found. Assuming all "
2394 "children have equal priority (Error: "
2395 << e.what() << __E__;
2401 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2402 if(groupId_ ==
"" || tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2407 tableView_->getValue(tmpStatus, r, tableView_->getColStatus());
2413 retVector.push_back(
2414 tableView_->getDataView()[r][tableView_->getColUID()]);
2417 else if(row_ == TableView::INVALID)
2419 __SS__ <<
"Malformed ConfigurationTree" << __E__;
2421 ss << nodeDump() << __E__;
2424 else if(col_ == TableView::INVALID)
2429 for(
unsigned int c = 0; c < tableView_->getNumberOfColumns(); ++c)
2430 if(c == tableView_->getColUID() ||
2432 tableView_->getColumnInfo(c).isChildLinkGroupID() ||
2433 tableView_->getColumnInfo(c).isChildLinkUID())
2436 retVector.push_back(tableView_->getColumnInfo(c).getName());
2441 __SS__ <<
"\n\nError occurred looking for children of nodeName=" << getValueName()
2443 <<
"Invalid depth! getChildrenValues() called from a value point in the "
2444 "Configuration Tree."
2447 ss << nodeDump() << __E__;
2465 __SS__ <<
"Invalid node for get value." << __E__;
2469 std::string valueString =
2470 tableView_->getValueAsString(row_, col_,
true );
2472 if(valueString.size() && valueString[0] ==
'/')
2479 __COUT__ <<
"Found a valid tree path in value!" << __E__;
2484 __SS__ <<
"Invalid tree path." << __E__;
2490 __SS__ <<
"Invalid value string '" << valueString
2491 <<
"' - must start with a '/' character." << __E__;