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 =
"/";
20 ConfigurationTree::ConfigurationTree()
24 , linkParentConfig_(0)
29 , disconnectedTargetName_(
"")
30 , disconnectedLinkID_(
"")
66 const std::string& groupId,
68 const std::string& linkColName,
69 const std::string& linkColValue,
70 const unsigned int linkBackRow,
71 const unsigned int linkBackCol,
72 const std::string& disconnectedTargetName,
73 const std::string& disconnectedLinkID,
74 const std::string& childLinkIndex,
75 const unsigned int row,
76 const unsigned int col)
77 : configMgr_(configMgr)
80 , linkParentConfig_(linkParentConfig)
81 , linkColName_(linkColName)
82 , linkColValue_(linkColValue)
83 , linkBackRow_(linkBackRow)
84 , linkBackCol_(linkBackCol)
85 , disconnectedTargetName_(disconnectedTargetName)
86 , disconnectedLinkID_(disconnectedLinkID)
87 , childLinkIndex_(childLinkIndex)
97 __SS__ <<
"Invalid empty pointer given to tree!\n"
98 <<
"\n\tconfigMgr_=" << configMgr_ <<
"\n\tconfiguration_=" << table_
99 <<
"\n\tconfigView_=" << tableView_ << __E__;
101 ss << nodeDump() << __E__;
106 tableView_ = &(table_->getView());
109 if(tableView_ && tableView_->getColumnInfo(tableView_->getColUID()).getType() !=
110 TableViewColumnInfo::TYPE_UID)
112 __SS__ <<
"Missing UID column (must column of type "
113 << TableViewColumnInfo::TYPE_UID
114 <<
") in config view : " << tableView_->getTableName() << __E__;
116 ss << nodeDump() << __E__;
123 ConfigurationTree::~ConfigurationTree(
void)
134 void ConfigurationTree::print(
const unsigned int& depth, std::ostream& out)
const
136 recursivePrint(*
this, depth, out,
"\t");
146 out << space << t.getValueName() <<
" :\t" << t.getValueAsString() << __E__;
151 out << space << t.getValueName();
152 if(t.isDisconnected())
154 out <<
" :\t" << t.getValueAsString() << __E__;
157 out <<
" (" << (t.isGroupLinkNode() ?
"Group" :
"U")
158 <<
"ID=" << t.getValueAsString() <<
") : " << __E__;
161 out << space << t.getValueAsString() <<
" : " << __E__;
167 auto C = t.getChildren();
169 out << space <<
"{" << __E__;
171 recursivePrint(c.second, depth - 1, out, space +
" ");
173 out << space <<
"}" << __E__;
179 std::string ConfigurationTree::handleValidateValueForColumn(
187 __SS__ <<
"Null configView" << __E__;
189 ss << nodeDump() << __E__;
192 __COUT__ <<
"handleValidateValueForColumn<string>" << __E__;
193 return configView->validateValueForColumn(value, col);
201 void ConfigurationTree::getValue(std::string& value)
const
205 if(row_ != TableView::INVALID &&
206 col_ != TableView::INVALID)
213 __COUT__ <<
"Success following path to tree node!" << __E__;
221 value = tableView_->validateValueForColumn(valueAsTreeNode.getValueAsString(),
224 __COUT__ <<
"Successful value!" << __E__;
238 tableView_->getValue(value, row_, col_);
240 else if(row_ == TableView::INVALID &&
241 col_ == TableView::INVALID)
243 if(isLinkNode() && isDisconnected())
245 (groupId_ ==
"") ? getValueName() : groupId_;
249 value = (groupId_ ==
"") ? table_->getTableName() : groupId_;
251 else if(row_ == TableView::INVALID)
253 __SS__ <<
"Malformed ConfigurationTree" << __E__;
256 else if(col_ == TableView::INVALID)
257 tableView_->getValue(value, row_, tableView_->getColUID());
260 __SS__ <<
"Impossible." << __E__;
278 std::string ConfigurationTree::getValue()
const
281 ConfigurationTree::getValue(value);
294 if(row_ != TableView::INVALID &&
295 col_ != TableView::INVALID)
297 std::string bitmapString;
298 tableView_->getValue(bitmapString, row_, col_);
300 __COUTV__(bitmapString);
301 if(bitmapString == TableViewColumnInfo::DATATYPE_STRING_DEFAULT)
303 bitmap.isDefault_ =
true;
307 bitmap.isDefault_ =
false;
311 bitmap.bitmap_.clear();
313 bool openRow =
false;
314 unsigned int startInt = -1;
315 for(
unsigned int i = 0; i < bitmapString.length(); i++)
317 __COUTV__(bitmapString[i]);
325 if(bitmapString[i] ==
'[')
329 bitmap.bitmap_.push_back(std::vector<uint64_t>());
331 else if(bitmapString[i] ==
']')
335 else if(bitmapString[i] ==
',')
339 <<
"Too many ']' or ',' characters in bit map configuration"
342 ss << nodeDump() << __E__;
346 else if(startInt == (
unsigned int)-1)
348 if(bitmapString[i] ==
']')
353 else if(bitmapString[i] >=
'0' &&
354 bitmapString[i] <=
'9')
358 else if(bitmapString[i] ==
',')
360 __SS__ <<
"Too many ',' characters in bit map configuration"
363 ss << nodeDump() << __E__;
371 if(bitmapString[i] ==
375 bitmap.bitmap_[row].push_back(strtoul(
376 bitmapString.substr(startInt, i - startInt).c_str(), 0, 0));
379 else if(bitmapString[i] ==
',')
381 bitmap.bitmap_[row].push_back(strtoul(
382 bitmapString.substr(startInt, i - startInt).c_str(), 0, 0));
388 for(
unsigned int r = 0; r < bitmap.bitmap_.size(); ++r)
390 for(
unsigned int c = 0; c < bitmap.bitmap_[r].size(); ++c)
392 __COUT__ << r <<
"," << c <<
" = " << bitmap.bitmap_[r][c] << __E__;
394 __COUT__ <<
"================" << __E__;
400 __SS__ <<
"Requesting getValue must be on a value node." << __E__;
402 ss << nodeDump() << __E__;
414 ConfigurationTree::getValueAsBitMap(value);
421 std::string ConfigurationTree::getEscapedValue()
const
423 if(row_ != TableView::INVALID &&
424 col_ != TableView::INVALID)
425 return tableView_->getEscapedValueAsString(row_, col_);
427 __SS__ <<
"Can not get escaped value except from a value node!"
428 <<
" This node is type '" << getNodeType() <<
"." << __E__;
430 ss << nodeDump() << __E__;
436 const std::string& ConfigurationTree::getTableName(
void)
const
440 __SS__ <<
"Can not get configuration name of node with no configuration pointer! "
441 <<
"Is there a broken link? " << __E__;
442 if(linkParentConfig_)
444 ss <<
"Error occurred traversing from " << linkParentConfig_->getTableName()
446 << linkParentConfig_->getView().getValueAsString(
447 linkBackRow_, linkParentConfig_->getView().getColUID())
448 <<
"' at row " << linkBackRow_ <<
" col '"
449 << linkParentConfig_->getView().getColumnInfo(linkBackCol_).getName()
452 ss << StringMacros::stackTrace() << __E__;
457 return table_->getTableName();
462 const unsigned int& ConfigurationTree::getNodeRow(
void)
const
464 if(isUIDNode() || isValueNode())
467 __SS__ <<
"Can only get row from a UID or value node!" << __E__;
468 if(linkParentConfig_)
470 ss <<
"Error occurred traversing from " << linkParentConfig_->getTableName()
472 << linkParentConfig_->getView().getValueAsString(
473 linkBackRow_, linkParentConfig_->getView().getColUID())
474 <<
"' at row " << linkBackRow_ <<
" col '"
475 << linkParentConfig_->getView().getColumnInfo(linkBackCol_).getName()
478 ss << StringMacros::stackTrace() << __E__;
490 const std::string& ConfigurationTree::getFieldTableName(
void)
const
495 if(!linkParentConfig_)
497 __SS__ <<
"Can not get configuration name of link node field with no parent "
498 "configuration pointer!"
500 ss << nodeDump() << __E__;
503 return linkParentConfig_->getTableName();
506 return getTableName();
511 const std::string& ConfigurationTree::getDisconnectedTableName(
void)
const
513 if(isLinkNode() && isDisconnected())
514 return disconnectedTargetName_;
516 __SS__ <<
"Can not get disconnected target name of node unless it is a disconnected "
520 ss << nodeDump() << __E__;
526 const std::string& ConfigurationTree::getDisconnectedLinkID(
void)
const
528 if(isLinkNode() && isDisconnected())
529 return disconnectedLinkID_;
531 __SS__ <<
"Can not get disconnected target name of node unless it is a disconnected "
535 ss << nodeDump() << __E__;
541 const TableVersion& ConfigurationTree::getTableVersion(
void)
const
545 __SS__ <<
"Can not get configuration version of node with no config view pointer!"
548 ss << nodeDump() << __E__;
551 return tableView_->getVersion();
556 const time_t& ConfigurationTree::getTableCreationTime(
void)
const
560 __SS__ <<
"Can not get configuration creation time of node with no config view "
564 ss << nodeDump() << __E__;
567 return tableView_->getCreationTime();
574 std::vector<std::string> ConfigurationTree::getFixedChoices(
void)
const
576 if(getValueType() != TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA &&
577 getValueType() != TableViewColumnInfo::TYPE_BITMAP_DATA && !isLinkNode())
579 __SS__ <<
"Can not get fixed choices of node with value type of '"
580 << getValueType() <<
".' Node must be a link or a value node with type '"
581 << TableViewColumnInfo::TYPE_BITMAP_DATA <<
"' or '"
582 << TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA <<
".'" << __E__;
584 ss << nodeDump() << __E__;
588 std::vector<std::string> retVec;
592 if(!linkParentConfig_)
595 <<
"Can not get fixed choices of node with no parent config view pointer!"
598 ss << nodeDump() << __E__;
608 const TableView* parentView = &(linkParentConfig_->getView());
609 int c = parentView->findCol(linkColName_);
611 std::pair<
unsigned int ,
unsigned int > linkPair;
613 parentView->getChildLink(c, isGroupLink, linkPair);
616 std::vector<std::string> choices = parentView->getColumnInfo(c).getDataChoices();
617 for(
const auto& choice : choices)
618 retVec.push_back(choice);
625 __SS__ <<
"Can not get fixed choices of node with no config view pointer!"
628 ss << nodeDump() << __E__;
633 retVec.push_back(tableView_->getColumnInfo(col_).getDefaultValue());
634 std::vector<std::string> choices = tableView_->getColumnInfo(col_).getDataChoices();
635 for(
const auto& choice : choices)
636 retVec.push_back(choice);
649 const std::string& ConfigurationTree::getValueAsString(
bool returnLinkTableValue)
const
655 if(returnLinkTableValue)
656 return linkColValue_;
657 else if(isDisconnected())
658 return ConfigurationTree::DISCONNECTED_VALUE;
659 else if(row_ == TableView::INVALID &&
660 col_ == TableView::INVALID)
661 return (groupId_ ==
"") ? table_->getTableName() : groupId_;
662 else if(col_ == TableView::INVALID)
663 return tableView_->getDataView()[row_][tableView_->getColUID()];
666 __SS__ <<
"Impossible Link." << __E__;
668 ss << nodeDump() << __E__;
672 else if(row_ != TableView::INVALID &&
673 col_ != TableView::INVALID)
674 return tableView_->getDataView()[row_][col_];
675 else if(row_ == TableView::INVALID &&
676 col_ == TableView::INVALID)
680 return ConfigurationTree::ROOT_NAME;
682 return (groupId_ ==
"") ? table_->getTableName() : groupId_;
684 else if(row_ == TableView::INVALID)
686 __SS__ <<
"Malformed ConfigurationTree" << __E__;
688 ss << nodeDump() << __E__;
691 else if(col_ == TableView::INVALID)
692 return tableView_->getDataView()[row_][tableView_->getColUID()];
695 __SS__ <<
"Impossible." << __E__;
697 ss << nodeDump() << __E__;
706 const std::string& ConfigurationTree::getUIDAsString(
void)
const
708 if(isValueNode() || isUIDLinkNode())
709 return tableView_->getDataView()[row_][tableView_->getColUID()];
712 __SS__ <<
"Can not get UID of node with type '" << getNodeType()
713 <<
".' Node type must be '" << ConfigurationTree::NODE_TYPE_VALUE
714 <<
"' or '" << ConfigurationTree::NODE_TYPE_UID_LINK <<
".'" << __E__;
716 ss << nodeDump() << __E__;
724 const std::string& ConfigurationTree::getValueDataType(
void)
const
727 return tableView_->getColumnInfo(col_).getDataType();
729 return TableViewColumnInfo::DATATYPE_STRING;
735 bool ConfigurationTree::isDefaultValue(
void)
const
740 if(getValueDataType() == TableViewColumnInfo::DATATYPE_STRING)
742 if(getValueType() == TableViewColumnInfo::TYPE_ON_OFF ||
743 getValueType() == TableViewColumnInfo::TYPE_TRUE_FALSE ||
744 getValueType() == TableViewColumnInfo::TYPE_YES_NO)
745 return getValueAsString() ==
746 TableViewColumnInfo::DATATYPE_BOOL_DEFAULT;
748 else if(getValueType() == TableViewColumnInfo::TYPE_COMMENT)
749 return getValueAsString() == TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT ||
750 getValueAsString() ==
753 return getValueAsString() == TableViewColumnInfo::DATATYPE_STRING_DEFAULT;
755 else if(getValueDataType() == TableViewColumnInfo::DATATYPE_NUMBER)
756 return getValueAsString() == TableViewColumnInfo::DATATYPE_NUMBER_DEFAULT;
757 else if(getValueDataType() == TableViewColumnInfo::DATATYPE_TIME)
758 return getValueAsString() == TableViewColumnInfo::DATATYPE_TIME_DEFAULT;
766 const std::string& ConfigurationTree::getValueType(
void)
const
769 return tableView_->getColumnInfo(col_).getType();
770 else if(isLinkNode() && isDisconnected())
771 return ConfigurationTree::VALUE_TYPE_DISCONNECTED;
773 return ConfigurationTree::VALUE_TYPE_NODE;
782 return tableView_->getColumnInfo(col_);
785 __SS__ <<
"Can only get column info from a value node! "
786 <<
"The node type is " << getNodeType() << __E__;
788 ss << nodeDump() << __E__;
795 const unsigned int& ConfigurationTree::getRow(
void)
const {
return row_; }
799 const unsigned int& ConfigurationTree::getColumn(
void)
const {
return col_; }
804 const unsigned int& ConfigurationTree::getFieldRow(
void)
const
818 const unsigned int& ConfigurationTree::getFieldColumn(
void)
const
831 const std::string& ConfigurationTree::getChildLinkIndex(
void)
const
835 __SS__ <<
"Can only get link ID from a link! "
836 <<
"The node type is " << getNodeType() << __E__;
838 ss << nodeDump() << __E__;
841 return childLinkIndex_;
847 const std::string& ConfigurationTree::getValueName(
void)
const
850 return tableView_->getColumnInfo(col_).getName();
851 else if(isLinkNode())
855 __SS__ <<
"Can only get value name of a value node!" << __E__;
857 ss << nodeDump() << __E__;
866 const std::string& childPath,
867 bool doNotThrowOnBrokenUIDLinks,
868 const std::string& originalNodeString)
872 if(childPath.length() <= 1)
874 return tree.recursiveGetNode(
875 childPath, doNotThrowOnBrokenUIDLinks, originalNodeString);
914 bool doNotThrowOnBrokenUIDLinks)
const
916 return recursiveGetNode(
917 nodeString, doNotThrowOnBrokenUIDLinks,
"" );
920 const std::string& nodeString,
921 bool doNotThrowOnBrokenUIDLinks,
922 const std::string& originalNodeString)
const
929 if(nodeString.length() < 1)
931 __SS__ <<
"Invalid empty node name! Looking for child node from node '"
932 << getValue() <<
"'..." << __E__;
934 ss << nodeDump() << __E__;
938 bool startingSlash = nodeString[0] ==
'/';
940 std::string nodeName = nodeString.substr(
941 startingSlash ? 1 : 0, nodeString.find(
'/', 1) - (startingSlash ? 1 : 0));
944 std::string childPath =
945 nodeString.substr(nodeName.length() + (startingSlash ? 1 : 0));
958 return recurse(configMgr_->getNode(nodeName),
960 doNotThrowOnBrokenUIDLinks,
963 else if(row_ == TableView::INVALID && col_ == TableView::INVALID)
969 __SS__ <<
"Missing configView pointer! Likely attempting to access a "
970 "child node through a disconnected link node."
973 ss << nodeDump() << __E__;
993 ? tableView_->findRow(tableView_->getColUID(), nodeName)
994 : tableView_->findRowInGroup(tableView_->getColUID(),
999 doNotThrowOnBrokenUIDLinks,
1000 originalNodeString);
1002 else if(row_ == TableView::INVALID)
1004 __SS__ <<
"Malformed ConfigurationTree" << __E__;
1006 ss << nodeDump() << __E__;
1009 else if(col_ == TableView::INVALID)
1025 __SS__ <<
"Missing configView pointer! Likely attempting to access a "
1026 "child node through a disconnected link node."
1029 ss << nodeDump() << __E__;
1033 unsigned int c = tableView_->findCol(nodeName);
1034 std::pair<
unsigned int ,
unsigned int > linkPair;
1035 bool isGroupLink, isLink;
1036 if((isLink = tableView_->getChildLink(c, isGroupLink, linkPair)) &&
1047 childConfig = configMgr_->getTableByName(
1048 tableView_->getDataView()[row_][linkPair.first]);
1049 childConfig->getView();
1051 if(doNotThrowOnBrokenUIDLinks)
1053 childConfig->getView().findRow(
1054 childConfig->getView().getColUID(),
1055 tableView_->getDataView()[row_][linkPair.second]);
1074 tableView_->getDataView()[row_][c],
1079 tableView_->getDataView()[row_][linkPair.first],
1082 tableView_->getDataView()[row_][linkPair.second],
1085 tableView_->getColumnInfo(c).getChildLinkIndex());
1095 tableView_->getDataView()[row_][c],
1102 tableView_->getColumnInfo(c).getChildLinkIndex(),
1103 childConfig->getView().findRow(
1104 childConfig->getView().getColUID(),
1105 tableView_->getDataView()[row_][linkPair.second])),
1107 doNotThrowOnBrokenUIDLinks,
1108 originalNodeString);
1120 childConfig = configMgr_->getTableByName(
1121 tableView_->getDataView()[row_][linkPair.first]);
1122 childConfig->getView();
1126 if(tableView_->getDataView()[row_][linkPair.first] !=
1127 TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
1129 <<
"Found disconnected node! Failed link target "
1131 << nodeName <<
" to table:id="
1132 << tableView_->getDataView()[row_][linkPair.first] <<
":"
1133 << tableView_->getDataView()[row_][linkPair.second] << __E__;
1139 tableView_->getDataView()[row_][linkPair.second],
1142 tableView_->getDataView()[row_][c],
1147 tableView_->getDataView()[row_][linkPair.first],
1150 tableView_->getDataView()[row_][linkPair.second],
1153 tableView_->getColumnInfo(c).getChildLinkIndex());
1161 ->getDataView()[row_][linkPair.second],
1164 tableView_->getDataView()[row_][c],
1171 tableView_->getColumnInfo(c).getChildLinkIndex()),
1173 doNotThrowOnBrokenUIDLinks,
1174 originalNodeString);
1186 TableView::INVALID ,
1187 TableView::INVALID ,
1196 catch(std::runtime_error& e)
1198 __SS__ <<
"\n\nError occurred descending from node '" << getValue()
1199 <<
"' in table '" << getTableName() <<
"' looking for child '" << nodeName
1202 ss <<
"The original node search string was '" << originalNodeString <<
".'"
1204 ss <<
"--- Additional error detail: \n\n" << e.what() << __E__;
1206 ss << nodeDump() << __E__;
1211 __SS__ <<
"\n\nError occurred descending from node '" << getValue()
1212 <<
"' in table '" << getTableName() <<
"' looking for child '" << nodeName
1215 ss <<
"The original node search string was '" << originalNodeString <<
".'"
1218 ss << nodeDump() << __E__;
1224 <<
"\n\nError occurred descending from node '" << getValue() <<
"' in table '"
1225 << getTableName() <<
"' looking for child '" << nodeName <<
"'\n\n"
1226 <<
"Invalid depth! getNode() called from a value point in the Configuration Tree."
1228 ss <<
"The original node search string was '" << originalNodeString <<
".'" << __E__;
1230 ss << nodeDump() << __E__;
1237 std::string ConfigurationTree::nodeDump(
void)
const
1239 __SS__ << __E__ << __E__;
1241 ss <<
"Row=" << (int)row_ <<
", Col=" << (
int)col_ << ", TablePointer=" << table_
1246 ss <<
"\n\n" << StringMacros::stackTrace() << __E__ << __E__;
1252 ss <<
"ConfigurationTree::nodeDump() "
1253 "=====================================\nConfigurationTree::nodeDump():"
1260 <<
"Error occurred from node '" << getValueAsString() <<
"'..." << __E__;
1268 <<
"Error occurred from node '" << getValue() <<
"' in table '"
1269 << getTableName() <<
".'" << __E__;
1276 auto children = getChildrenNames();
1278 <<
"Here is the list of possible children (count = " << children.size()
1280 for(
auto& child : children)
1281 ss <<
"\t\t" << child << __E__;
1284 ss <<
"\n\nHere is the culprit table printout:\n\n";
1285 tableView_->print(ss);
1292 ss <<
"end ConfigurationTree::nodeDump() ====================================="
1300 unsigned int backSteps)
const
1302 for(
unsigned int i = 0; i < backSteps; i++)
1303 nodeName = nodeName.substr(0, nodeName.find_last_of(
'/'));
1305 return getNode(nodeName);
1310 unsigned int forwardSteps)
const
1315 while(s < nodeName.length() && nodeName[s] ==
'/')
1318 for(
unsigned int i = 0; i < forwardSteps; i++)
1319 s = nodeName.find(
'/', s) + 1;
1321 return getNode(nodeName.substr(0, s));
1327 bool ConfigurationTree::isValueNode(
void)
const
1329 return (row_ != TableView::INVALID && col_ != TableView::INVALID);
1335 bool ConfigurationTree::isValueBoolType(
void)
const
1337 return isValueNode() && tableView_->getColumnInfo(col_).isBoolType();
1343 bool ConfigurationTree::isValueNumberDataType(
void)
const
1345 return isValueNode() && tableView_->getColumnInfo(col_).isNumberDataType();
1353 bool ConfigurationTree::isDisconnected(
void)
const
1357 __SS__ <<
"\n\nError occurred testing link connection at node with value '"
1358 << getValue() <<
"' in table '" << getTableName() <<
"'\n\n"
1360 ss <<
"This is not a Link node! It is node type '" << getNodeType()
1361 <<
".' Only a Link node can be disconnected." << __E__;
1363 ss << nodeDump() << __E__;
1367 return !table_ || !tableView_;
1373 bool ConfigurationTree::isLinkNode(
void)
const {
return linkColName_ !=
""; }
1378 const std::string ConfigurationTree::NODE_TYPE_GROUP_TABLE =
"GroupTableNode";
1379 const std::string ConfigurationTree::NODE_TYPE_TABLE =
"TableNode";
1380 const std::string ConfigurationTree::NODE_TYPE_GROUP_LINK =
"GroupLinkNode";
1381 const std::string ConfigurationTree::NODE_TYPE_UID_LINK =
"UIDLinkNode";
1382 const std::string ConfigurationTree::NODE_TYPE_VALUE =
"ValueNode";
1383 const std::string ConfigurationTree::NODE_TYPE_UID =
"UIDNode";
1384 const std::string ConfigurationTree::NODE_TYPE_ROOT =
"RootNode";
1386 std::string ConfigurationTree::getNodeType(
void)
const
1389 return ConfigurationTree::NODE_TYPE_ROOT;
1390 if(isTableNode() && groupId_ !=
"")
1391 return ConfigurationTree::NODE_TYPE_GROUP_TABLE;
1393 return ConfigurationTree::NODE_TYPE_TABLE;
1394 if(isGroupLinkNode())
1395 return ConfigurationTree::NODE_TYPE_GROUP_LINK;
1397 return ConfigurationTree::NODE_TYPE_UID_LINK;
1399 return ConfigurationTree::NODE_TYPE_VALUE;
1400 return ConfigurationTree::NODE_TYPE_UID;
1406 bool ConfigurationTree::isGroupLinkNode(
void)
const
1408 return (isLinkNode() && groupId_ !=
"");
1414 bool ConfigurationTree::isUIDLinkNode(
void)
const
1416 return (isLinkNode() && groupId_ ==
"");
1422 bool ConfigurationTree::isGroupIDNode(
void)
const
1424 return (isValueNode() && tableView_->getColumnInfo(col_).isGroupID());
1430 bool ConfigurationTree::isUIDNode(
void)
const
1432 return (row_ != TableView::INVALID && col_ == TableView::INVALID);
1451 std::vector<ConfigurationTree::RecordField> ConfigurationTree::getCommonFields(
1452 const std::vector<std::string /*uid*/>& recordList,
1453 const std::vector<std::string /*relative-path*/>& fieldAcceptList,
1454 const std::vector<std::string /*relative-path*/>& fieldRejectList,
1456 bool autoSelectFilterFields)
const
1459 if(!isRootNode() && !isTableNode())
1461 __SS__ <<
"Can only get getCommonFields from a root or table node! "
1462 <<
"The node type is " << getNodeType() << __E__;
1464 ss << nodeDump() << __E__;
1468 std::vector<ConfigurationTree::RecordField> fieldCandidateList;
1469 std::vector<int> fieldCount;
1512 for(
unsigned int i = 0; i < recordList.size(); ++i)
1517 std::vector<std::pair<std::string, ConfigurationTree>> recordChildren =
1520 for(
const auto& fieldNode : recordChildren)
1525 if(fieldNode.second.isValueNode() || fieldNode.second.isGroupLinkNode())
1528 if(fieldNode.second.isValueNode())
1530 if(fieldNode.second.getColumnInfo().getType() ==
1531 TableViewColumnInfo::TYPE_AUTHOR ||
1532 fieldNode.second.getColumnInfo().getType() ==
1533 TableViewColumnInfo::TYPE_TIMESTAMP)
1542 found = fieldAcceptList.size() ?
false
1544 for(
const auto& fieldFilter : fieldAcceptList)
1545 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1556 for(
const auto& fieldFilter : fieldRejectList)
1557 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1568 if(fieldNode.second.isGroupLinkNode())
1574 std::pair<
unsigned int ,
1578 node.tableView_->getChildLink(
1579 node.tableView_->findCol(fieldNode.first),
1586 node.table_->getTableName(),
1588 node.tableView_->getColumnInfo(linkPair.first).getName(),
1590 &node.tableView_->getColumnInfo(linkPair.first)));
1591 fieldCount.push_back(-1);
1594 node.table_->getTableName(),
1596 node.tableView_->getColumnInfo(linkPair.second).getName(),
1598 &node.tableView_->getColumnInfo(linkPair.second)));
1599 fieldCount.push_back(-1);
1604 fieldNode.second.getTableName(),
1608 &fieldNode.second.getColumnInfo()));
1609 fieldCount.push_back(-1);
1616 else if(depth > 0 && fieldNode.second.isUIDLinkNode())
1626 found = fieldAcceptList.size() ?
false
1628 for(
const auto& fieldFilter : fieldAcceptList)
1629 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1640 for(
const auto& fieldFilter : fieldRejectList)
1641 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1652 std::pair<
unsigned int ,
unsigned int >
1657 node.tableView_->getChildLink(
1658 node.tableView_->findCol(fieldNode.first),
1665 node.table_->getTableName(),
1667 node.tableView_->getColumnInfo(linkPair.first).getName(),
1669 &node.tableView_->getColumnInfo(linkPair.first)));
1670 fieldCount.push_back(-1);
1673 node.table_->getTableName(),
1675 node.tableView_->getColumnInfo(linkPair.second).getName(),
1677 &node.tableView_->getColumnInfo(linkPair.second)));
1678 fieldCount.push_back(-1);
1684 if(!fieldNode.second.isDisconnected())
1685 fieldNode.second.recursiveGetCommonFields(
1691 fieldNode.first +
"/",
1703 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1708 if(fieldCount[i] != -1 && fieldCount[i] != (
int)recordList.size())
1713 fieldCount.erase(fieldCount.begin() + i);
1714 fieldCandidateList.erase(fieldCandidateList.begin() + i);
1723 if(autoSelectFilterFields)
1727 std::set<std::pair<
unsigned int ,
unsigned int >>
1730 unsigned int highestPriority = 0;
1731 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1739 if(fieldCandidateList[i].columnInfo_->isBoolType())
1740 prioritySet.emplace(
1741 std::make_pair(0 , i ));
1742 else if(fieldCandidateList[i].columnInfo_->isGroupID())
1744 prioritySet.emplace(
1745 std::make_pair(1 , i ));
1746 if(highestPriority < 1)
1747 highestPriority = 1;
1749 else if(fieldCandidateList[i].columnInfo_->getType() ==
1750 TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA)
1752 prioritySet.emplace(
1753 std::make_pair(3 , i ));
1754 if(highestPriority < 3)
1755 highestPriority = 3;
1757 else if(fieldCandidateList[i].columnInfo_->getType() ==
1758 TableViewColumnInfo::TYPE_DATA)
1760 prioritySet.emplace(
1761 std::make_pair(10 , i ));
1762 if(highestPriority < 10)
1763 highestPriority = 10;
1767 fieldCandidateList[i].tableName_ =
1774 __COUTV__(StringMacros::setToString(prioritySet));
1779 unsigned int cnt = 0;
1780 for(
const auto& priorityFieldIndex : prioritySet)
1790 fieldCandidateList[priorityFieldIndex.second].tableName_ =
1795 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1797 if(fieldCandidateList[i].tableName_ ==
"")
1802 fieldCandidateList.erase(fieldCandidateList.begin() + i);
1808 for(
unsigned int i = 0; i < fieldCandidateList.size(); ++i)
1809 __COUT__ <<
"Final " << fieldCandidateList[i].relativePath_
1810 << fieldCandidateList[i].columnName_ << __E__;
1812 return fieldCandidateList;
1820 std::set<std::string > ConfigurationTree::getUniqueValuesForField(
1821 const std::vector<std::string /*relative-path*/>& recordList,
1822 const std::string& fieldName,
1823 std::string* fieldGroupIDChildLinkIndex )
const
1828 __SS__ <<
"Can only get getCommonFields from a table node! "
1829 <<
"The node type is " << getNodeType() << __E__;
1831 ss << nodeDump() << __E__;
1835 std::set<std::string > uniqueValues;
1842 for(
unsigned int i = 0; i < recordList.size(); ++i)
1844 __COUT__ <<
"Checking " << recordList[i] << __E__;
1854 uniqueValues.emplace(node.getValueAsString(
true));
1856 if(i == 0 && fieldGroupIDChildLinkIndex)
1859 if(node.isGroupIDNode())
1861 __COUT__ <<
"GroupID field " << fieldName << __E__;
1862 *fieldGroupIDChildLinkIndex = node.getColumnInfo().getChildLinkIndex();
1865 *fieldGroupIDChildLinkIndex =
"";
1869 return uniqueValues;
1875 void ConfigurationTree::recursiveGetCommonFields(
1876 std::vector<ConfigurationTree::RecordField>& fieldCandidateList,
1877 std::vector<int>& fieldCount,
1878 const std::vector<std::string /*relative-path*/>& fieldAcceptList,
1879 const std::vector<std::string /*relative-path*/>& fieldRejectList,
1881 const std::string& relativePathBase,
1882 bool inFirstRecord)
const
1906 auto tableName = getTableName();
1907 auto uid = getUIDAsString();
1910 auto recordChildren = getChildren();
1911 for(
const auto& fieldNode : recordChildren)
1916 if(fieldNode.second.isValueNode())
1919 if(fieldNode.second.getColumnInfo().getType() ==
1920 TableViewColumnInfo::TYPE_AUTHOR ||
1921 fieldNode.second.getColumnInfo().getType() ==
1922 TableViewColumnInfo::TYPE_TIMESTAMP)
1929 found = fieldAcceptList.size() ?
false :
true;
1931 for(
const auto& fieldFilter : fieldAcceptList)
1932 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1943 for(
const auto& fieldFilter : fieldRejectList)
1944 if(StringMacros::wildCardMatch(fieldFilter, fieldNode.first))
1961 &fieldNode.second.getColumnInfo()));
1962 fieldCount.push_back(1);
1969 for(j = 0; j < fieldCandidateList.size(); ++j)
1971 if((relativePathBase + fieldNode.first) ==
1972 (fieldCandidateList[j].relativePath_ +
1973 fieldCandidateList[j].columnName_))
1984 else if(depth > 0 && fieldNode.second.isUIDLinkNode() &&
1985 !fieldNode.second.isDisconnected())
1989 fieldNode.second.recursiveGetCommonFields(
1995 (relativePathBase + fieldNode.first) +
"/",
2008 std::vector<std::vector<std::pair<std::string, ConfigurationTree>>>
2009 ConfigurationTree::getChildrenByPriority(
2010 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
2011 bool onlyStatusTrue)
const
2013 std::vector<std::vector<std::pair<std::string, ConfigurationTree>>> retVector;
2017 bool filtering = filterMap.size();
2019 std::string fieldValue;
2021 bool createContainer;
2023 std::vector<std::vector<std::string>> childrenNamesByPriority =
2024 getChildrenNamesByPriority(onlyStatusTrue);
2026 for(
auto& childNamesAtPriority : childrenNamesByPriority)
2028 createContainer =
true;
2030 for(
auto& childName : childNamesAtPriority)
2040 for(
const auto& filterPair : filterMap)
2042 std::string filterPath = childName +
"/" + filterPair.first;
2043 __COUTV__(filterPath);
2047 std::vector<std::string> fieldValues;
2048 StringMacros::getVectorFromString(
2051 std::set<char>({
','}) );
2053 __COUTV__(fieldValues.size());
2057 for(
const auto& fieldValue : fieldValues)
2068 __COUT__ <<
"\t\tCheck: " << filterPair.first
2069 <<
" == " << fieldValue <<
" => "
2070 << StringMacros::decodeURIComponent(fieldValue)
2072 << this->getNode(filterPath).getValueAsString(
true)
2075 if(StringMacros::wildCardMatch(
2076 StringMacros::decodeURIComponent(fieldValue),
2077 this->getNode(filterPath).getValueAsString(
true)))
2087 __SS__ <<
"Failed to access filter path '" << filterPath
2088 <<
"' - aborting." << __E__;
2090 ss << nodeDump() << __E__;
2107 retVector.push_back(
2108 std::vector<std::pair<std::string, ConfigurationTree>>());
2109 createContainer =
false;
2112 retVector[retVector.size() - 1].push_back(
2113 std::pair<std::string, ConfigurationTree>(
2114 childName, this->getNode(childName,
true)));
2128 std::vector<std::pair<std::string, ConfigurationTree>> ConfigurationTree::getChildren(
2129 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
2131 bool onlyStatusTrue)
const
2133 std::vector<std::pair<std::string, ConfigurationTree>> retVector;
2137 bool filtering = filterMap.size();
2139 std::string fieldValue;
2141 std::vector<std::string> childrenNames = getChildrenNames(byPriority, onlyStatusTrue);
2142 for(
auto& childName : childrenNames)
2152 for(
const auto& filterPair : filterMap)
2154 std::string filterPath = childName +
"/" + filterPair.first;
2155 __COUTV__(filterPath);
2159 std::vector<std::string> fieldValues;
2160 StringMacros::getVectorFromString(
2163 std::set<char>({
','}) );
2165 __COUTV__(fieldValues.size());
2169 for(
const auto& fieldValue : fieldValues)
2180 <<
"\t\tCheck: " << filterPair.first <<
" == " << fieldValue
2181 <<
" => " << StringMacros::decodeURIComponent(fieldValue)
2182 <<
" ??? " << this->getNode(filterPath).getValueAsString(
true)
2185 if(StringMacros::wildCardMatch(
2186 StringMacros::decodeURIComponent(fieldValue),
2187 this->getNode(filterPath).getValueAsString(
true)))
2197 __SS__ <<
"Failed to access filter path '" << filterPath
2198 <<
"' - aborting." << __E__;
2200 ss << nodeDump() << __E__;
2215 retVector.push_back(std::pair<std::string, ConfigurationTree>(
2216 childName, this->getNode(childName,
true)));
2226 std::map<std::string, ConfigurationTree> ConfigurationTree::getChildrenMap(
void)
const
2228 std::map<std::string, ConfigurationTree> retMap;
2232 std::vector<std::string> childrenNames = getChildrenNames();
2233 for(
auto& childName : childrenNames)
2236 retMap.insert(std::pair<std::string, ConfigurationTree>(
2237 childName, this->getNode(childName)));
2245 inline bool ConfigurationTree::isRootNode(
void)
const {
return (!table_); }
2248 inline bool ConfigurationTree::isTableNode(
void)
const
2250 return (table_ && row_ == TableView::INVALID && col_ == TableView::INVALID);
2255 bool ConfigurationTree::isEnabled(
void)
const
2259 __SS__ <<
"Can only check the status of a UID/Record node!" << __E__;
2264 tableView_->getValue(tmpStatus, row_, tableView_->getColStatus());
2269 inline bool ConfigurationTree::status(
void)
const {
return isEnabled(); }
2274 std::vector<std::vector<std::string>> ConfigurationTree::getChildrenNamesByPriority(
2275 bool onlyStatusTrue)
const
2277 std::vector<std::vector<std::string >> retVector;
2281 __SS__ <<
"Can not get children names of '" << getValueAsString()
2282 <<
"' with null configuration view pointer!" << __E__;
2283 if(isLinkNode() && isDisconnected())
2284 ss <<
" This node is a disconnected link to " << getDisconnectedTableName()
2287 ss << nodeDump() << __E__;
2291 if(row_ == TableView::INVALID && col_ == TableView::INVALID)
2302 std::map<uint64_t , std::vector<
unsigned int >>
2304 std::vector<std::string > retPrioritySet;
2306 unsigned int col = tableView_->getColPriority();
2308 uint64_t tmpPriority;
2310 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2311 if(groupId_ ==
"" ||
2312 tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2317 tableView_->getValue(
2318 tmpStatus, r, tableView_->getColStatus());
2323 tableView_->getValue(tmpPriority, r, col);
2325 orderedByPriority[tmpPriority ? tmpPriority : 100].push_back(r);
2331 for(
const auto& priorityChildRowVector : orderedByPriority)
2333 retVector.push_back(std::vector<std::string /*child name*/>());
2334 for(
const auto& priorityChildRow : priorityChildRowVector.second)
2335 retVector[retVector.size() - 1].push_back(
2336 tableView_->getDataView()[priorityChildRow]
2337 [tableView_->getColUID()]);
2340 __COUT__ <<
"Returning priority children list." << __E__;
2343 catch(std::runtime_error& e)
2345 __COUT_WARN__ <<
"Error identifying priority. Assuming all children have "
2346 "equal priority (Error: "
2347 << e.what() << __E__;
2353 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2354 if(groupId_ ==
"" || tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2359 tableView_->getValue(tmpStatus, r, tableView_->getColStatus());
2364 retVector.push_back(std::vector<std::string /*child name*/>());
2365 retVector[retVector.size() - 1].push_back(
2366 tableView_->getDataView()[r][tableView_->getColUID()]);
2369 else if(row_ == TableView::INVALID)
2371 __SS__ <<
"Malformed ConfigurationTree" << __E__;
2373 ss << nodeDump() << __E__;
2376 else if(col_ == TableView::INVALID)
2381 for(
unsigned int c = 0; c < tableView_->getNumberOfColumns(); ++c)
2382 if(c == tableView_->getColUID() ||
2384 tableView_->getColumnInfo(c).isChildLinkGroupID() ||
2385 tableView_->getColumnInfo(c).isChildLinkUID())
2389 retVector.push_back(std::vector<std::string /*child name*/>());
2390 retVector[retVector.size() - 1].push_back(
2391 tableView_->getColumnInfo(c).getName());
2397 __SS__ <<
"\n\nError occurred looking for children of nodeName=" << getValueName()
2399 <<
"Invalid depth! getChildrenValues() called from a value point in the "
2400 "Configuration Tree."
2403 ss << nodeDump() << __E__;
2413 std::vector<std::string> ConfigurationTree::getChildrenNames(
bool byPriority,
2414 bool onlyStatusTrue)
const
2416 std::vector<std::string > retVector;
2420 __SS__ <<
"Can not get children names of '" << getValueAsString()
2421 <<
"' with null configuration view pointer!" << __E__;
2422 if(isLinkNode() && isDisconnected())
2423 ss <<
" This node is a disconnected link to " << getDisconnectedTableName()
2428 if(row_ == TableView::INVALID && col_ == TableView::INVALID)
2439 std::map<uint64_t , std::vector<
unsigned int >>
2441 std::vector<std::string > retPrioritySet;
2443 unsigned int col = tableView_->getColPriority();
2445 uint64_t tmpPriority;
2447 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2448 if(groupId_ ==
"" ||
2449 tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2454 tableView_->getValue(
2455 tmpStatus, r, tableView_->getColStatus());
2461 tableView_->getValue(tmpPriority, r, col);
2463 orderedByPriority[tmpPriority ? tmpPriority : 100].push_back(r);
2469 for(
const auto& priorityChildRowVector : orderedByPriority)
2470 for(
const auto& priorityChildRow : priorityChildRowVector.second)
2471 retVector.push_back(
2472 tableView_->getDataView()[priorityChildRow]
2473 [tableView_->getColUID()]);
2475 __COUT__ <<
"Returning priority children list." << __E__;
2478 catch(std::runtime_error& e)
2480 __COUT_WARN__ <<
"Priority configuration not found. Assuming all "
2481 "children have equal priority. "
2488 for(
unsigned int r = 0; r < tableView_->getNumberOfRows(); ++r)
2489 if(groupId_ ==
"" || tableView_->isEntryInGroup(r, childLinkIndex_, groupId_))
2494 tableView_->getValue(tmpStatus, r, tableView_->getColStatus());
2500 retVector.push_back(
2501 tableView_->getDataView()[r][tableView_->getColUID()]);
2504 else if(row_ == TableView::INVALID)
2506 __SS__ <<
"Malformed ConfigurationTree" << __E__;
2508 ss << nodeDump() << __E__;
2511 else if(col_ == TableView::INVALID)
2516 for(
unsigned int c = 0; c < tableView_->getNumberOfColumns(); ++c)
2517 if(c == tableView_->getColUID() ||
2519 tableView_->getColumnInfo(c).isChildLinkGroupID() ||
2520 tableView_->getColumnInfo(c).isChildLinkUID())
2523 retVector.push_back(tableView_->getColumnInfo(c).getName());
2528 __SS__ <<
"\n\nError occurred looking for children of nodeName=" << getValueName()
2530 <<
"Invalid depth! getChildrenValues() called from a value point in the "
2531 "Configuration Tree."
2534 ss << nodeDump() << __E__;
2552 __SS__ <<
"Invalid node for get value." << __E__;
2556 std::string valueString =
2557 tableView_->getValueAsString(row_, col_,
true );
2559 if(valueString.size() && valueString[0] ==
'/')
2566 __COUT__ <<
"Found a valid tree path in value!" << __E__;
2571 __SS__ <<
"Invalid tree path." << __E__;
2577 __SS__ <<
"Invalid value string '" << valueString
2578 <<
"' - must start with a '/' character." << __E__;