1 #include "otsdaq-core/ConfigurationInterface/ConfigurationTree.h"
2 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationBase.h"
4 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
13 #define __MF_SUBJECT__ "ConfigurationTree"
15 const std::string ConfigurationTree::DISCONNECTED_VALUE =
"X";
16 const std::string ConfigurationTree::VALUE_TYPE_DISCONNECTED =
"Disconnected";
17 const std::string ConfigurationTree::VALUE_TYPE_NODE =
"Node";
20 ConfigurationTree::ConfigurationTree()
24 linkParentConfig_ (0),
29 disconnectedTargetName_ (
""),
30 disconnectedLinkID_ (
""),
54 ConfigurationTree::ConfigurationTree(
57 const std::string& groupId,
59 const std::string& linkColName,
60 const std::string& linkColValue,
61 const unsigned int linkBackRow,
62 const unsigned int linkBackCol,
63 const std::string& disconnectedTargetName,
64 const std::string& disconnectedLinkID,
65 const std::string& childLinkIndex,
66 const unsigned int row,
67 const unsigned int col)
68 : configMgr_ (configMgr),
69 configuration_ (config),
71 linkParentConfig_ (linkParentConfig),
72 linkColName_ (linkColName),
73 linkColValue_ (linkColValue),
74 linkBackRow_ (linkBackRow),
75 linkBackCol_ (linkBackCol),
76 disconnectedTargetName_ (disconnectedTargetName),
77 disconnectedLinkID_ (disconnectedLinkID),
78 childLinkIndex_ (childLinkIndex),
88 ss << __COUT_HDR_FL__ <<
"Invalid empty pointer given to tree!\n" <<
89 "\n\tconfigMgr_=" << configMgr_ <<
90 "\n\tconfiguration_=" << configuration_ <<
91 "\n\tconfigView_=" << configView_ <<
93 __COUT__ <<
"\n" << ss.str();
94 throw std::runtime_error(ss.str());
98 configView_ = &(configuration_->getView());
102 configView_->getColumnInfo(configView_->getColUID()).getType() != ViewColumnInfo::TYPE_UID)
104 __SS__ <<
"Missing UID column (must column of type " << ViewColumnInfo::TYPE_UID <<
105 ") in config view : " << configView_->getTableName() << std::endl;
106 __COUT__ <<
"\n" << ss.str();
107 throw std::runtime_error(ss.str());
113 ConfigurationTree::~ConfigurationTree(
void)
124 void ConfigurationTree::print(
const unsigned int &depth, std::ostream &out)
const
126 recursivePrint(*
this,depth,out,
"\t");
130 void ConfigurationTree::recursivePrint(
const ConfigurationTree &t,
unsigned int depth, std::ostream &out, std::string space)
133 out << space << t.getValueName() <<
" :\t" << t.getValueAsString() << std::endl;
138 out << space << t.getValueName();
139 if(t.isDisconnected())
141 out <<
" :\t" << t.getValueAsString() << std::endl;
145 (t.isGroupLinkNode()?
"Group":
"U") <<
146 "ID=" << t.getValueAsString() <<
150 out << space << t.getValueAsString() <<
" : " << std::endl;
156 auto C = t.getChildren();
158 out << space <<
"{" << std::endl;
160 recursivePrint(c.second,depth-1,out,space +
" ");
162 out << space <<
"}" << std::endl;
172 void ConfigurationTree::getValue(std::string& value)
const
176 if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
183 __COUT__ <<
"Success following path to tree node!" << std::endl;
190 value = configView_->validateValueForColumn(
191 valueAsTreeNode.getValueAsString(),col_);
194 __COUT__ <<
"Successful value!" << std::endl;
208 configView_->getValue(value,row_,col_);
210 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
212 if(isLinkNode() && isDisconnected())
213 value = (groupId_ ==
"") ? getValueName():groupId_;
215 value = (groupId_ ==
"") ? configuration_->getConfigurationName():groupId_;
217 else if(row_ == ConfigurationView::INVALID)
219 __SS__ <<
"Malformed ConfigurationTree" << std::endl;
220 __COUT_ERR__ << ss.str();
221 throw std::runtime_error(ss.str());
223 else if(col_ == ConfigurationView::INVALID)
224 configView_->getValue(value,row_,configView_->getColUID());
227 __SS__ <<
"Impossible." << std::endl;
228 __COUT_ERR__ << ss.str();
229 throw std::runtime_error(ss.str());
246 std::string ConfigurationTree::getValue()
const
249 ConfigurationTree::getValue(value);
256 std::string ConfigurationTree::getEscapedValue()
const
258 if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
259 return configView_->getEscapedValueAsString(row_,col_);
261 __SS__ <<
"Can't get escaped value except from a value node!" <<
262 " This node is type '" << getNodeType() <<
"." << std::endl;
263 __COUT_ERR__ <<
"\n" << ss.str();
264 throw std::runtime_error(ss.str());
269 const std::string& ConfigurationTree::getConfigurationName(
void)
const
273 __SS__ <<
"Can't get configuration name of node with no configuration pointer!" << std::endl;
274 throw std::runtime_error(ss.str());
276 return configuration_->getConfigurationName();
283 const std::string& ConfigurationTree::getFieldConfigurationName(
void)
const
288 if(!linkParentConfig_)
290 __SS__ <<
"Can't get configuration name of link node field with no parent configuration pointer!" << std::endl;
291 throw std::runtime_error(ss.str());
293 return linkParentConfig_->getConfigurationName();
296 return getConfigurationName();
301 const std::string& ConfigurationTree::getDisconnectedTableName(
void)
const
303 if(isLinkNode() && isDisconnected())
return disconnectedTargetName_;
305 __SS__ <<
"Can't get disconnected target name of node unless it is a disconnected link node!" << std::endl;
306 throw std::runtime_error(ss.str());
311 const std::string& ConfigurationTree::getDisconnectedLinkID(
void)
const
313 if(isLinkNode() && isDisconnected())
return disconnectedLinkID_;
315 __SS__ <<
"Can't get disconnected target name of node unless it is a disconnected link node!" << std::endl;
316 throw std::runtime_error(ss.str());
325 __SS__ <<
"Can't get configuration version of node with no config view pointer!" << std::endl;
326 throw std::runtime_error(ss.str());
328 return configView_->getVersion();
333 const time_t& ConfigurationTree::getConfigurationCreationTime(
void)
const
337 __SS__ <<
"Can't get configuration creation time of node with no config view pointer!" << std::endl;
338 throw std::runtime_error(ss.str());
340 return configView_->getCreationTime();
348 std::vector<std::string> ConfigurationTree::getFixedChoices(
void)
const
352 __SS__ <<
"Can't get fixed choices of node with no config view pointer!" << std::endl;
353 throw std::runtime_error(ss.str());
356 if(getValueType() != ViewColumnInfo::TYPE_FIXED_CHOICE_DATA &&
357 getValueType() != ViewColumnInfo::TYPE_BITMAP_DATA &&
360 __SS__ <<
"Can't get fixed choices of node with value type of '" <<
361 getValueType() <<
".' Node must be a link or a value node with type '" <<
362 ViewColumnInfo::TYPE_BITMAP_DATA <<
"' or '" <<
363 ViewColumnInfo::TYPE_FIXED_CHOICE_DATA <<
".'" << std::endl;
364 throw std::runtime_error(ss.str());
367 std::vector<std::string> retVec;
371 if(!linkParentConfig_)
373 __SS__ <<
"Can't get fixed choices of node with no parent config view pointer!" << std::endl;
374 throw std::runtime_error(ss.str());
384 int c = parentView->findCol(linkColName_);
386 std::pair<
unsigned int ,
unsigned int > linkPair;
388 parentView->getChildLink(c, isGroupLink, linkPair);
391 std::vector<std::string> choices = parentView->getColumnInfo(c).getDataChoices();
392 for(
const auto &choice:choices)
393 retVec.push_back(choice);
399 retVec.push_back(configView_->getColumnInfo(col_).getDefaultValue());
400 std::vector<std::string> choices = configView_->getColumnInfo(col_).getDataChoices();
401 for(
const auto &choice:choices)
402 retVec.push_back(choice);
415 const std::string& ConfigurationTree::getValueAsString(
bool returnLinkTableValue)
const
419 if(returnLinkTableValue)
420 return linkColValue_;
421 else if(isDisconnected())
422 return ConfigurationTree::DISCONNECTED_VALUE;
423 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
424 return (groupId_ ==
"")?configuration_->getConfigurationName():groupId_;
425 else if(col_ == ConfigurationView::INVALID)
426 return configView_->getDataView()[row_][configView_->getColUID()];
429 __SS__ <<
"Impossible Link." << std::endl;
430 __COUT_ERR__ << ss.str();
431 throw std::runtime_error(ss.str());
434 else if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
435 return configView_->getDataView()[row_][col_];
436 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
437 return (groupId_ ==
"")?configuration_->getConfigurationName():groupId_;
438 else if(row_ == ConfigurationView::INVALID)
440 __SS__ <<
"Malformed ConfigurationTree" << std::endl;
441 __COUT_ERR__ << ss.str();
442 throw std::runtime_error(ss.str());
444 else if(col_ == ConfigurationView::INVALID)
445 return configView_->getDataView()[row_][configView_->getColUID()];
448 __SS__ <<
"Impossible." << std::endl;
449 __COUT_ERR__ << ss.str();
450 throw std::runtime_error(ss.str());
458 const std::string& ConfigurationTree::getUIDAsString(
void)
const
460 if(isValueNode() || isUIDLinkNode())
461 return configView_->getDataView()[row_][configView_->getColUID()];
464 __SS__ <<
"Can't get UID of node with type '" <<
465 getNodeType() <<
".' Node type must be '" <<
466 ConfigurationTree::NODE_TYPE_VALUE <<
"' or '" <<
467 ConfigurationTree::NODE_TYPE_UID_LINK <<
".'" << std::endl;
468 throw std::runtime_error(ss.str());
475 const std::string& ConfigurationTree::getValueDataType(
void)
const
478 return configView_->getColumnInfo(col_).getDataType();
480 return ViewColumnInfo::DATATYPE_STRING;
486 bool ConfigurationTree::isDefaultValue(
void)
const
488 if(!isValueNode())
return false;
490 if(getValueDataType() == ViewColumnInfo::DATATYPE_STRING)
492 if(getValueType() == ViewColumnInfo::TYPE_ON_OFF ||
493 getValueType() == ViewColumnInfo::TYPE_TRUE_FALSE ||
494 getValueType() == ViewColumnInfo::TYPE_YES_NO)
495 return getValueAsString() == ViewColumnInfo::DATATYPE_BOOL_DEFAULT;
496 else if(getValueType() == ViewColumnInfo::TYPE_COMMENT)
497 return getValueAsString() == ViewColumnInfo::DATATYPE_COMMENT_DEFAULT ||
498 getValueAsString() ==
"";
500 return getValueAsString() == ViewColumnInfo::DATATYPE_STRING_DEFAULT;
502 else if(getValueDataType() == ViewColumnInfo::DATATYPE_NUMBER)
503 return getValueAsString() == ViewColumnInfo::DATATYPE_NUMBER_DEFAULT;
504 else if(getValueDataType() == ViewColumnInfo::DATATYPE_TIME)
505 return getValueAsString() == ViewColumnInfo::DATATYPE_TIME_DEFAULT;
513 const std::string& ConfigurationTree::getValueType(
void)
const
516 return configView_->getColumnInfo(col_).getType();
517 else if(isLinkNode() && isDisconnected())
518 return ConfigurationTree::VALUE_TYPE_DISCONNECTED;
520 return ConfigurationTree::VALUE_TYPE_NODE;
526 const ViewColumnInfo& ConfigurationTree::getColumnInfo(
void)
const
529 return configView_->getColumnInfo(col_);
532 __SS__ <<
"Can only get column info from a value node! " <<
533 "The node type is " << getNodeType() << std::endl;
534 __COUT__ <<
"\n" << ss.str() << std::endl;
535 throw std::runtime_error(ss.str());
542 const unsigned int& ConfigurationTree::getRow(
void)
const
549 const unsigned int& ConfigurationTree::getColumn(
void)
const
557 const unsigned int& ConfigurationTree::getFieldRow(
void)
const
571 const unsigned int& ConfigurationTree::getFieldColumn(
void)
const
584 const std::string& ConfigurationTree::getChildLinkIndex(
void)
const
588 __SS__ <<
"Can only get link ID from a link! " <<
589 "The node type is " << getNodeType() << std::endl;
590 __COUT__ <<
"\n" << ss.str() << std::endl;
591 throw std::runtime_error(ss.str());
593 return childLinkIndex_;
599 const std::string& ConfigurationTree::getValueName(
void)
const
602 return configView_->getColumnInfo(col_).getName();
603 else if(isLinkNode())
607 __SS__ <<
"Can only get value name of a value node!" << std::endl;
608 __COUT__ <<
"\n" << ss.str() << std::endl;
609 throw std::runtime_error(ss.str());
618 const std::string& childPath,
bool doNotThrowOnBrokenUIDLinks)
622 if(childPath.length() <= 1)
624 return tree.getNode(childPath,doNotThrowOnBrokenUIDLinks);
661 bool doNotThrowOnBrokenUIDLinks)
const
667 if(nodeString.length() < 1)
669 __SS__ <<
"Invalid empty node name! Looking for child node from node '" <<
670 getValue() <<
"'..." << std::endl;
671 __COUT_ERR__ << ss.str();
672 throw std::runtime_error(ss.str());
675 bool startingSlash = nodeString[0] ==
'/';
677 std::string nodeName = nodeString.substr(startingSlash?1:0, nodeString.find(
'/',1)-(startingSlash?1:0));
680 std::string childPath = nodeString.substr(nodeName.length() + (startingSlash?1:0));
689 if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
693 __SS__ <<
"Missing configView pointer! Likely attempting to access a child node through a disconnected link node." << std::endl;
694 __COUT_ERR__ <<
"\n" << ss.str();
695 throw std::runtime_error(ss.str());
706 ConfigurationView::INVALID , ConfigurationView::INVALID ,
712 configView_->findRow(configView_->getColUID(),nodeName)
713 : configView_->findRowInGroup(configView_->getColUID(),
714 nodeName,groupId_,childLinkIndex_) ),
715 childPath, doNotThrowOnBrokenUIDLinks);
717 else if(row_ == ConfigurationView::INVALID)
719 __SS__ <<
"Malformed ConfigurationTree" << std::endl;
720 __COUT_ERR__ <<
"\n" << ss.str();
721 throw std::runtime_error(ss.str());
723 else if(col_ == ConfigurationView::INVALID)
737 __SS__ <<
"Missing configView pointer! Likely attempting to access a child node through a disconnected link node." << std::endl;
738 __COUT_ERR__ <<
"\n" << ss.str();
739 throw std::runtime_error(ss.str());
742 unsigned int c = configView_->findCol(nodeName);
743 std::pair<
unsigned int ,
unsigned int > linkPair;
744 bool isGroupLink, isLink;
745 if((isLink = configView_->getChildLink(c, isGroupLink, linkPair)) &&
756 childConfig = configMgr_->getConfigurationByName(configView_->getDataView()[row_][linkPair.first]);
757 childConfig->getView();
759 if(doNotThrowOnBrokenUIDLinks)
761 childConfig->getView().findRow(childConfig->getView().getColUID(),
762 configView_->getDataView()[row_][linkPair.second]);
779 configView_->getDataView()[row_][c],
781 configView_->getDataView()[row_][linkPair.first],
782 configView_->getDataView()[row_][linkPair.second],
783 configView_->getColumnInfo(c).getChildLinkIndex());
793 configView_->getDataView()[row_][c],
797 configView_->getColumnInfo(c).getChildLinkIndex(),
798 childConfig->getView().findRow(childConfig->getView().getColUID(),
799 configView_->getDataView()[row_][linkPair.second])
801 childPath, doNotThrowOnBrokenUIDLinks);
813 childConfig = configMgr_->getConfigurationByName(
814 configView_->getDataView()[row_][linkPair.first]);
815 childConfig->getView();
819 if(configView_->getDataView()[row_][linkPair.first] !=
820 ViewColumnInfo::DATATYPE_LINK_DEFAULT)
821 __COUT_WARN__ <<
"Found disconnected node! Failed link target from nodeName=" <<
822 nodeName <<
" to table:id=" <<
823 configView_->getDataView()[row_][linkPair.first] <<
":" <<
824 configView_->getDataView()[row_][linkPair.second] <<
829 configView_->getDataView()[row_][linkPair.second],
832 configView_->getDataView()[row_][c],
834 configView_->getDataView()[row_][linkPair.first],
835 configView_->getDataView()[row_][linkPair.second],
836 configView_->getColumnInfo(c).getChildLinkIndex()
844 configView_->getDataView()[row_][linkPair.second],
847 configView_->getDataView()[row_][c],
851 configView_->getColumnInfo(c).getChildLinkIndex()
853 childPath, doNotThrowOnBrokenUIDLinks);
864 ConfigurationView::INVALID , ConfigurationView::INVALID ,
871 catch(std::runtime_error &e)
873 __SS__ <<
"\n\nError occurred descending from node '" << getValue() <<
874 "' in table '" << getConfigurationName() <<
875 "' looking for child '" << nodeName <<
"'\n\n" << std::endl;
876 ss <<
"--- Additional error detail: \n\n" << e.what() << std::endl;
877 throw std::runtime_error(ss.str());
881 __SS__ <<
"\n\nError occurred descending from node '" << getValue() <<
882 "' in table '" << getConfigurationName() <<
883 "' looking for child '" << nodeName <<
"'\n\n" << std::endl;
884 throw std::runtime_error(ss.str());
888 __SS__ <<
"\n\nError occurred descending from node '" << getValue() <<
889 "' in table '" << getConfigurationName() <<
890 "' looking for child '" << nodeName <<
"'\n\n" <<
891 "Invalid depth! getNode() called from a value point in the Configuration Tree." << std::endl;
892 throw std::runtime_error(ss.str());
897 ConfigurationTree ConfigurationTree::getBackNode(std::string nodeName,
unsigned int backSteps)
const
899 for(
unsigned int i=0; i<backSteps; i++)
900 nodeName = nodeName.substr(0, nodeName.find_last_of(
'/'));
902 return getNode(nodeName);
908 bool ConfigurationTree::isValueNode(
void)
const
910 return (row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID);
918 bool ConfigurationTree::isDisconnected(
void)
const
922 __SS__ <<
"\n\nError occurred testing link connection at node with value '" <<
924 "' in table '" << getConfigurationName() <<
925 "'\n\n" << std::endl;
926 ss <<
"This is not a Link node! It is node type '" <<
927 getNodeType() <<
".' Only a Link node can be disconnected." << std::endl;
929 throw std::runtime_error(ss.str());
932 return !configuration_ || !configView_;
938 bool ConfigurationTree::isLinkNode(
void)
const
940 return linkColName_ !=
"";
946 const std::string ConfigurationTree::NODE_TYPE_GROUP_TABLE =
"GroupConfigurationNode";
947 const std::string ConfigurationTree::NODE_TYPE_TABLE =
"ConfigurationNode";
948 const std::string ConfigurationTree::NODE_TYPE_GROUP_LINK =
"GroupLinkNode";
949 const std::string ConfigurationTree::NODE_TYPE_UID_LINK =
"UIDLinkNode";
950 const std::string ConfigurationTree::NODE_TYPE_VALUE =
"ValueNode";
951 const std::string ConfigurationTree::NODE_TYPE_UID =
"UIDNode";
952 std::string ConfigurationTree::getNodeType(
void)
const
954 if(isConfigurationNode() && groupId_ !=
"")
return ConfigurationTree::NODE_TYPE_GROUP_TABLE;
955 if(isConfigurationNode())
return ConfigurationTree::NODE_TYPE_TABLE;
956 if(isGroupLinkNode())
return ConfigurationTree::NODE_TYPE_GROUP_LINK;
957 if(isLinkNode())
return ConfigurationTree::NODE_TYPE_UID_LINK;
958 if(isValueNode())
return ConfigurationTree::NODE_TYPE_VALUE;
959 return ConfigurationTree::NODE_TYPE_UID;
965 bool ConfigurationTree::isGroupLinkNode(
void)
const
967 return (isLinkNode() && groupId_ !=
"");
973 bool ConfigurationTree::isUIDLinkNode(
void)
const
975 return (isLinkNode() && groupId_ ==
"");
981 bool ConfigurationTree::isUIDNode(
void)
const
983 return (row_ != ConfigurationView::INVALID && col_ == ConfigurationView::INVALID);
1003 std::vector<ConfigurationTree::RecordField> ConfigurationTree::getCommonFields(
1004 const std::vector<std::string /*uid*/> &recordList,
1005 const std::vector<std::string /*relative-path*/> &fieldAcceptList,
1006 const std::vector<std::string /*relative-path*/> &fieldRejectList,
1007 unsigned int depth)
const
1010 if(!isConfigurationNode())
1012 __SS__ <<
"Can only get getCommonFields from a table node! " <<
1013 "The node type is " << getNodeType() << std::endl;
1014 __COUT__ <<
"\n" << ss.str() << std::endl;
1015 throw std::runtime_error(ss.str());
1018 std::vector<ConfigurationTree::RecordField> fieldCandidateList;
1019 std::vector<int> fieldCount;
1057 auto tableName = getConfigurationName();
1059 for(
unsigned int i=0;i<recordList.size();++i)
1063 auto recordChildren = getNode(recordList[i]).getChildren();
1064 for(
const auto &fieldNode : recordChildren)
1068 if(fieldNode.second.isValueNode())
1071 if(fieldNode.second.getColumnInfo().getType() ==
1072 ViewColumnInfo::TYPE_AUTHOR ||
1073 fieldNode.second.getColumnInfo().getType() ==
1074 ViewColumnInfo::TYPE_TIMESTAMP)
1081 found = fieldAcceptList.size()?
false:
true;
1082 for(
const auto &fieldFilter : fieldAcceptList)
1083 if(ConfigurationTree::wildCardMatch(
1084 fieldFilter,fieldNode.first))
1123 for(
const auto &fieldFilter : fieldRejectList)
1124 if(ConfigurationTree::wildCardMatch(
1125 fieldFilter,fieldNode.first))
1164 fieldCandidateList.push_back(
1170 &fieldNode.second.getColumnInfo()
1172 fieldCount.push_back(-1);
1178 else if(depth > 0 &&
1179 fieldNode.second.isUIDLinkNode() &&
1180 !fieldNode.second.isDisconnected())
1183 fieldNode.second.recursiveGetCommonFields(
1189 fieldNode.first +
"/",
1202 for(
unsigned int i=0;i<fieldCandidateList.size();++i)
1207 if(fieldCount[i] != -1 &&
1208 fieldCount[i] != (
int)recordList.size())
1213 fieldCount.erase(fieldCount.begin() + i);
1214 fieldCandidateList.erase(fieldCandidateList.begin() + i);
1223 return fieldCandidateList;
1231 std::set<std::string > ConfigurationTree::getUniqueValuesForField(
1232 const std::vector<std::string /*relative-path*/> &recordList,
1233 const std::string &fieldName)
const
1236 if(!isConfigurationNode())
1238 __SS__ <<
"Can only get getCommonFields from a table node! " <<
1239 "The node type is " << getNodeType() << std::endl;
1240 __COUT__ <<
"\n" << ss.str() << std::endl;
1241 throw std::runtime_error(ss.str());
1244 std::set<std::string > uniqueValues;
1251 for(
unsigned int i=0;i<recordList.size();++i)
1253 __COUT__ <<
"Checking " << recordList[i] << std::endl;
1261 uniqueValues.emplace(getNode(recordList[i]).getNode(fieldName).getValueAsString(
true));
1264 return uniqueValues;
1270 void ConfigurationTree::recursiveGetCommonFields(
1271 std::vector<ConfigurationTree::RecordField> &fieldCandidateList,
1272 std::vector<int> &fieldCount,
1273 const std::vector<std::string /*relative-path*/> &fieldAcceptList,
1274 const std::vector<std::string /*relative-path*/> &fieldRejectList,
1276 const std::string &relativePathBase,
1303 auto tableName = getConfigurationName();
1304 auto uid = getUIDAsString();
1307 auto recordChildren = getChildren();
1308 for(
const auto &fieldNode : recordChildren)
1310 if(fieldNode.second.isValueNode())
1313 if(fieldNode.second.getColumnInfo().getType() ==
1314 ViewColumnInfo::TYPE_AUTHOR ||
1315 fieldNode.second.getColumnInfo().getType() ==
1316 ViewColumnInfo::TYPE_TIMESTAMP)
1323 found = fieldAcceptList.size()?
false:
true;
1324 for(
const auto &fieldFilter : fieldAcceptList)
1325 if(ConfigurationTree::wildCardMatch(
1326 fieldFilter,fieldNode.first))
1366 for(
const auto &fieldFilter : fieldRejectList)
1367 if(ConfigurationTree::wildCardMatch(
1368 fieldFilter,fieldNode.first))
1409 fieldCandidateList.push_back(
1415 &fieldNode.second.getColumnInfo()
1417 fieldCount.push_back(1);
1424 for(j=0;j<fieldCandidateList.size();++j)
1426 if((relativePathBase + fieldNode.first) ==
1427 (fieldCandidateList[j].relativePath_ +
1428 fieldCandidateList[j].columnName_))
1439 else if(depth > 0 &&
1440 fieldNode.second.isUIDLinkNode() &&
1441 !fieldNode.second.isDisconnected())
1444 fieldNode.second.recursiveGetCommonFields(
1450 (relativePathBase + fieldNode.first) +
"/",
1461 std::vector<std::pair<std::string,ConfigurationTree> > ConfigurationTree::getChildren(
1462 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap)
const
1464 std::vector<std::pair<std::string,ConfigurationTree> > retMap;
1468 bool filtering = filterMap.size();
1470 std::string fieldValue;
1472 std::vector<std::string> childrenNames = getChildrenNames();
1473 for(
auto &childName : childrenNames)
1483 for(
const auto &filterPair:filterMap)
1485 std::string filterPath = childName +
"/" + filterPair.first;
1490 std::istringstream f(filterPair.second);
1494 while (getline(f, fieldValue,
','))
1503 __COUT__ <<
"\t\tCheck: " << filterPair.first <<
1504 " == " << fieldValue <<
" ??? " <<
1505 this->getNode(filterPath).getValueAsString(
true) <<
1508 if(ConfigurationTree::wildCardMatch(
1509 ConfigurationView::decodeURIComponent(fieldValue),
1510 this->getNode(filterPath).getValueAsString(
true) ))
1528 __SS__ <<
"Failed to access filter path '" <<
1529 filterPath <<
"' - aborting." << std::endl;
1530 __COUT_ERR__ <<
"\n" << ss.str();
1531 throw std::runtime_error(ss.str());
1539 __COUT__ <<
"\tChild accepted: " << childName << std::endl;
1542 retMap.push_back(std::pair<std::string,ConfigurationTree>(childName,
1543 this->getNode(childName,
true)));
1554 bool ConfigurationTree::wildCardMatch(
const std::string& needle,
const std::string& haystack)
1561 if(needle.size() == 0)
1564 if(needle[0] ==
'*' &&
1565 needle[needle.size()-1] ==
'*' )
1566 return std::string::npos != haystack.find(needle.substr(1,needle.size()-2));
1568 if(needle[0] ==
'*')
1569 return needle.substr(1) ==
1570 haystack.substr(haystack.size() - (needle.size()-1));
1572 if(needle[needle.size()-1] ==
'*')
1573 return needle.substr(0,needle.size()-1) ==
1574 haystack.substr(0,needle.size()-1);
1577 return needle == haystack;
1588 std::map<std::string,ConfigurationTree> ConfigurationTree::getChildrenMap(
void)
const
1590 std::map<std::string,ConfigurationTree> retMap;
1594 std::vector<std::string> childrenNames = getChildrenNames();
1595 for(
auto& childName : childrenNames)
1598 retMap.insert(std::pair<std::string,ConfigurationTree>(childName, this->getNode(childName)));
1606 bool ConfigurationTree::isConfigurationNode(
void)
const
1608 return (row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID);
1614 std::vector<std::string> ConfigurationTree::getChildrenNames(
void)
const
1616 std::vector<std::string> retSet;
1620 __SS__ <<
"Can not get children names of '" <<
1621 getValueAsString() <<
1622 "' with null configuration view pointer!" << std::endl;
1623 if(isLinkNode() && isDisconnected())
1624 ss <<
" This node is a disconnected link to " <<
1625 getDisconnectedTableName() << std::endl;
1626 __COUT_ERR__ <<
"\n" << ss.str();
1627 throw std::runtime_error(ss.str());
1630 if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
1635 for(
unsigned int r = 0; r<configView_->getNumberOfRows(); ++r)
1636 if(groupId_ ==
"" ||
1637 configView_->isEntryInGroup(r,childLinkIndex_,groupId_))
1640 retSet.push_back(configView_->getDataView()[r][configView_->getColUID()]);
1642 else if(row_ == ConfigurationView::INVALID)
1644 __SS__ <<
"Malformed ConfigurationTree" << std::endl;
1645 __COUT_ERR__ << ss.str();
1646 throw std::runtime_error(ss.str());
1648 else if(col_ == ConfigurationView::INVALID)
1653 for(
unsigned int c = 0; c<configView_->getNumberOfColumns(); ++c)
1654 if(c == configView_->getColUID() ||
1655 configView_->getColumnInfo(c).isChildLinkGroupID() ||
1656 configView_->getColumnInfo(c).isChildLinkUID())
1659 retSet.push_back(configView_->getColumnInfo(c).getName());
1664 __SS__ <<
"\n\nError occurred looking for children of nodeName=" << getValueName() <<
"\n\n" <<
1665 "Invalid depth! getChildrenValues() called from a value point in the Configuration Tree." << std::endl;
1666 __COUT_ERR__ << ss.str();
1667 throw std::runtime_error(ss.str());
1685 __SS__ <<
"Invalid node for get value." << std::endl;
1686 __COUT__ << ss.str();
1687 throw std::runtime_error(ss.str());
1690 std::string valueString = configView_->getValueAsString(row_,col_,
true );
1692 if(valueString.size() && valueString[0] ==
'/')
1698 __COUT__ <<
"Found a valid tree path in value!" << std::endl;
1703 __SS__ <<
"Invalid tree path." << std::endl;
1705 throw std::runtime_error(ss.str());
1711 __SS__ <<
"Invalid value string '" << valueString <<
1712 "' - must start with a '/' character." << std::endl;
1713 throw std::runtime_error(ss.str());