1 #include "otsdaq/ConfigurationInterface/ConfigurationTree.h"
5 #include "otsdaq/ConfigurationInterface/ConfigurationManager.h"
6 #include "otsdaq/Macros/StringMacros.h"
7 #include "otsdaq/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";
17 const std::string ConfigurationTree::ROOT_NAME =
"/";
18 time_t ConfigurationTree::LAST_NODE_DUMP_TIME = 0;
30 , disconnectedTargetName_(
"")
31 , disconnectedLinkID_(
"")
67 const std::string& groupId,
69 const std::string& linkColName,
70 const std::string& linkColValue,
71 const unsigned int linkBackRow,
72 const unsigned int linkBackCol,
73 const std::string& disconnectedTargetName,
74 const std::string& disconnectedLinkID,
75 const std::string& childLinkIndex,
76 const unsigned int row,
77 const unsigned int col)
78 : configMgr_(configMgr)
81 , linkParentTable_(linkParentConfig)
82 , linkColName_(linkColName)
83 , linkColValue_(linkColValue)
84 , linkBackRow_(linkBackRow)
85 , linkBackCol_(linkBackCol)
86 , disconnectedTargetName_(disconnectedTargetName)
87 , disconnectedLinkID_(disconnectedLinkID)
88 , childLinkIndex_(childLinkIndex)
95 __SS__ <<
"Invalid empty pointer given to tree!\n"
96 <<
"\n\tconfigMgr_=" << configMgr_ <<
"\n\tconfiguration_=" << table_
97 <<
"\n\tconfigView_=" << tableView_ << __E__;
104 tableView_ = &(table_->getView());
107 if(tableView_ && tableView_->getColumnInfo(tableView_->
getColUID()).getType() !=
110 __SS__ <<
"Missing UID column (must column of type "
112 <<
") in config view : " << tableView_->getTableName() << __E__;
134 recursivePrint(*
this, depth, out,
"\t");
167 out << space <<
"{" << __E__;
169 recursivePrint(c.second, depth - 1, out, space +
" ");
171 out << space <<
"}" << __E__;
177 std::string ConfigurationTree::handleValidateValueForColumn(
185 __SS__ <<
"Null configView" << __E__;
190 __COUT__ <<
"handleValidateValueForColumn<string>" << __E__;
203 if(row_ != TableView::INVALID &&
204 col_ != TableView::INVALID)
211 __COUT__ <<
"Success following path to tree node!" << __E__;
222 __COUT__ <<
"Successful value!" << __E__;
236 tableView_->
getValue(value, row_, col_);
238 else if(row_ == TableView::INVALID &&
239 col_ == TableView::INVALID)
246 value = (groupId_ ==
"") ? table_->
getTableName() : groupId_;
248 else if(row_ == TableView::INVALID)
250 __SS__ <<
"Malformed ConfigurationTree" << __E__;
253 else if(col_ == TableView::INVALID)
257 __SS__ <<
"Impossible." << __E__;
307 void ConfigurationTree::getValueAsBitMap(
310 __COUTS__(2) << row_ <<
" " << col_ <<
" p: " << tableView_ << __E__;
312 if(row_ != TableView::INVALID &&
313 col_ != TableView::INVALID)
315 std::string bitmapString;
316 tableView_->
getValue(bitmapString, row_, col_);
320 __COUTV__(bitmapString);
321 if(bitmapString == TableViewColumnInfo::DATATYPE_STRING_DEFAULT)
323 bitmap.isDefault_ =
true;
325 for(
unsigned int r = 0; r < bmp.numOfRows_; ++r)
327 bitmap.bitmap_.push_back(std::vector<std::string>());
328 for(
unsigned int c = 0; c < bmp.numOfColumns_; ++c)
329 bitmap.bitmap_[r].push_back(std::string());
334 bitmap.isDefault_ =
false;
338 std::map<std::string, size_t> valueMap;
339 if(bmp.mapsToStrings_)
341 std::vector<std::string> list =
344 for(
size_t i = 0; i < list.size(); ++i)
345 valueMap.emplace(std::make_pair(list[i], i));
351 bitmap.bitmap_.clear();
353 bool openRow =
false;
354 unsigned int startInt = -1;
355 for(
unsigned int i = 0; i < bitmapString.length(); i++)
357 __COUTVS__(2, bitmapString[i]);
359 __COUTVS__(2, openRow);
360 __COUTVS__(2, startInt);
365 if(bitmapString[i] ==
'[')
369 bitmap.bitmap_.push_back(std::vector<std::string>());
371 else if(bitmapString[i] ==
']')
375 else if(bitmapString[i] ==
',')
382 else if(startInt == (
unsigned int)-1)
384 if(bitmapString[i] ==
']')
389 else if((bitmapString[i] >=
'0' &&
390 bitmapString[i] <=
'9') ||
391 (bmp.mapsToStrings_ && bitmapString[i] >=
'a' &&
394 (bmp.mapsToStrings_ && bitmapString[i] >=
'A' &&
395 bitmapString[i] <=
'Z'))
399 else if(bitmapString[i] ==
',')
401 __SS__ <<
"Too many ',' characters in bit map configuration"
412 if(bitmapString[i] ==
419 while(ii - startInt > 2 && (bitmapString[ii - 1] ==
' ' ||
420 bitmapString[ii - 1] ==
'\r' ||
421 bitmapString[ii - 1] ==
'\n' ||
422 bitmapString[ii - 1] ==
'\t' ||
423 bitmapString[ii - 1] ==
'"'))
425 __COUTVS__(2, bitmapString.substr(startInt, ii - startInt));
426 if(bmp.mapsToStrings_)
429 valueMap.at(bitmapString.substr(startInt, ii - startInt));
430 __COUTVS__(2, value);
433 bitmap.bitmap_[row].push_back(
434 bitmapString.substr(startInt, ii - startInt));
438 else if(bitmapString[i] ==
',')
442 while(ii - startInt > 2 && (bitmapString[ii - 1] ==
' ' ||
443 bitmapString[ii - 1] ==
'\r' ||
444 bitmapString[ii - 1] ==
'\n' ||
445 bitmapString[ii - 1] ==
'\t' ||
446 bitmapString[ii - 1] ==
'"'))
448 __COUTVS__(2, bitmapString.substr(startInt, ii - startInt));
449 if(bmp.mapsToStrings_)
452 valueMap.at(bitmapString.substr(startInt, ii - startInt));
453 __COUTVS__(2, value);
456 bitmap.bitmap_[row].push_back(
457 bitmapString.substr(startInt, ii - startInt));
466 for(
unsigned int r = 0; r < bitmap.bitmap_.size(); ++r)
468 for(
unsigned int c = 0; c < bitmap.bitmap_[r].size(); ++c)
470 __COUTT__ << r <<
"," << c <<
" = " << bitmap.bitmap_[r][c]
473 __COUTT__ <<
"================" << __E__;
478 if(bitmap.bitmap_.size() != bmp.numOfRows_ ||
479 (bmp.numOfRows_ && bitmap.bitmap_[0].size() != bmp.numOfColumns_))
482 <<
"Illegal mismatch in number of rows and columns. Extracted data was "
483 << bitmap.bitmap_.size() <<
" x "
484 << (bitmap.bitmap_.size() ? bitmap.bitmap_[0].size() : 0)
485 <<
" and the expected size is " << bmp.numOfRows_ <<
" x "
486 << bmp.numOfColumns_ << __E__;
492 __SS__ <<
"Requesting getValue must be on a value node." << __E__;
506 ConfigurationTree::getValueAsBitMap(value);
515 if(row_ != TableView::INVALID &&
516 col_ != TableView::INVALID)
519 __SS__ <<
"Can not get escaped value except from a value node!"
520 <<
" This node is type '" << getNodeType() <<
"." << __E__;
532 __SS__ <<
"Can not get configuration name of node with no configuration pointer! "
533 <<
"Is there a broken link? " << __E__;
536 ss <<
"Error occurred traversing from " << linkParentTable_->
getTableName()
539 linkBackRow_, linkParentTable_->getView().
getColUID())
540 <<
"' at row " << linkBackRow_ <<
" col '"
541 << linkParentTable_->getView().getColumnInfo(linkBackCol_).getName()
559 __SS__ <<
"Can not get parent table name of node with no parent table pointer! "
560 <<
"Was this node initialized correctly? " << __E__;
571 __SS__ <<
"Can only get row from a UID or value node!" << __E__;
574 ss <<
"Error occurred traversing from " << linkParentTable_->
getTableName()
577 linkBackRow_, linkParentTable_->getView().
getColUID())
578 <<
"' at row " << linkBackRow_ <<
" col '"
579 << linkParentTable_->getView().getColumnInfo(linkBackCol_).getName() <<
".'"
599 if(!linkParentTable_)
601 __SS__ <<
"Can not get configuration name of link node field with no parent "
602 "configuration pointer!"
618 return disconnectedTargetName_;
620 __SS__ <<
"Can not get disconnected target name of node unless it is a disconnected "
633 return disconnectedLinkID_;
635 __SS__ <<
"Can not get disconnected target name of node unless it is a disconnected "
649 __SS__ <<
"Can not get configuration version of node with no config view pointer!"
655 return tableView_->getVersion();
664 __SS__ <<
"Can not get configuration creation time of node with no config view "
671 return tableView_->getCreationTime();
681 __SS__ <<
"Can not get set of group IDs of node with value type of '"
682 << getNodeType() <<
".' Node must be a GroupID node." << __E__;
698 if(
getValueType() != TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA &&
701 __SS__ <<
"Can not get fixed choices of node with value type of '"
702 <<
getValueType() <<
".' Node must be a link or a value node with type '"
703 << TableViewColumnInfo::TYPE_BITMAP_DATA <<
"' or '"
704 << TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA <<
".'" << __E__;
710 std::vector<std::string> retVec;
714 if(!linkParentTable_)
717 <<
"Can not get fixed choices of node with no parent config view pointer!"
730 const TableView* parentView = &(linkParentTable_->getView());
731 int c = parentView->
findCol(linkColName_);
733 std::pair<
unsigned int ,
unsigned int > linkPair;
738 std::vector<std::string> choices = parentView->getColumnInfo(c).getDataChoices();
739 for(
const auto& choice : choices)
740 retVec.push_back(choice);
747 __SS__ <<
"Can not get fixed choices of node with no config view pointer!"
755 retVec.push_back(tableView_->getColumnInfo(col_).getDefaultValue());
756 std::vector<std::string> choices = tableView_->getColumnInfo(col_).getDataChoices();
757 for(
const auto& choice : choices)
758 retVec.push_back(choice);
768 ? TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT
793 if(returnLinkTableValue)
794 return linkColValue_;
796 return ConfigurationTree::DISCONNECTED_VALUE;
797 else if(row_ == TableView::INVALID &&
798 col_ == TableView::INVALID)
799 return (groupId_ ==
"") ? table_->
getTableName() : groupId_;
800 else if(col_ == TableView::INVALID)
801 return tableView_->getDataView()[row_][tableView_->
getColUID()];
804 __SS__ <<
"Impossible Link." << __E__;
810 else if(row_ != TableView::INVALID &&
811 col_ != TableView::INVALID)
812 return tableView_->getDataView()[row_][col_];
813 else if(row_ == TableView::INVALID &&
814 col_ == TableView::INVALID)
818 return ConfigurationTree::ROOT_NAME;
820 return (groupId_ ==
"") ? table_->
getTableName() : groupId_;
822 else if(row_ == TableView::INVALID)
824 __SS__ <<
"Malformed ConfigurationTree" << __E__;
829 else if(col_ == TableView::INVALID)
830 return tableView_->getDataView()[row_][tableView_->
getColUID()];
833 __SS__ <<
"Impossible." << __E__;
847 return tableView_->getDataView()[row_][tableView_->
getColUID()];
850 __SS__ <<
"Can not get UID of node with type '" << getNodeType()
851 <<
".' Node type must be '" << ConfigurationTree::NODE_TYPE_VALUE
852 <<
"' or '" << ConfigurationTree::NODE_TYPE_UID_LINK <<
".'" << __E__;
865 return tableView_->getColumnInfo(col_).getDataType();
867 return TableViewColumnInfo::DATATYPE_STRING;
880 if(
getValueType() == TableViewColumnInfo::TYPE_ON_OFF ||
881 getValueType() == TableViewColumnInfo::TYPE_TRUE_FALSE ||
884 TableViewColumnInfo::DATATYPE_BOOL_DEFAULT;
886 else if(
getValueType() == TableViewColumnInfo::TYPE_COMMENT)
887 return getValueAsString() == TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT ||
909 __SS__ <<
"Can only get default value from a value node! "
910 <<
"The node type is " << getNodeType() << __E__;
918 if(
getValueType() == TableViewColumnInfo::TYPE_ON_OFF ||
919 getValueType() == TableViewColumnInfo::TYPE_TRUE_FALSE ||
921 return TableViewColumnInfo::DATATYPE_BOOL_DEFAULT;
923 else if(
getValueType() == TableViewColumnInfo::TYPE_COMMENT)
924 return TableViewColumnInfo::
925 DATATYPE_COMMENT_DEFAULT;
927 return TableViewColumnInfo::DATATYPE_STRING_DEFAULT;
930 return TableViewColumnInfo::DATATYPE_NUMBER_DEFAULT;
932 return TableViewColumnInfo::DATATYPE_TIME_DEFAULT;
935 __SS__ <<
"Can only get default value from a value node! "
936 <<
"The node type is " << getNodeType() << __E__;
949 return tableView_->getColumnInfo(col_).getType();
951 return ConfigurationTree::VALUE_TYPE_DISCONNECTED;
953 return ConfigurationTree::VALUE_TYPE_NODE;
962 return tableView_->getColumnInfo(col_);
965 __SS__ <<
"Can only get column info from a value node! "
966 <<
"The node type is " << getNodeType() << __E__;
1003 return linkBackCol_;
1015 __SS__ <<
"Can only get link ID from a link! "
1016 <<
"The node type is " << getNodeType() << __E__;
1021 return childLinkIndex_;
1030 return tableView_->getColumnInfo(col_).getName();
1032 return linkColName_;
1035 __SS__ <<
"Can only get value name of a value node!" << __E__;
1046 const std::string& childPath,
1047 bool doNotThrowOnBrokenUIDLinks,
1048 const std::string& originalNodeString)
1050 __COUTS__(50) << tree.row_ <<
" " << tree.col_ << __E__;
1051 __COUTS__(51) <<
"childPath=" << childPath <<
" " << childPath.length() << __E__;
1052 if(childPath.length() <= 1)
1054 return tree.recursiveGetNode(
1055 childPath, doNotThrowOnBrokenUIDLinks, originalNodeString);
1069 bool doNotThrowOnBrokenUIDLinks)
const
1072 return recursiveGetNode(
1073 nodeString, doNotThrowOnBrokenUIDLinks,
"" );
1076 const std::string& nodeString,
1077 bool doNotThrowOnBrokenUIDLinks,
1078 const std::string& originalNodeString)
const
1080 __COUTS__(51) <<
"nodeString=" << nodeString <<
" len=" << nodeString.length()
1082 __COUTS__(52) <<
"doNotThrowOnBrokenUIDLinks=" << doNotThrowOnBrokenUIDLinks << __E__;
1085 if(nodeString.length() < 1)
1087 __SS__ <<
"Invalid empty node name! Looking for child node '" << nodeString
1088 <<
"' from node '" <<
getValue() <<
"'..." << __E__;
1095 size_t startingIndex = 0;
1096 while(startingIndex < nodeString.length() && nodeString[startingIndex] ==
'/')
1098 size_t endingIndex = nodeString.find(
'/', startingIndex);
1099 if(endingIndex == std::string::npos)
1100 endingIndex = nodeString.length();
1102 std::string nodeName = nodeString.substr(startingIndex, endingIndex - startingIndex);
1103 __COUTS__(51) <<
"nodeName=" << nodeName <<
" len=" << nodeName.length() << __E__;
1106 std::string childPath =
1107 (endingIndex >= nodeString.length() ?
"" : nodeString.substr(endingIndex));
1108 __COUTS__(51) <<
"childPath=" << childPath <<
" len=" << childPath.length()
1109 <<
" endingIndex=" << endingIndex
1110 <<
" nodeString.length()=" << nodeString.length() << __E__;
1116 __COUTS__(50) << row_ <<
" " << col_ <<
" " << groupId_ <<
" " << tableView_
1122 return recurse(configMgr_->
getNode(nodeName),
1124 doNotThrowOnBrokenUIDLinks,
1125 originalNodeString);
1127 else if(row_ == TableView::INVALID && col_ == TableView::INVALID)
1133 __SS__ <<
"Missing configView pointer! Likely attempting to access a "
1134 "child node through a disconnected link node."
1150 TableView::INVALID ,
1151 TableView::INVALID ,
1163 doNotThrowOnBrokenUIDLinks,
1164 originalNodeString);
1166 else if(row_ == TableView::INVALID)
1168 __SS__ <<
"Malformed ConfigurationTree" << __E__;
1173 else if(col_ == TableView::INVALID)
1178 __COUTS__(51) <<
"nodeName=" << nodeName <<
" " << nodeName.length() << __E__;
1188 __SS__ <<
"Missing configView pointer! Likely attempting to access a "
1189 "child node through a disconnected link node."
1196 unsigned int c = tableView_->
findCol(nodeName);
1197 std::pair<
unsigned int ,
unsigned int > linkPair;
1198 bool isGroupLink, isLink;
1199 if((isLink = tableView_->
getChildLink(c, isGroupLink, linkPair)) &&
1202 __COUTS__(50) <<
"nodeName=" << nodeName <<
" " << nodeName.length()
1212 tableView_->getDataView()[row_][linkPair.first]);
1213 childConfig->getView();
1215 if(doNotThrowOnBrokenUIDLinks)
1217 childConfig->getView().
findRow(
1219 tableView_->getDataView()[row_][linkPair.second]);
1225 <<
"Found disconnected node! (" << nodeName <<
":"
1226 << tableView_->getDataView()[row_][linkPair.first] <<
")"
1227 <<
" at entry with UID "
1228 << tableView_->getDataView()[row_][tableView_->
getColUID()]
1237 tableView_->getDataView()[row_][c],
1242 tableView_->getDataView()[row_][linkPair.first],
1245 tableView_->getDataView()[row_][linkPair.second],
1258 tableView_->getDataView()[row_][c],
1266 childConfig->getView().
findRow(
1268 tableView_->getDataView()[row_][linkPair.second])),
1270 doNotThrowOnBrokenUIDLinks,
1271 originalNodeString);
1275 __COUTS__(50) <<
"nodeName=" << nodeName <<
" " << nodeName.length()
1285 tableView_->getDataView()[row_][linkPair.first]);
1286 childConfig->getView();
1290 if(tableView_->getDataView()[row_][linkPair.first] !=
1291 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
1293 <<
"Found disconnected node! Failed link target "
1295 << nodeName <<
" to table:id="
1296 << tableView_->getDataView()[row_][linkPair.first] <<
":"
1297 << tableView_->getDataView()[row_][linkPair.second] << __E__;
1303 tableView_->getDataView()[row_][linkPair.second],
1306 tableView_->getDataView()[row_][c],
1311 tableView_->getDataView()[row_][linkPair.first],
1314 tableView_->getDataView()[row_][linkPair.second],
1325 ->getDataView()[row_][linkPair.second],
1328 tableView_->getDataView()[row_][c],
1337 doNotThrowOnBrokenUIDLinks,
1338 originalNodeString);
1342 __COUTS__(50) <<
"nodeName=" << nodeName <<
" " << nodeName.length()
1351 TableView::INVALID ,
1352 TableView::INVALID ,
1361 catch(std::runtime_error& e)
1363 __SS__ <<
"\n\nError occurred descending from node '" <<
getValue()
1364 <<
"' in table '" <<
getTableName() <<
"' looking for child '" << nodeName
1367 ss <<
"The original node search string was '" << originalNodeString <<
".'"
1369 ss <<
"--- Additional error detail: \n\n" << e.what() << __E__;
1376 __SS__ <<
"\n\nError occurred descending from node '" <<
getValue()
1377 <<
"' in table '" <<
getTableName() <<
"' looking for child '" << nodeName
1380 ss <<
"The original node search string was '" << originalNodeString <<
".'"
1386 catch(
const std::exception& e)
1388 ss <<
"Exception message: " << e.what();
1399 <<
"\n\nError occurred descending from node '" <<
getValue() <<
"' in table '"
1400 <<
getTableName() <<
"' looking for child '" << nodeName <<
"'\n\n"
1401 <<
"Invalid depth! getNode() called from a value point in the Configuration Tree."
1403 ss <<
"The original node search string was '" << originalNodeString <<
".'" << __E__;
1412 const std::string& nodeString)
const
1414 if(nodeString.length() < 1)
1428 if(time(0) - ConfigurationTree::LAST_NODE_DUMP_TIME < 3)
1430 __COUTS__(20) <<
"Blocking cascading node dumps..." << __E__;
1433 ConfigurationTree::LAST_NODE_DUMP_TIME = time(0);
1435 __SS__ << __E__ << __E__;
1437 ss <<
"Row=" << (int)row_ <<
", Col=" << (
int)col_ <<
", TablePointer=" << table_
1449 ss <<
"ConfigurationTree::nodeDump() start"
1450 "=====================================\nConfigurationTree::nodeDump():"
1457 <<
"Node dump initiated from node '" <<
getValueAsString() <<
"'..." << __E__;
1465 <<
"Node dump initiated from node '" <<
getValue() <<
"' in table '"
1480 <<
"Here is the list of possible children (count = " << children.size()
1482 for(
auto& child : children)
1483 ss <<
"\t\t" << child << __E__;
1486 ss <<
"\n\nHere is the culprit table printout:\n\n";
1487 tableView_->print(ss);
1493 ss <<
"Is link node." << __E__;
1494 ss <<
"disconnectedTargetName_ = " << disconnectedTargetName_
1495 <<
", disconnectedLinkID_ = " << disconnectedLinkID_ << __E__;
1499 <<
"Here is the list of active tables:" << __E__;
1500 for(
auto& table : tables)
1501 ss <<
"\t\t" << table.first << __E__;
1508 ss <<
"\n\nConfigurationTree::nodeDump() end ====================================="
1516 unsigned int backSteps)
const
1518 for(
unsigned int i = 0; i < backSteps; i++)
1519 nodeName = nodeName.substr(0, nodeName.find_last_of(
'/'));
1526 unsigned int forwardSteps)
const
1531 while(s < nodeName.length() && nodeName[s] ==
'/')
1534 for(
unsigned int i = 0; i < forwardSteps; i++)
1535 s = nodeName.find(
'/', s) + 1;
1537 return getNode(nodeName.substr(0, s));
1545 return (row_ != TableView::INVALID && col_ != TableView::INVALID);
1573 __SS__ <<
"\n\nError occurred testing link connection at node with value '"
1576 ss <<
"This is not a Link node! It is node type '" << getNodeType()
1577 <<
".' Only a Link node can be disconnected." << __E__;
1583 return !table_ || !tableView_;
1595 const std::string ConfigurationTree::NODE_TYPE_TABLE =
"TableNode";
1596 const std::string ConfigurationTree::NODE_TYPE_GROUP_LINK =
"GroupLinkNode";
1597 const std::string ConfigurationTree::NODE_TYPE_UID_LINK =
"UIDLinkNode";
1598 const std::string ConfigurationTree::NODE_TYPE_VALUE =
"ValueNode";
1599 const std::string ConfigurationTree::NODE_TYPE_UID =
"UIDNode";
1600 const std::string ConfigurationTree::NODE_TYPE_ROOT =
"RootNode";
1602 std::string ConfigurationTree::getNodeType(
void)
const
1605 return ConfigurationTree::NODE_TYPE_ROOT;
1606 if(isTableNode() && groupId_ !=
"")
1609 return ConfigurationTree::NODE_TYPE_TABLE;
1611 return ConfigurationTree::NODE_TYPE_GROUP_LINK;
1613 return ConfigurationTree::NODE_TYPE_UID_LINK;
1615 return ConfigurationTree::NODE_TYPE_VALUE;
1616 return ConfigurationTree::NODE_TYPE_UID;
1648 return (row_ != TableView::INVALID && col_ == TableView::INVALID);
1668 const std::vector<std::string /*uid*/>& recordList,
1669 const std::vector<std::string /*relative-path*/>& fieldAcceptList,
1670 const std::vector<std::string /*relative-path*/>& fieldRejectList,
1672 bool autoSelectFilterFields)
const
1675 if(!isRootNode() && !isTableNode())
1677 __SS__ <<
"Can only get getCommonFields from a root or table node! "
1678 <<
"The node type is " << getNodeType() << __E__;
1684 std::vector<ConfigurationTree::RecordField> fieldCandidateList;
1685 std::vector<int> fieldCount;
1729 if(!recordList.size() && tableView_)
1731 const std::vector<TableViewColumnInfo>& colInfo = tableView_->getColumnsInfo();
1733 for(
unsigned int col = 0; col < colInfo.size(); ++col)
1735 __COUTS__(11) <<
"Considering field " << colInfo[col].getName() << __E__;
1738 found = fieldAcceptList.size() ? false :
true;
1740 for(
const auto& fieldFilter : fieldAcceptList)
1752 for(
const auto& fieldFilter : fieldRejectList)
1763 __COUTS__(11) <<
"FOUND field " << colInfo[col].getName() << __E__;
1765 if(colInfo[col].isChildLink())
1768 <<
"isGroupLinkNode " << colInfo[col].getName() << __E__;
1772 std::pair<
unsigned int ,
unsigned int >
1782 tableView_->getColumnInfo(linkPair.first).getName(),
1784 &tableView_->getColumnInfo(linkPair.first)));
1785 fieldCount.push_back(-1);
1790 tableView_->getColumnInfo(linkPair.second).getName(),
1792 &tableView_->getColumnInfo(linkPair.second)));
1793 fieldCount.push_back(-1);
1800 colInfo[col].getName(),
1803 fieldCount.push_back(1);
1809 for(
unsigned int i = 0; i < recordList.size(); ++i)
1811 __COUTS__(11) <<
"Checking " << recordList[i] << __E__;
1814 node.recursiveGetCommonFields(fieldCandidateList,
1825 __COUT__ <<
"======================= check for count = " << (int)recordList.size()
1830 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1832 __COUTS__(11) <<
"Checking " << fieldCandidateList[i].relativePath_
1833 << fieldCandidateList[i].columnName_ <<
" = " << fieldCount[i]
1835 if(recordList.size() != 0 && fieldCount[i] != -1 &&
1836 fieldCount[i] != (
int)recordList.size())
1838 __COUTS__(11) <<
"Erasing " << fieldCandidateList[i].relativePath_
1839 << fieldCandidateList[i].columnName_ << __E__;
1841 fieldCount.erase(fieldCount.begin() + i);
1842 fieldCandidateList.erase(fieldCandidateList.begin() + i);
1847 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1848 __COUTS__(11) <<
"Pre-Final " << fieldCandidateList[i].relativePath_
1849 << fieldCandidateList[i].columnName_ << __E__;
1851 if(autoSelectFilterFields)
1855 std::set<std::pair<
unsigned int ,
unsigned int >>
1858 unsigned int priorityPenalty;
1859 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1861 __COUTS__(11) <<
"Option [" << i <<
"] "
1862 << fieldCandidateList[i].relativePath_
1863 << fieldCandidateList[i].columnName_ <<
" : "
1864 << fieldCandidateList[i].columnInfo_->getType() <<
":"
1865 << fieldCandidateList[i].columnInfo_->getDataType() << __E__;
1867 priorityPenalty = std::count(fieldCandidateList[i].relativePath_.begin(),
1868 fieldCandidateList[i].relativePath_.end(),
1872 if(fieldCandidateList[i].columnInfo_->isBoolType() &&
1873 (fieldCandidateList[i].columnName_ ==
1874 TableViewColumnInfo::COL_NAME_STATUS ||
1875 fieldCandidateList[i].columnName_ ==
1876 TableViewColumnInfo::COL_NAME_ENABLED))
1878 priorityPenalty += 0;
1880 else if(fieldCandidateList[i].columnInfo_->isGroupID())
1882 priorityPenalty += 1;
1884 else if(fieldCandidateList[i].columnInfo_->isBoolType())
1886 priorityPenalty += 3;
1888 else if(fieldCandidateList[i].columnInfo_->getType() ==
1889 TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA)
1891 priorityPenalty += 3;
1893 else if(fieldCandidateList[i].columnInfo_->getType() ==
1894 TableViewColumnInfo::TYPE_DATA)
1896 priorityPenalty += 10;
1900 fieldCandidateList[i].tableName_ =
1904 prioritySet.emplace(
1905 std::make_pair(priorityPenalty , i ));
1906 __COUTS__(11) <<
"Option [" << i <<
"] "
1907 << fieldCandidateList[i].relativePath_
1908 << fieldCandidateList[i].columnName_ <<
" : "
1909 << fieldCandidateList[i].columnInfo_->getType() <<
":"
1910 << fieldCandidateList[i].columnInfo_->getDataType()
1911 <<
"... priority = " << priorityPenalty << __E__;
1920 unsigned int cnt = 0;
1921 for(
const auto& priorityFieldIndex : prioritySet)
1925 << cnt <<
" marking "
1926 << fieldCandidateList[priorityFieldIndex.second].relativePath_
1927 << fieldCandidateList[priorityFieldIndex.second].columnName_
1929 fieldCandidateList[priorityFieldIndex.second].tableName_ =
1934 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1936 if(fieldCandidateList[i].tableName_ ==
"")
1938 __COUTS__(11) <<
"Erasing " << fieldCandidateList[i].relativePath_
1939 << fieldCandidateList[i].columnName_ << __E__;
1940 fieldCandidateList.erase(fieldCandidateList.begin() + i);
1946 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1947 __COUT__ <<
"Final " << fieldCandidateList[i].relativePath_
1948 << fieldCandidateList[i].columnName_ << __E__;
1950 return fieldCandidateList;
1960 const std::vector<std::string /*relative-path*/>& recordList,
1961 const std::string& fieldName,
1962 std::string* fieldGroupIDChildLinkIndex )
const
1964 if(fieldGroupIDChildLinkIndex)
1965 *fieldGroupIDChildLinkIndex =
"";
1970 __SS__ <<
"Can only get getCommonFields from a table node! "
1971 <<
"The node type is " << getNodeType() << __E__;
1977 std::set<std::string > uniqueValues;
1985 if(!recordList.size() && tableView_ && fieldGroupIDChildLinkIndex)
1988 tableView_->getColumnInfo(tableView_->
findCol(fieldName));
1995 for(
unsigned int i = 0; i < recordList.size(); ++i)
2015 if(i == 0 && fieldGroupIDChildLinkIndex)
2021 for(
auto& groupID : setOfGroupIDs)
2022 uniqueValues.emplace(groupID);
2029 return uniqueValues;
2035 void ConfigurationTree::recursiveGetCommonFields(
2036 std::vector<ConfigurationTree::RecordField>& fieldCandidateList,
2037 std::vector<int>& fieldCount,
2038 const std::vector<std::string /*relative-path*/>& fieldAcceptList,
2039 const std::vector<std::string /*relative-path*/>& fieldRejectList,
2041 const std::string& relativePathBase,
2042 bool inFirstRecord)
const
2075 for(
const auto& fieldNode : recordChildren)
2081 if(fieldNode.second.isValueNode() || fieldNode.second.isGroupLinkNode())
2084 if(fieldNode.second.isValueNode())
2086 if(fieldNode.second.getColumnInfo().getType() ==
2087 TableViewColumnInfo::TYPE_AUTHOR ||
2088 fieldNode.second.getColumnInfo().getType() ==
2089 TableViewColumnInfo::TYPE_TIMESTAMP)
2102 found = fieldAcceptList.size() ? false :
true;
2104 for(
const auto& fieldFilter : fieldAcceptList)
2105 if(fieldFilter.find(
'/') != std::string::npos)
2109 fieldFilter, relativePathBase + fieldNode.first))
2126 for(
const auto& fieldFilter : fieldRejectList)
2127 if(fieldFilter.find(
'/') != std::string::npos)
2131 fieldFilter, relativePathBase + fieldNode.first))
2150 if(fieldNode.second.isGroupLinkNode())
2156 std::pair<
unsigned int ,
unsigned int >
2160 tableView_->
findCol(fieldNode.first), isGroupLink, linkPair);
2167 tableView_->getColumnInfo(linkPair.first).getName(),
2169 &tableView_->getColumnInfo(linkPair.first)));
2170 fieldCount.push_back(1);
2175 tableView_->getColumnInfo(linkPair.second).getName(),
2177 &tableView_->getColumnInfo(linkPair.second)));
2178 fieldCount.push_back(1);
2187 &fieldNode.second.getColumnInfo()));
2188 fieldCount.push_back(1);
2196 for(j = 0; j < fieldCandidateList.size(); ++j)
2198 if((relativePathBase + fieldNode.first) ==
2199 (fieldCandidateList[j].relativePath_ +
2200 fieldCandidateList[j].columnName_))
2206 if(fieldNode.second.isGroupLinkNode() &&
2207 j + 1 < fieldCandidateList.size())
2208 ++fieldCount[j + 1];
2214 else if(fieldNode.second.isUIDLinkNode())
2223 fieldAcceptList.size() ? false :
true;
2224 for(
const auto& fieldFilter : fieldAcceptList)
2225 if(fieldFilter.find(
'/') != std::string::npos)
2229 fieldFilter, relativePathBase + fieldNode.first))
2246 for(
const auto& fieldFilter : fieldRejectList)
2247 if(fieldFilter.find(
'/') != std::string::npos)
2251 fieldFilter, relativePathBase + fieldNode.first))
2269 std::pair<
unsigned int ,
unsigned int >
2275 tableView_->
findCol(fieldNode.first), isGroupLink, linkPair);
2282 tableView_->getColumnInfo(linkPair.first).getName(),
2284 &tableView_->getColumnInfo(linkPair.first)));
2285 fieldCount.push_back(1);
2290 tableView_->getColumnInfo(linkPair.second).getName(),
2292 &tableView_->getColumnInfo(linkPair.second)));
2293 fieldCount.push_back(1);
2300 for(j = 0; j < fieldCandidateList.size() - 1; ++j)
2302 if((relativePathBase + fieldNode.first) ==
2303 (fieldCandidateList[j].relativePath_ +
2304 fieldCandidateList[j].columnName_))
2310 ++fieldCount[j + 1];
2317 if(depth > 0 && !fieldNode.second.isDisconnected())
2318 fieldNode.second.recursiveGetCommonFields(
2324 (relativePathBase + fieldNode.first) +
"/",
2337 std::vector<std::vector<std::pair<std::string, ConfigurationTree>>>
2339 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
2340 bool onlyStatusTrue)
const
2342 std::vector<std::vector<std::pair<std::string, ConfigurationTree>>> retVector;
2346 bool filtering = filterMap.size();
2347 std::string fieldValue;
2349 bool createContainer;
2351 std::vector<std::vector<std::string>> childrenNamesByPriority =
2354 for(
auto& childNamesAtPriority : childrenNamesByPriority)
2356 createContainer =
true;
2358 for(
auto& childName : childNamesAtPriority)
2368 retVector.push_back(
2369 std::vector<std::pair<std::string, ConfigurationTree>>());
2370 createContainer =
false;
2373 retVector[retVector.size() - 1].push_back(
2374 std::pair<std::string, ConfigurationTree>(
2375 childName, this->
getNode(childName,
true)));
2387 const std::string& childName,
2388 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap)
const
2394 for(
const auto& filterPair : filterMap)
2396 std::string filterPath = childName +
"/" + filterPair.first;
2397 __COUTV__(filterPath);
2403 std::vector<std::string> fieldValues;
2405 filterPair.second, fieldValues, std::set<char>({
','}) );
2407 __COUTV__(fieldValues.size());
2411 for(
const auto& fieldValue : fieldValues)
2425 bool groupIdFound =
false;
2428 for(
auto& groupID : setOfGroupIDs)
2430 __COUT__ <<
"\t\tGroupID Check: " << filterPair.first
2431 <<
" == " << fieldValue <<
" => "
2433 <<
" ??? " << groupID << __E__;
2439 __COUT__ <<
"Found match" << __E__;
2440 groupIdFound =
true;
2448 __COUT__ <<
"Found break match" << __E__;
2455 __COUT__ <<
"\t\tCheck: " << filterPair.first <<
" == " << fieldValue
2472 __SS__ <<
"Failed to access filter path '" << filterPath <<
"' - aborting."
2496 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
2498 bool onlyStatusTrue)
const
2500 std::vector<std::pair<std::string, ConfigurationTree>> retVector;
2504 bool filtering = filterMap.size();
2506 std::string fieldValue;
2508 std::vector<std::string> childrenNames =
getChildrenNames(byPriority, onlyStatusTrue);
2509 for(
auto& childName : childrenNames)
2515 retVector.push_back(std::pair<std::string, ConfigurationTree>(
2516 childName, this->
getNode(childName,
true)));
2528 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
2529 bool onlyStatusTrue)
const
2531 std::map<std::string, ConfigurationTree> retMap;
2533 bool filtering = filterMap.size();
2536 std::vector<std::string> childrenNames =
2538 for(
auto& childName : childrenNames)
2546 retMap.insert(std::pair<std::string, ConfigurationTree>(
2547 childName, this->
getNode(childName)));
2561 <<
".' Can only check the status of a UID/Record node!" << __E__;
2566 bool tmpStatus =
true;
2571 catch(
const std::runtime_error& e)
2580 bool ConfigurationTree::isStatusNode(
void)
const
2592 bool onlyStatusTrue)
const
2594 std::vector<std::vector<std::string >> retVector;
2599 <<
"' with null configuration view pointer!" << __E__;
2608 if(row_ == TableView::INVALID && col_ == TableView::INVALID)
2615 std::vector<std::vector<
unsigned int >> groupRowsByPriority =
2618 ? TableView::INVALID
2625 for(
const auto& priorityChildRowVector : groupRowsByPriority)
2627 retVector.push_back(std::vector<std::string /*child name*/>());
2628 for(
const auto& priorityChildRow : priorityChildRowVector)
2629 retVector[retVector.size() - 1].push_back(
2630 tableView_->getDataView()[priorityChildRow][tableView_->
getColUID()]);
2633 else if(row_ == TableView::INVALID)
2635 __SS__ <<
"Malformed ConfigurationTree" << __E__;
2640 else if(col_ == TableView::INVALID)
2645 for(
unsigned int c = 0; c < tableView_->getNumberOfColumns(); ++c)
2653 retVector.push_back(std::vector<std::string /*child name*/>());
2654 retVector[retVector.size() - 1].push_back(
2655 tableView_->getColumnInfo(c).getName());
2661 __SS__ <<
"\n\nError occurred looking for children of nodeName=" <<
getValueName()
2663 <<
"Invalid depth! getChildrenValues() called from a value point in the "
2664 "Configuration Tree."
2678 bool onlyStatusTrue)
const
2680 std::vector<std::string > retVector;
2688 retVector.push_back(configPair.first);
2695 __SS__ <<
"Can not get children names of '" <<
getFieldName() <<
":"
2704 if(row_ == TableView::INVALID && col_ == TableView::INVALID)
2708 std::vector<
unsigned int > groupRows = tableView_->
getGroupRows(
2710 ? TableView::INVALID
2718 for(
const auto& groupRow : groupRows)
2719 retVector.push_back(
2720 tableView_->getDataView()[groupRow][tableView_->
getColUID()]);
2787 else if(row_ == TableView::INVALID)
2789 __SS__ <<
"Malformed ConfigurationTree" << __E__;
2794 else if(col_ == TableView::INVALID)
2799 for(
unsigned int c = 0; c < tableView_->getNumberOfColumns(); ++c)
2806 retVector.push_back(tableView_->getColumnInfo(c).getName());
2811 __SS__ <<
"\n\nError occurred looking for children of nodeName=" <<
getValueName()
2813 <<
"Invalid depth! getChildrenValues() called from a value point in the "
2814 "Configuration Tree."
2835 __SS__ <<
"Invalid node for get value." << __E__;
2839 std::string valueString =
2842 if(valueString.size() && valueString[0] ==
'/')
2849 __COUT__ <<
"Found a valid tree path in value!" << __E__;
2854 __SS__ <<
"Invalid tree path." << __E__;
2860 __SS__ <<
"Invalid value string '" << valueString
2861 <<
"' - must start with a '/' character." << __E__;
std::map< std::string, TableVersion > getActiveVersions(void) const
getActiveVersions
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
"root/parent/parent/"
const TableBase * getTableByName(const std::string &configurationName) const
const unsigned int & getRow(void) const
getRow
const std::string & getValueDataType(void) const
bool isUIDNode(void) const
std::map< std::string, ConfigurationTree > getNodes(const std::string &nodeString) const
getNodes
const TableVersion & getTableVersion(void) const
getTableVersion
bool isDisconnected(void) const
const std::string & getAuthor(void) const
getAuthor
const std::string & getComment(void) const
getComment
std::vector< std::string > getChildrenNames(bool byPriority=false, bool onlyStatusTrue=false) const
bool isEnabled(void) const
same as status()
static const std::string NODE_TYPE_GROUP_TABLE
bool isValueNumberDataType(void) const
ConfigurationTree getNode(const std::string &nodeName, bool doNotThrowOnBrokenUIDLinks=false) const
navigating between nodes
const std::string & getTableName(void) const
getTableName
T getValueWithDefault(const T &defaultValue) const
const unsigned int & getFieldRow(void) const
std::map< std::string, ConfigurationTree > getChildrenMap(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool onlyStatusTrue=false) const
const std::string & getValueName(void) const
const std::string & getValueAsString(bool returnLinkTableValue=false) const
const ConfigurationManager * getConfigurationManager(void) const
extracting information from node
const std::string & getChildLinkIndex(void) const
getChildLinkIndex
void print(const unsigned int &depth=-1, std::ostream &out=std::cout) const
bool isGroupIDNode(void) const
const std::string & getDisconnectedTableName(void) const
getDisconnectedTableName
bool isValueBoolType(void) const
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
std::vector< std::string > getFixedChoices(void) const
bool isLinkNode(void) const
const std::string & getDefaultValue(void) const
const time_t & getTableCreationTime(void) const
getTableCreationTime
const std::string & getUIDAsString(void) const
std::vector< ConfigurationTree::RecordField > getCommonFields(const std::vector< std::string > &recordList, const std::vector< std::string > &fieldAcceptList, const std::vector< std::string > &fieldRejectList, unsigned int depth=-1, bool autoSelectFilterFields=false) const
const unsigned int & getNodeRow(void) const
getNodeRow
std::set< std::string > getSetOfGroupIDs(void) const
bool isValueNode(void) const
const std::string & getFieldName(void) const
alias for getValueName
std::vector< std::vector< std::string > > getChildrenNamesByPriority(bool onlyStatusTrue=false) const
std::set< std::string > getUniqueValuesForField(const std::vector< std::string > &recordList, const std::string &fieldName, std::string *fieldGroupIDChildLinkIndex=0) const
const std::string & getValueType(void) const
bool passFilterMap(const std::string &childName, std::map< std::string, std::string > filterMap) const
std::string nodeDump(void) const
used for debugging (when throwing exception)
~ConfigurationTree(void)
destructor
bool isGroupLinkNode(void) const
const std::string & getFieldTableName(void) const
const unsigned int & getColumn(void) const
getColumn
const std::string & getDisconnectedLinkID(void) const
getDisconnectedLinkID
const std::string & getParentTableName(void) const
getParentTableName
bool isUIDLinkNode(void) const
std::string getEscapedValue(void) const
const TableViewColumnInfo & getColumnInfo(void) const
bool isDefaultValue(void) const
boolean info
std::vector< std::vector< std::pair< std::string, ConfigurationTree > > > getChildrenByPriority(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool onlyStatusTrue=false) const
T getValue(void) const
defined in included .icc source
const unsigned int & getFieldColumn(void) const
const std::string & getTableName(void) const
Getters.
bool isChildLinkUID(void) const
static const std::string DATATYPE_NUMBER
std::string getChildLinkIndex(void) const
getChildLinkIndex
bool isGroupID(void) const
static const std::string TYPE_UID
NOTE: Do NOT put '-' in static const TYPEs because it will mess up javascript handling in the web gui...
const BitMapInfo & getBitMapInfo(void) const
uses dataChoices CSV fields if type is TYPE_BITMAP_DATA
bool isBoolType(void) const
TODO check if min and max values need a function called getallminmaxforgui or something like that for...
bool isNumberDataType(void) const
isNumberDataType
bool isChildLinkGroupID(void) const
unsigned int findRow(unsigned int col, const T &value, unsigned int offsetRow=0, bool doNotThrow=false) const
< in included .icc source
std::string getEscapedValueAsString(unsigned int row, unsigned int col, bool convertEnvironmentVariables=true, bool quotesToDoubleQuotes=false) const
std::vector< std::vector< unsigned int > > getGroupRowsByPriority(const unsigned int groupIdCol, const std::string &groupID, bool onlyStatusTrue=false) const
T validateValueForColumn(const std::string &value, unsigned int col, bool doConvertEnvironmentVariables=true) const
< in included .icc source
unsigned int getColStatus(void) const
unsigned int getLinkGroupIDColumn(const std::string &childLinkIndex) const
bool getChildLink(const unsigned int &col, bool &isGroup, std::pair< unsigned int, unsigned int > &linkPair) const
std::string getValueAsString(unsigned int row, unsigned int col, bool convertEnvironmentVariables=true) const
std::vector< unsigned int > getGroupRows(const unsigned int groupIdCol, const std::string &groupID, bool onlyStatusTrue=false, bool orderedByPriority=false) const
std::set< std::string > getSetOfGroupIDs(const std::string &childLinkIndex, unsigned int row=-1) const
void getValue(T &value, unsigned int row, unsigned int col, bool doConvertEnvironmentVariables=true) const
< in included .icc source
unsigned int getColUID(void) const
unsigned int findCol(const std::string &name) const
unsigned int findRowInGroup(unsigned int col, const T &value, const std::string &groupId, const std::string &childLinkIndex, unsigned int offsetRow=0) const
< in included .icc source
extracting information from a list of records
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
setToString ~
static std::string vectorToString(const std::vector< T > &setToReturn, const std::string &delimeter=", ")
vectorToString ~
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static bool wildCardMatch(const std::string &needle, const std::string &haystack, unsigned int *priorityIndex=0)
static std::string decodeURIComponent(const std::string &data)
static std::string stackTrace(void)