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()
444 <<
" row " << linkBackRow_ <<
" col '"
445 << linkParentConfig_->getView().getColumnInfo(linkBackCol_).getName()
451 return table_->getTableName();
459 const std::string& ConfigurationTree::getFieldTableName(
void)
const
464 if(!linkParentConfig_)
466 __SS__ <<
"Can not get configuration name of link node field with no parent "
467 "configuration pointer!"
469 ss << nodeDump() << __E__;
472 return linkParentConfig_->getTableName();
475 return getTableName();
480 const std::string& ConfigurationTree::getDisconnectedTableName(
void)
const
482 if(isLinkNode() && isDisconnected())
483 return disconnectedTargetName_;
485 __SS__ <<
"Can not get disconnected target name of node unless it is a disconnected "
489 ss << nodeDump() << __E__;
495 const std::string& ConfigurationTree::getDisconnectedLinkID(
void)
const
497 if(isLinkNode() && isDisconnected())
498 return disconnectedLinkID_;
500 __SS__ <<
"Can not get disconnected target name of node unless it is a disconnected "
504 ss << nodeDump() << __E__;
510 const TableVersion& ConfigurationTree::getTableVersion(
void)
const
514 __SS__ <<
"Can not get configuration version of node with no config view pointer!"
517 ss << nodeDump() << __E__;
520 return tableView_->getVersion();
525 const time_t& ConfigurationTree::getTableCreationTime(
void)
const
529 __SS__ <<
"Can not get configuration creation time of node with no config view "
533 ss << nodeDump() << __E__;
536 return tableView_->getCreationTime();
543 std::vector<std::string> ConfigurationTree::getFixedChoices(
void)
const
545 if(getValueType() != TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA &&
546 getValueType() != TableViewColumnInfo::TYPE_BITMAP_DATA && !isLinkNode())
548 __SS__ <<
"Can not get fixed choices of node with value type of '"
549 << getValueType() <<
".' Node must be a link or a value node with type '"
550 << TableViewColumnInfo::TYPE_BITMAP_DATA <<
"' or '"
551 << TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA <<
".'" << __E__;
553 ss << nodeDump() << __E__;
557 std::vector<std::string> retVec;
561 if(!linkParentConfig_)
564 <<
"Can not get fixed choices of node with no parent config view pointer!"
567 ss << nodeDump() << __E__;
577 const TableView* parentView = &(linkParentConfig_->getView());
578 int c = parentView->findCol(linkColName_);
580 std::pair<
unsigned int ,
unsigned int > linkPair;
582 parentView->getChildLink(c, isGroupLink, linkPair);
585 std::vector<std::string> choices = parentView->getColumnInfo(c).getDataChoices();
586 for(
const auto& choice : choices)
587 retVec.push_back(choice);
594 __SS__ <<
"Can not get fixed choices of node with no config view pointer!"
597 ss << nodeDump() << __E__;
602 retVec.push_back(tableView_->getColumnInfo(col_).getDefaultValue());
603 std::vector<std::string> choices = tableView_->getColumnInfo(col_).getDataChoices();
604 for(
const auto& choice : choices)
605 retVec.push_back(choice);
618 const std::string& ConfigurationTree::getValueAsString(
bool returnLinkTableValue)
const
622 if(returnLinkTableValue)
623 return linkColValue_;
624 else if(isDisconnected())
625 return ConfigurationTree::DISCONNECTED_VALUE;
626 else if(row_ == TableView::INVALID &&
627 col_ == TableView::INVALID)
628 return (groupId_ ==
"") ? table_->getTableName() : groupId_;
629 else if(col_ == TableView::INVALID)
630 return tableView_->getDataView()[row_][tableView_->getColUID()];
633 __SS__ <<
"Impossible Link." << __E__;
635 ss << nodeDump() << __E__;
639 else if(row_ != TableView::INVALID &&
640 col_ != TableView::INVALID)
641 return tableView_->getDataView()[row_][col_];
642 else if(row_ == TableView::INVALID &&
643 col_ == TableView::INVALID)
644 return (groupId_ ==
"") ? table_->getTableName() : groupId_;
645 else if(row_ == TableView::INVALID)
647 __SS__ <<
"Malformed ConfigurationTree" << __E__;
649 ss << nodeDump() << __E__;
652 else if(col_ == TableView::INVALID)
653 return tableView_->getDataView()[row_][tableView_->getColUID()];
656 __SS__ <<
"Impossible." << __E__;
658 ss << nodeDump() << __E__;
667 const std::string& ConfigurationTree::getUIDAsString(
void)
const
669 if(isValueNode() || isUIDLinkNode())
670 return tableView_->getDataView()[row_][tableView_->getColUID()];
673 __SS__ <<
"Can not get UID of node with type '" << getNodeType()
674 <<
".' Node type must be '" << ConfigurationTree::NODE_TYPE_VALUE
675 <<
"' or '" << ConfigurationTree::NODE_TYPE_UID_LINK <<
".'" << __E__;
677 ss << nodeDump() << __E__;
685 const std::string& ConfigurationTree::getValueDataType(
void)
const
688 return tableView_->getColumnInfo(col_).getDataType();
690 return TableViewColumnInfo::DATATYPE_STRING;
696 bool ConfigurationTree::isDefaultValue(
void)
const
701 if(getValueDataType() == TableViewColumnInfo::DATATYPE_STRING)
703 if(getValueType() == TableViewColumnInfo::TYPE_ON_OFF ||
704 getValueType() == TableViewColumnInfo::TYPE_TRUE_FALSE ||
705 getValueType() == TableViewColumnInfo::TYPE_YES_NO)
706 return getValueAsString() ==
707 TableViewColumnInfo::DATATYPE_BOOL_DEFAULT;
709 else if(getValueType() == TableViewColumnInfo::TYPE_COMMENT)
710 return getValueAsString() == TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT ||
711 getValueAsString() ==
714 return getValueAsString() == TableViewColumnInfo::DATATYPE_STRING_DEFAULT;
716 else if(getValueDataType() == TableViewColumnInfo::DATATYPE_NUMBER)
717 return getValueAsString() == TableViewColumnInfo::DATATYPE_NUMBER_DEFAULT;
718 else if(getValueDataType() == TableViewColumnInfo::DATATYPE_TIME)
719 return getValueAsString() == TableViewColumnInfo::DATATYPE_TIME_DEFAULT;
727 const std::string& ConfigurationTree::getValueType(
void)
const
730 return tableView_->getColumnInfo(col_).getType();
731 else if(isLinkNode() && isDisconnected())
732 return ConfigurationTree::VALUE_TYPE_DISCONNECTED;
734 return ConfigurationTree::VALUE_TYPE_NODE;
743 return tableView_->getColumnInfo(col_);
746 __SS__ <<
"Can only get column info from a value node! "
747 <<
"The node type is " << getNodeType() << __E__;
749 ss << nodeDump() << __E__;
756 const unsigned int& ConfigurationTree::getRow(
void)
const {
return row_; }
760 const unsigned int& ConfigurationTree::getColumn(
void)
const {
return col_; }
765 const unsigned int& ConfigurationTree::getFieldRow(
void)
const
779 const unsigned int& ConfigurationTree::getFieldColumn(
void)
const
792 const std::string& ConfigurationTree::getChildLinkIndex(
void)
const
796 __SS__ <<
"Can only get link ID from a link! "
797 <<
"The node type is " << getNodeType() << __E__;
799 ss << nodeDump() << __E__;
802 return childLinkIndex_;
808 const std::string& ConfigurationTree::getValueName(
void)
const
811 return tableView_->getColumnInfo(col_).getName();
812 else if(isLinkNode())
816 __SS__ <<
"Can only get value name of a value node!" << __E__;
818 ss << nodeDump() << __E__;
827 const std::string& childPath,
828 bool doNotThrowOnBrokenUIDLinks,
829 const std::string& originalNodeString)
833 if(childPath.length() <= 1)
835 return tree.recursiveGetNode(
836 childPath, doNotThrowOnBrokenUIDLinks, originalNodeString);
875 bool doNotThrowOnBrokenUIDLinks)
const
877 return recursiveGetNode(
878 nodeString, doNotThrowOnBrokenUIDLinks,
"" );
881 const std::string& nodeString,
882 bool doNotThrowOnBrokenUIDLinks,
883 const std::string& originalNodeString)
const
890 if(nodeString.length() < 1)
892 __SS__ <<
"Invalid empty node name! Looking for child node from node '"
893 << getValue() <<
"'..." << __E__;
895 ss << nodeDump() << __E__;
899 bool startingSlash = nodeString[0] ==
'/';
901 std::string nodeName = nodeString.substr(
902 startingSlash ? 1 : 0, nodeString.find(
'/', 1) - (startingSlash ? 1 : 0));
905 std::string childPath =
906 nodeString.substr(nodeName.length() + (startingSlash ? 1 : 0));
919 return recurse(configMgr_->getNode(nodeName),
921 doNotThrowOnBrokenUIDLinks,
924 else if(row_ == TableView::INVALID && col_ == TableView::INVALID)
930 __SS__ <<
"Missing configView pointer! Likely attempting to access a "
931 "child node through a disconnected link node."
934 ss << nodeDump() << __E__;
954 ? tableView_->findRow(tableView_->getColUID(), nodeName)
955 : tableView_->findRowInGroup(tableView_->getColUID(),
960 doNotThrowOnBrokenUIDLinks,
963 else if(row_ == TableView::INVALID)
965 __SS__ <<
"Malformed ConfigurationTree" << __E__;
967 ss << nodeDump() << __E__;
970 else if(col_ == TableView::INVALID)
986 __SS__ <<
"Missing configView pointer! Likely attempting to access a "
987 "child node through a disconnected link node."
990 ss << nodeDump() << __E__;
994 unsigned int c = tableView_->findCol(nodeName);
995 std::pair<
unsigned int ,
unsigned int > linkPair;
996 bool isGroupLink, isLink;
997 if((isLink = tableView_->getChildLink(c, isGroupLink, linkPair)) &&
1008 childConfig = configMgr_->getTableByName(
1009 tableView_->getDataView()[row_][linkPair.first]);
1010 childConfig->getView();
1012 if(doNotThrowOnBrokenUIDLinks)
1014 childConfig->getView().findRow(
1015 childConfig->getView().getColUID(),
1016 tableView_->getDataView()[row_][linkPair.second]);
1035 tableView_->getDataView()[row_][c],
1040 tableView_->getDataView()[row_][linkPair.first],
1043 tableView_->getDataView()[row_][linkPair.second],
1046 tableView_->getColumnInfo(c).getChildLinkIndex());
1056 tableView_->getDataView()[row_][c],
1063 tableView_->getColumnInfo(c).getChildLinkIndex(),
1064 childConfig->getView().findRow(
1065 childConfig->getView().getColUID(),
1066 tableView_->getDataView()[row_][linkPair.second])),
1068 doNotThrowOnBrokenUIDLinks,
1069 originalNodeString);
1081 childConfig = configMgr_->getTableByName(
1082 tableView_->getDataView()[row_][linkPair.first]);
1083 childConfig->getView();
1087 if(tableView_->getDataView()[row_][linkPair.first] !=
1088 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
1090 <<
"Found disconnected node! Failed link target "
1092 << nodeName <<
" to table:id="
1093 << tableView_->getDataView()[row_][linkPair.first] <<
":"
1094 << tableView_->getDataView()[row_][linkPair.second] << __E__;
1100 tableView_->getDataView()[row_][linkPair.second],
1103 tableView_->getDataView()[row_][c],
1108 tableView_->getDataView()[row_][linkPair.first],
1111 tableView_->getDataView()[row_][linkPair.second],
1114 tableView_->getColumnInfo(c).getChildLinkIndex());
1122 ->getDataView()[row_][linkPair.second],
1125 tableView_->getDataView()[row_][c],
1132 tableView_->getColumnInfo(c).getChildLinkIndex()),
1134 doNotThrowOnBrokenUIDLinks,
1135 originalNodeString);
1147 TableView::INVALID ,
1148 TableView::INVALID ,
1157 catch(std::runtime_error& e)
1159 __SS__ <<
"\n\nError occurred descending from node '" << getValue()
1160 <<
"' in table '" << getTableName() <<
"' looking for child '" << nodeName
1163 ss <<
"The original node search string was '" << originalNodeString <<
".'"
1165 ss <<
"--- Additional error detail: \n\n" << e.what() << __E__;
1167 ss << nodeDump() << __E__;
1172 __SS__ <<
"\n\nError occurred descending from node '" << getValue()
1173 <<
"' in table '" << getTableName() <<
"' looking for child '" << nodeName
1176 ss <<
"The original node search string was '" << originalNodeString <<
".'"
1179 ss << nodeDump() << __E__;
1185 <<
"\n\nError occurred descending from node '" << getValue() <<
"' in table '"
1186 << getTableName() <<
"' looking for child '" << nodeName <<
"'\n\n"
1187 <<
"Invalid depth! getNode() called from a value point in the Configuration Tree."
1189 ss <<
"The original node search string was '" << originalNodeString <<
".'" << __E__;
1191 ss << nodeDump() << __E__;
1198 std::string ConfigurationTree::nodeDump(
void)
const
1200 __SS__ <<
"ConfigurationTree::nodeDump() "
1201 "=====================================\nConfigurationTree::nodeDump():"
1208 <<
"Error occurred from node '" << getValueAsString() <<
"'..." << __E__;
1216 <<
"Error occurred from node '" << getValue() <<
"' in table '"
1217 << getTableName() <<
".'" << __E__;
1224 auto children = getChildrenNames();
1226 <<
"Here is the list of possible children (count = " << children.size()
1228 for(
auto& child : children)
1229 ss <<
"\t\t" << child << __E__;
1232 ss <<
"\n\nHere is the culprit table printout:\n\n";
1233 tableView_->print(ss);
1242 ss <<
"\n\n" << StringMacros::stackTrace() << __E__;
1248 ss <<
"end ConfigurationTree::nodeDump() ====================================="
1256 unsigned int backSteps)
const
1258 for(
unsigned int i = 0; i < backSteps; i++)
1259 nodeName = nodeName.substr(0, nodeName.find_last_of(
'/'));
1261 return getNode(nodeName);
1266 unsigned int forwardSteps)
const
1271 while(s < nodeName.length() && nodeName[s] ==
'/')
1274 for(
unsigned int i = 0; i < forwardSteps; i++)
1275 s = nodeName.find(
'/', s) + 1;
1277 return getNode(nodeName.substr(0, s));
1283 bool ConfigurationTree::isValueNode(
void)
const
1285 return (row_ != TableView::INVALID && col_ != TableView::INVALID);
1291 bool ConfigurationTree::isValueBoolType(
void)
const
1293 return isValueNode() && tableView_->getColumnInfo(col_).isBoolType();
1299 bool ConfigurationTree::isValueNumberDataType(
void)
const
1301 return isValueNode() && tableView_->getColumnInfo(col_).isNumberDataType();
1309 bool ConfigurationTree::isDisconnected(
void)
const
1313 __SS__ <<
"\n\nError occurred testing link connection at node with value '"
1314 << getValue() <<
"' in table '" << getTableName() <<
"'\n\n"
1316 ss <<
"This is not a Link node! It is node type '" << getNodeType()
1317 <<
".' Only a Link node can be disconnected." << __E__;
1319 ss << nodeDump() << __E__;
1323 return !table_ || !tableView_;
1329 bool ConfigurationTree::isLinkNode(
void)
const {
return linkColName_ !=
""; }
1334 const std::string ConfigurationTree::NODE_TYPE_GROUP_TABLE =
"GroupTableNode";
1335 const std::string ConfigurationTree::NODE_TYPE_TABLE =
"TableNode";
1336 const std::string ConfigurationTree::NODE_TYPE_GROUP_LINK =
"GroupLinkNode";
1337 const std::string ConfigurationTree::NODE_TYPE_UID_LINK =
"UIDLinkNode";
1338 const std::string ConfigurationTree::NODE_TYPE_VALUE =
"ValueNode";
1339 const std::string ConfigurationTree::NODE_TYPE_UID =
"UIDNode";
1340 const std::string ConfigurationTree::NODE_TYPE_ROOT =
"RootNode";
1342 std::string ConfigurationTree::getNodeType(
void)
const
1345 return ConfigurationTree::NODE_TYPE_ROOT;
1346 if(isConfigurationNode() && groupId_ !=
"")
1347 return ConfigurationTree::NODE_TYPE_GROUP_TABLE;
1348 if(isConfigurationNode())
1349 return ConfigurationTree::NODE_TYPE_TABLE;
1350 if(isGroupLinkNode())
1351 return ConfigurationTree::NODE_TYPE_GROUP_LINK;
1353 return ConfigurationTree::NODE_TYPE_UID_LINK;
1355 return ConfigurationTree::NODE_TYPE_VALUE;
1356 return ConfigurationTree::NODE_TYPE_UID;
1362 bool ConfigurationTree::isGroupLinkNode(
void)
const
1364 return (isLinkNode() && groupId_ !=
"");
1370 bool ConfigurationTree::isUIDLinkNode(
void)
const
1372 return (isLinkNode() && groupId_ ==
"");
1378 bool ConfigurationTree::isUIDNode(
void)
const
1380 return (row_ != TableView::INVALID && col_ == TableView::INVALID);
1399 std::vector<ConfigurationTree::RecordField> ConfigurationTree::getCommonFields(
1400 const std::vector<std::string /*uid*/>& recordList,
1401 const std::vector<std::string /*relative-path*/>& fieldAcceptList,
1402 const std::vector<std::string /*relative-path*/>& fieldRejectList,
1403 unsigned int depth)
const
1406 if(!isRootNode() && !isConfigurationNode())
1408 __SS__ <<
"Can only get getCommonFields from a root or table node! "
1409 <<
"The node type is " << getNodeType() << __E__;
1411 ss << nodeDump() << __E__;
1415 std::vector<ConfigurationTree::RecordField> fieldCandidateList;
1416 std::vector<int> fieldCount;
1459 for(
unsigned int i = 0; i < recordList.size(); ++i)
1463 auto recordChildren = getNode(recordList[i]).getChildren();
1464 for(
const auto& fieldNode : recordChildren)
1468 if(fieldNode.second.isValueNode())
1471 if(fieldNode.second.getColumnInfo().getType() ==
1472 TableViewColumnInfo::TYPE_AUTHOR ||
1473 fieldNode.second.getColumnInfo().getType() ==
1474 TableViewColumnInfo::TYPE_TIMESTAMP)
1481 found = fieldAcceptList.size() ?
false
1483 for(
const auto& fieldFilter : fieldAcceptList)
1484 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1495 for(
const auto& fieldFilter : fieldRejectList)
1496 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1508 fieldNode.second.getTableName(),
1512 &fieldNode.second.getColumnInfo()));
1513 fieldCount.push_back(-1);
1519 else if(depth > 0 && fieldNode.second.isUIDLinkNode() &&
1520 !fieldNode.second.isDisconnected())
1523 fieldNode.second.recursiveGetCommonFields(
1529 fieldNode.first +
"/",
1541 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1546 if(fieldCount[i] != -1 && fieldCount[i] != (
int)recordList.size())
1551 fieldCount.erase(fieldCount.begin() + i);
1552 fieldCandidateList.erase(fieldCandidateList.begin() + i);
1561 return fieldCandidateList;
1569 std::set<std::string > ConfigurationTree::getUniqueValuesForField(
1570 const std::vector<std::string /*relative-path*/>& recordList,
1571 const std::string& fieldName)
const
1574 if(!isConfigurationNode())
1576 __SS__ <<
"Can only get getCommonFields from a table node! "
1577 <<
"The node type is " << getNodeType() << __E__;
1579 ss << nodeDump() << __E__;
1583 std::set<std::string > uniqueValues;
1590 for(
unsigned int i = 0; i < recordList.size(); ++i)
1592 __COUT__ <<
"Checking " << recordList[i] << __E__;
1600 uniqueValues.emplace(
1601 getNode(recordList[i]).getNode(fieldName).getValueAsString(
true));
1604 return uniqueValues;
1610 void ConfigurationTree::recursiveGetCommonFields(
1611 std::vector<ConfigurationTree::RecordField>& fieldCandidateList,
1612 std::vector<int>& fieldCount,
1613 const std::vector<std::string /*relative-path*/>& fieldAcceptList,
1614 const std::vector<std::string /*relative-path*/>& fieldRejectList,
1616 const std::string& relativePathBase,
1617 bool inFirstRecord)
const
1641 auto tableName = getTableName();
1642 auto uid = getUIDAsString();
1645 auto recordChildren = getChildren();
1646 for(
const auto& fieldNode : recordChildren)
1648 if(fieldNode.second.isValueNode())
1651 if(fieldNode.second.getColumnInfo().getType() ==
1652 TableViewColumnInfo::TYPE_AUTHOR ||
1653 fieldNode.second.getColumnInfo().getType() ==
1654 TableViewColumnInfo::TYPE_TIMESTAMP)
1661 found = fieldAcceptList.size() ?
false :
true;
1663 for(
const auto& fieldFilter : fieldAcceptList)
1664 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1675 for(
const auto& fieldFilter : fieldRejectList)
1676 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1693 &fieldNode.second.getColumnInfo()));
1694 fieldCount.push_back(1);
1701 for(j = 0; j < fieldCandidateList.size(); ++j)
1703 if((relativePathBase + fieldNode.first) ==
1704 (fieldCandidateList[j].relativePath_ +
1705 fieldCandidateList[j].columnName_))
1716 else if(depth > 0 && fieldNode.second.isUIDLinkNode() &&
1717 !fieldNode.second.isDisconnected())
1721 fieldNode.second.recursiveGetCommonFields(
1727 (relativePathBase + fieldNode.first) +
"/",
1740 std::vector<std::vector<std::pair<std::string, ConfigurationTree>>>
1741 ConfigurationTree::getChildrenByPriority(
1742 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
1743 bool onlyStatusTrue)
const
1745 std::vector<std::vector<std::pair<std::string, ConfigurationTree>>> retVector;
1749 bool filtering = filterMap.size();
1751 std::string fieldValue;
1753 bool createContainer;
1755 std::vector<std::vector<std::string>> childrenNamesByPriority =
1756 getChildrenNamesByPriority(onlyStatusTrue);
1758 for(
auto& childNamesAtPriority : childrenNamesByPriority)
1760 createContainer =
true;
1762 for(
auto& childName : childNamesAtPriority)
1772 for(
const auto& filterPair : filterMap)
1774 std::string filterPath = childName +
"/" + filterPair.first;
1775 __COUTV__(filterPath);
1779 std::vector<std::string> fieldValues;
1780 StringMacros::getVectorFromString(
1783 std::set<char>({
','}) );
1785 __COUTV__(fieldValues.size());
1789 for(
const auto& fieldValue : fieldValues)
1800 __COUT__ <<
"\t\tCheck: " << filterPair.first
1801 <<
" == " << fieldValue <<
" => "
1802 << StringMacros::decodeURIComponent(fieldValue)
1804 << this->getNode(filterPath).getValueAsString(
true)
1807 if(StringMacros::wildCardMatch(
1808 StringMacros::decodeURIComponent(fieldValue),
1809 this->getNode(filterPath).getValueAsString(
true)))
1819 __SS__ <<
"Failed to access filter path '" << filterPath
1820 <<
"' - aborting." << __E__;
1822 ss << nodeDump() << __E__;
1839 retVector.push_back(
1840 std::vector<std::pair<std::string, ConfigurationTree>>());
1841 createContainer =
false;
1844 retVector[retVector.size() - 1].push_back(
1845 std::pair<std::string, ConfigurationTree>(
1846 childName, this->getNode(childName,
true)));
1860 std::vector<std::pair<std::string, ConfigurationTree>> ConfigurationTree::getChildren(
1861 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
1863 bool onlyStatusTrue)
const
1865 std::vector<std::pair<std::string, ConfigurationTree>> retVector;
1869 bool filtering = filterMap.size();
1871 std::string fieldValue;
1873 std::vector<std::string> childrenNames = getChildrenNames(byPriority, onlyStatusTrue);
1874 for(
auto& childName : childrenNames)
1884 for(
const auto& filterPair : filterMap)
1886 std::string filterPath = childName +
"/" + filterPair.first;
1887 __COUTV__(filterPath);
1891 std::vector<std::string> fieldValues;
1892 StringMacros::getVectorFromString(
1895 std::set<char>({
','}) );
1897 __COUTV__(fieldValues.size());
1901 for(
const auto& fieldValue : fieldValues)
1912 <<
"\t\tCheck: " << filterPair.first <<
" == " << fieldValue
1913 <<
" => " << StringMacros::decodeURIComponent(fieldValue)
1914 <<
" ??? " << this->getNode(filterPath).getValueAsString(
true)
1917 if(StringMacros::wildCardMatch(
1918 StringMacros::decodeURIComponent(fieldValue),
1919 this->getNode(filterPath).getValueAsString(
true)))
1929 __SS__ <<
"Failed to access filter path '" << filterPath
1930 <<
"' - aborting." << __E__;
1932 ss << nodeDump() << __E__;
1947 retVector.push_back(std::pair<std::string, ConfigurationTree>(
1948 childName, this->getNode(childName,
true)));
1958 std::map<std::string, ConfigurationTree> ConfigurationTree::getChildrenMap(
void)
const
1960 std::map<std::string, ConfigurationTree> retMap;
1964 std::vector<std::string> childrenNames = getChildrenNames();
1965 for(
auto& childName : childrenNames)
1968 retMap.insert(std::pair<std::string, ConfigurationTree>(
1969 childName, this->getNode(childName)));
1977 bool ConfigurationTree::isRootNode(
void)
const {
return (!table_); }
1980 bool ConfigurationTree::isConfigurationNode(
void)
const
1982 return (table_ && row_ == TableView::INVALID && col_ == TableView::INVALID);
1988 std::vector<std::vector<std::string>> ConfigurationTree::getChildrenNamesByPriority(
1989 bool onlyStatusTrue)
const
1991 std::vector<std::vector<std::string >> retVector;
1995 __SS__ <<
"Can not get children names of '" << getValueAsString()
1996 <<
"' with null configuration view pointer!" << __E__;
1997 if(isLinkNode() && isDisconnected())
1998 ss <<
" This node is a disconnected link to " << getDisconnectedTableName()
2001 ss << nodeDump() << __E__;
2005 if(row_ == TableView::INVALID && col_ == TableView::INVALID)
2016 std::map<uint64_t , std::vector<
unsigned int >>
2018 std::vector<std::string > retPrioritySet;
2020 unsigned int col = tableView_->getColPriority();
2022 uint64_t tmpPriority;
2024 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2025 if(groupId_ ==
"" ||
2026 tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2031 tableView_->getValue(
2032 tmpStatus, r, tableView_->getColStatus());
2037 tableView_->getValue(tmpPriority, r, col);
2039 orderedByPriority[tmpPriority ? tmpPriority : 100].push_back(r);
2045 for(
const auto& priorityChildRowVector : orderedByPriority)
2047 retVector.push_back(std::vector<std::string /*child name*/>());
2048 for(
const auto& priorityChildRow : priorityChildRowVector.second)
2049 retVector[retVector.size() - 1].push_back(
2050 tableView_->getDataView()[priorityChildRow]
2051 [tableView_->getColUID()]);
2054 __COUT__ <<
"Returning priority children list." << __E__;
2057 catch(std::runtime_error& e)
2059 __COUT_WARN__ <<
"Error identifying priority. Assuming all children have "
2060 "equal priority (Error: "
2061 << e.what() << __E__;
2067 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2068 if(groupId_ ==
"" || tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2073 tableView_->getValue(tmpStatus, r, tableView_->getColStatus());
2078 retVector.push_back(std::vector<std::string /*child name*/>());
2079 retVector[retVector.size() - 1].push_back(
2080 tableView_->getDataView()[r][tableView_->getColUID()]);
2083 else if(row_ == TableView::INVALID)
2085 __SS__ <<
"Malformed ConfigurationTree" << __E__;
2087 ss << nodeDump() << __E__;
2090 else if(col_ == TableView::INVALID)
2095 for(
unsigned int c = 0; c < tableView_->getNumberOfColumns(); ++c)
2096 if(c == tableView_->getColUID() ||
2098 tableView_->getColumnInfo(c).isChildLinkGroupID() ||
2099 tableView_->getColumnInfo(c).isChildLinkUID())
2103 retVector.push_back(std::vector<std::string /*child name*/>());
2104 retVector[retVector.size() - 1].push_back(
2105 tableView_->getColumnInfo(c).getName());
2111 __SS__ <<
"\n\nError occurred looking for children of nodeName=" << getValueName()
2113 <<
"Invalid depth! getChildrenValues() called from a value point in the "
2114 "Configuration Tree."
2117 ss << nodeDump() << __E__;
2127 std::vector<std::string> ConfigurationTree::getChildrenNames(
bool byPriority,
2128 bool onlyStatusTrue)
const
2130 std::vector<std::string > retVector;
2134 __SS__ <<
"Can not get children names of '" << getValueAsString()
2135 <<
"' with null configuration view pointer!" << __E__;
2136 if(isLinkNode() && isDisconnected())
2137 ss <<
" This node is a disconnected link to " << getDisconnectedTableName()
2142 if(row_ == TableView::INVALID && col_ == TableView::INVALID)
2153 std::map<uint64_t , std::vector<
unsigned int >>
2155 std::vector<std::string > retPrioritySet;
2157 unsigned int col = tableView_->getColPriority();
2159 uint64_t tmpPriority;
2161 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2162 if(groupId_ ==
"" ||
2163 tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2168 tableView_->getValue(
2169 tmpStatus, r, tableView_->getColStatus());
2174 tableView_->getValue(tmpPriority, r, col);
2176 orderedByPriority[tmpPriority ? tmpPriority : 100].push_back(r);
2182 for(
const auto& priorityChildRowVector : orderedByPriority)
2183 for(
const auto& priorityChildRow : priorityChildRowVector.second)
2184 retVector.push_back(
2185 tableView_->getDataView()[priorityChildRow]
2186 [tableView_->getColUID()]);
2188 __COUT__ <<
"Returning priority children list." << __E__;
2191 catch(std::runtime_error& e)
2193 __COUT_WARN__ <<
"Priority configuration not found. Assuming all "
2194 "children have equal priority (Error: "
2195 << e.what() << __E__;
2201 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2202 if(groupId_ ==
"" || tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2207 tableView_->getValue(tmpStatus, r, tableView_->getColStatus());
2212 retVector.push_back(
2213 tableView_->getDataView()[r][tableView_->getColUID()]);
2216 else if(row_ == TableView::INVALID)
2218 __SS__ <<
"Malformed ConfigurationTree" << __E__;
2220 ss << nodeDump() << __E__;
2223 else if(col_ == TableView::INVALID)
2228 for(
unsigned int c = 0; c < tableView_->getNumberOfColumns(); ++c)
2229 if(c == tableView_->getColUID() ||
2231 tableView_->getColumnInfo(c).isChildLinkGroupID() ||
2232 tableView_->getColumnInfo(c).isChildLinkUID())
2235 retVector.push_back(tableView_->getColumnInfo(c).getName());
2240 __SS__ <<
"\n\nError occurred looking for children of nodeName=" << getValueName()
2242 <<
"Invalid depth! getChildrenValues() called from a value point in the "
2243 "Configuration Tree."
2246 ss << nodeDump() << __E__;
2264 __SS__ <<
"Invalid node for get value." << __E__;
2268 std::string valueString =
2269 tableView_->getValueAsString(row_, col_,
true );
2271 if(valueString.size() && valueString[0] ==
'/')
2278 __COUT__ <<
"Found a valid tree path in value!" << __E__;
2283 __SS__ <<
"Invalid tree path." << __E__;
2289 __SS__ <<
"Invalid value string '" << valueString
2290 <<
"' - must start with a '/' character." << __E__;