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),
27 disconnectedTargetName_ (
""),
28 disconnectedLinkID_ (
""),
49 ConfigurationTree::ConfigurationTree(
52 const std::string& groupId,
54 const std::string& linkColName,
55 const std::string& linkColValue,
56 const std::string& disconnectedTargetName,
57 const std::string& disconnectedLinkID,
58 const std::string& childLinkIndex,
59 const unsigned int row,
60 const unsigned int col)
61 : configMgr_ (configMgr),
62 configuration_ (config),
64 linkParentConfig_ (linkParentConfig),
65 linkColName_ (linkColName),
66 linkColValue_ (linkColValue),
67 disconnectedTargetName_ (disconnectedTargetName),
68 disconnectedLinkID_ (disconnectedLinkID),
69 childLinkIndex_ (childLinkIndex),
79 ss << __COUT_HDR_FL__ <<
"Invalid empty pointer given to tree!\n" <<
80 "\n\tconfigMgr_=" << configMgr_ <<
81 "\n\tconfiguration_=" << configuration_ <<
82 "\n\tconfigView_=" << configView_ <<
84 __MOUT__ <<
"\n" << ss.str();
85 throw std::runtime_error(ss.str());
89 configView_ = &(configuration_->getView());
93 configView_->getColumnInfo(configView_->getColUID()).getType() != ViewColumnInfo::TYPE_UID)
95 __SS__ <<
"Missing UID column (must column of type " << ViewColumnInfo::TYPE_UID <<
96 ") in config view : " << configView_->getTableName() << std::endl;
97 __MOUT__ <<
"\n" << ss.str();
98 throw std::runtime_error(ss.str());
104 ConfigurationTree::~ConfigurationTree(
void)
115 void ConfigurationTree::print(
const unsigned int &depth, std::ostream &out)
const
117 recursivePrint(*
this,depth,out,
"\t");
121 void ConfigurationTree::recursivePrint(
const ConfigurationTree &t,
unsigned int depth, std::ostream &out, std::string space)
124 out << space << t.getValueName() <<
" :\t" << t.getValueAsString() << std::endl;
129 out << space << t.getValueName();
130 if(t.isDisconnected())
132 out <<
" :\t" << t.getValueAsString() << std::endl;
136 (t.isGroupLinkNode()?
"Group":
"U") <<
137 "ID=" << t.getValueAsString() <<
141 out << space << t.getValueAsString() <<
" : " << std::endl;
147 auto C = t.getChildren();
149 out << space <<
"{" << std::endl;
151 recursivePrint(c.second,depth-1,out,space +
" ");
153 out << space <<
"}" << std::endl;
163 void ConfigurationTree::getValue(std::string& value)
const
167 if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
174 __MOUT__ <<
"Success following path to tree node!" << std::endl;
181 value = configView_->validateValueForColumn(
182 valueAsTreeNode.getValueAsString(),col_);
185 __MOUT__ <<
"Successful value!" << std::endl;
199 configView_->getValue(value,row_,col_);
201 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
203 if(isLinkNode() && isDisconnected())
204 value = (groupId_ ==
"") ? getValueName():groupId_;
206 value = (groupId_ ==
"") ? configuration_->getConfigurationName():groupId_;
208 else if(row_ == ConfigurationView::INVALID)
210 __MOUT__ << std::endl;
211 throw std::runtime_error(
"Malformed ConfigurationTree");
213 else if(col_ == ConfigurationView::INVALID)
214 configView_->getValue(value,row_,configView_->getColUID());
217 __MOUT__ << std::endl;
218 throw std::runtime_error(
"Impossible.");
235 std::string ConfigurationTree::getValue()
const
238 ConfigurationTree::getValue(value);
272 std::string ConfigurationTree::getEscapedValue()
const
274 if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
275 return configView_->getEscapedValueAsString(row_,col_);
277 __SS__ <<
"Can't get escaped value except from a value node!" <<
278 " This node is type '" << getNodeType() <<
"." << std::endl;
279 __MOUT_ERR__ <<
"\n" << ss.str();
280 throw std::runtime_error(ss.str());
285 const std::string& ConfigurationTree::getConfigurationName(
void)
const
289 __SS__ <<
"Can't get configuration name of node with no configuration pointer!" << std::endl;
290 throw std::runtime_error(ss.str());
292 return configuration_->getConfigurationName();
297 const std::string& ConfigurationTree::getDisconnectedTableName(
void)
const
299 if(isLinkNode() && isDisconnected())
return disconnectedTargetName_;
301 __SS__ <<
"Can't get disconnected target name of node unless it is a disconnected link node!" << std::endl;
302 throw std::runtime_error(ss.str());
307 const std::string& ConfigurationTree::getDisconnectedLinkID(
void)
const
309 if(isLinkNode() && isDisconnected())
return disconnectedLinkID_;
311 __SS__ <<
"Can't get disconnected target name of node unless it is a disconnected link node!" << std::endl;
312 throw std::runtime_error(ss.str());
321 __SS__ <<
"Can't get configuration version of node with no config view pointer!" << std::endl;
322 throw std::runtime_error(ss.str());
324 return configView_->getVersion();
329 const time_t& ConfigurationTree::getConfigurationCreationTime(
void)
const
333 __SS__ <<
"Can't get configuration creation time of node with no config view pointer!" << std::endl;
334 throw std::runtime_error(ss.str());
336 return configView_->getCreationTime();
344 std::vector<std::string> ConfigurationTree::getFixedChoices(
void)
const
348 __SS__ <<
"Can't get fixed choices of node with no config view pointer!" << std::endl;
349 throw std::runtime_error(ss.str());
352 if(getValueType() != ViewColumnInfo::TYPE_FIXED_CHOICE_DATA &&
353 getValueType() != ViewColumnInfo::TYPE_BITMAP_DATA &&
356 __SS__ <<
"Can't get fixed choices of node with value type of '" <<
357 getValueType() <<
".' Node must be a link or a value node with type '" <<
358 ViewColumnInfo::TYPE_BITMAP_DATA <<
"' or '" <<
359 ViewColumnInfo::TYPE_FIXED_CHOICE_DATA <<
".'" << std::endl;
360 throw std::runtime_error(ss.str());
363 std::vector<std::string> retVec;
367 if(!linkParentConfig_)
369 __SS__ <<
"Can't get fixed choices of node with no parent config view pointer!" << std::endl;
370 throw std::runtime_error(ss.str());
373 __MOUT__ << getChildLinkIndex() << std::endl;
374 __MOUT__ << linkColName_ << std::endl;
380 int c = parentView->findCol(linkColName_);
382 __MOUT__ <<
"Link " << c << std::endl;
384 std::pair<
unsigned int ,
unsigned int > linkPair;
386 parentView->getChildLink(c, isGroupLink, linkPair);
389 __MOUT__ <<
"Link " << c << std::endl;
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 __MOUT__ << std::endl;
430 throw std::runtime_error(
"Impossible Link.");
433 else if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
434 return configView_->getDataView()[row_][col_];
435 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
436 return (groupId_ ==
"")?configuration_->getConfigurationName():groupId_;
437 else if(row_ == ConfigurationView::INVALID)
439 __MOUT__ << std::endl;
440 throw std::runtime_error(
"Malformed ConfigurationTree");
442 else if(col_ == ConfigurationView::INVALID)
443 return configView_->getDataView()[row_][configView_->getColUID()];
446 __MOUT__ << std::endl;
447 throw std::runtime_error(
"Impossible.");
455 const std::string& ConfigurationTree::getUIDAsString(
void)
const
457 if(isValueNode() || isUIDLinkNode())
458 return configView_->getDataView()[row_][configView_->getColUID()];
461 __SS__ <<
"Can't get UID of node with type '" <<
462 getNodeType() <<
".' Node type must be '" <<
463 ConfigurationTree::NODE_TYPE_VALUE <<
"' or '" <<
464 ConfigurationTree::NODE_TYPE_UID_LINK <<
".'" << std::endl;
465 throw std::runtime_error(ss.str());
472 const std::string& ConfigurationTree::getValueDataType(
void)
const
475 return configView_->getColumnInfo(col_).getDataType();
477 return ViewColumnInfo::DATATYPE_STRING;
483 bool ConfigurationTree::isDefaultValue(
void)
const
485 if(!isValueNode())
return false;
487 if(getValueDataType() == ViewColumnInfo::DATATYPE_STRING)
489 if(getValueType() == ViewColumnInfo::TYPE_ON_OFF ||
490 getValueType() == ViewColumnInfo::TYPE_TRUE_FALSE ||
491 getValueType() == ViewColumnInfo::TYPE_YES_NO)
492 return getValueAsString() == ViewColumnInfo::DATATYPE_BOOL_DEFAULT;
493 else if(getValueType() == ViewColumnInfo::TYPE_COMMENT)
494 return getValueAsString() == ViewColumnInfo::DATATYPE_COMMENT_DEFAULT ||
495 getValueAsString() ==
"";
497 return getValueAsString() == ViewColumnInfo::DATATYPE_STRING_DEFAULT;
499 else if(getValueDataType() == ViewColumnInfo::DATATYPE_NUMBER)
500 return getValueAsString() == ViewColumnInfo::DATATYPE_NUMBER_DEFAULT;
501 else if(getValueDataType() == ViewColumnInfo::DATATYPE_TIME)
502 return getValueAsString() == ViewColumnInfo::DATATYPE_TIME_DEFAULT;
510 const std::string& ConfigurationTree::getValueType(
void)
const
513 return configView_->getColumnInfo(col_).getType();
514 else if(isLinkNode() && isDisconnected())
515 return ConfigurationTree::VALUE_TYPE_DISCONNECTED;
517 return ConfigurationTree::VALUE_TYPE_NODE;
523 const ViewColumnInfo& ConfigurationTree::getColumnInfo(
void)
const
526 return configView_->getColumnInfo(col_);
529 __SS__ <<
"Can only get column info from a value node! " <<
530 "The node type is " << getNodeType() << std::endl;
531 __MOUT__ <<
"\n" << ss.str() << std::endl;
532 throw std::runtime_error(ss.str());
539 const unsigned int& ConfigurationTree::getRow(
void)
const
544 const unsigned int& ConfigurationTree::getColumn(
void)
const
549 const std::string& ConfigurationTree::getChildLinkIndex(
void)
const
553 __SS__ <<
"Can only get link ID from a link! " <<
554 "The node type is " << getNodeType() << std::endl;
555 __MOUT__ <<
"\n" << ss.str() << std::endl;
556 throw std::runtime_error(ss.str());
558 return childLinkIndex_;
564 const std::string& ConfigurationTree::getValueName(
void)
const
567 return configView_->getColumnInfo(col_).getName();
568 else if(isLinkNode())
572 __SS__ <<
"Can only get value name of a value node!" << std::endl;
573 __MOUT__ <<
"\n" << ss.str() << std::endl;
574 throw std::runtime_error(ss.str());
583 const std::string& childPath,
bool doNotThrowOnBrokenUIDLinks)
587 if(childPath.length() <= 1)
589 return tree.getNode(childPath,doNotThrowOnBrokenUIDLinks);
626 bool doNotThrowOnBrokenUIDLinks)
const
632 if(nodeString.length() < 1)
throw std::runtime_error(
"Invalid node name!");
634 bool startingSlash = nodeString[0] ==
'/';
636 std::string nodeName = nodeString.substr(startingSlash?1:0, nodeString.find(
'/',1)-(startingSlash?1:0));
639 std::string childPath = nodeString.substr(nodeName.length() + (startingSlash?1:0));
648 if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
652 __SS__ <<
"Missing configView pointer! Likely attempting to access a child node through a disconnected link node." << std::endl;
653 __MOUT_ERR__ <<
"\n" << ss.str();
654 throw std::runtime_error(ss.str());
670 configView_->findRow(configView_->getColUID(),nodeName)
671 : configView_->findRowInGroup(configView_->getColUID(),
672 nodeName,groupId_,childLinkIndex_) ),
673 childPath, doNotThrowOnBrokenUIDLinks);
675 else if(row_ == ConfigurationView::INVALID)
677 __SS__ <<
"Malformed ConfigurationTree" << std::endl;
678 __MOUT_ERR__ <<
"\n" << ss.str();
679 throw std::runtime_error(ss.str());
681 else if(col_ == ConfigurationView::INVALID)
695 __SS__ <<
"Missing configView pointer! Likely attempting to access a child node through a disconnected link node." << std::endl;
696 __MOUT_ERR__ <<
"\n" << ss.str();
697 throw std::runtime_error(ss.str());
700 unsigned int c = configView_->findCol(nodeName);
701 std::pair<
unsigned int ,
unsigned int > linkPair;
702 bool isGroupLink, isLink;
703 if((isLink = configView_->getChildLink(c, isGroupLink, linkPair)) &&
714 childConfig = configMgr_->getConfigurationByName(configView_->getDataView()[row_][linkPair.first]);
715 childConfig->getView();
717 if(doNotThrowOnBrokenUIDLinks)
719 childConfig->getView().findRow(childConfig->getView().getColUID(),
720 configView_->getDataView()[row_][linkPair.second]);
737 configView_->getDataView()[row_][c],
738 configView_->getDataView()[row_][linkPair.first],
739 configView_->getDataView()[row_][linkPair.second],
740 configView_->getColumnInfo(c).getChildLinkIndex());
750 configView_->getDataView()[row_][c],
753 configView_->getColumnInfo(c).getChildLinkIndex(),
754 childConfig->getView().findRow(childConfig->getView().getColUID(),
755 configView_->getDataView()[row_][linkPair.second])
757 childPath, doNotThrowOnBrokenUIDLinks);
769 childConfig = configMgr_->getConfigurationByName(
770 configView_->getDataView()[row_][linkPair.first]);
771 childConfig->getView();
775 if(configView_->getDataView()[row_][linkPair.first] !=
776 ViewColumnInfo::DATATYPE_LINK_DEFAULT)
777 __MOUT_WARN__ <<
"Found disconnected node! Failed link target from nodeName=" <<
778 nodeName <<
" to table:id=" <<
779 configView_->getDataView()[row_][linkPair.first] <<
":" <<
780 configView_->getDataView()[row_][linkPair.second] <<
785 configView_->getDataView()[row_][linkPair.second],
788 configView_->getDataView()[row_][c],
789 configView_->getDataView()[row_][linkPair.first],
790 configView_->getDataView()[row_][linkPair.second],
791 configView_->getColumnInfo(c).getChildLinkIndex()
799 configView_->getDataView()[row_][linkPair.second],
802 configView_->getDataView()[row_][c],
805 configView_->getColumnInfo(c).getChildLinkIndex()
807 childPath, doNotThrowOnBrokenUIDLinks);
823 catch(std::runtime_error &e)
825 __SS__ <<
"\n\nError occurred descending from node '" << getValue() <<
826 "' in table '" << getConfigurationName() <<
827 "' looking for child '" << nodeName <<
"'\n\n" << std::endl;
828 ss <<
"--- Additional error detail: \n\n" << e.what() << std::endl;
829 throw std::runtime_error(ss.str());
833 __SS__ <<
"\n\nError occurred descending from node '" << getValue() <<
834 "' in table '" << getConfigurationName() <<
835 "' looking for child '" << nodeName <<
"'\n\n" << std::endl;
836 throw std::runtime_error(ss.str());
840 __SS__ <<
"\n\nError occurred descending from node '" << getValue() <<
841 "' in table '" << getConfigurationName() <<
842 "' looking for child '" << nodeName <<
"'\n\n" <<
843 "Invalid depth! getNode() called from a value point in the Configuration Tree." << std::endl;
844 throw std::runtime_error(ss.str());
849 ConfigurationTree ConfigurationTree::getBackNode(std::string nodeName,
unsigned int backSteps)
const
851 for(
unsigned int i=0; i<backSteps; i++)
852 nodeName = nodeName.substr(0, nodeName.find_last_of(
'/'));
854 return getNode(nodeName);
860 bool ConfigurationTree::isValueNode(
void)
const
862 return (row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID);
870 bool ConfigurationTree::isDisconnected(
void)
const
874 __SS__ <<
"\n\nError occurred testing link connection at node with value '" <<
876 "' in table '" << getConfigurationName() <<
877 "'\n\n" << std::endl;
878 ss <<
"This is not a Link node! It is node type '" <<
879 getNodeType() <<
".' Only a Link node can be disconnected." << std::endl;
880 __MOUT__ <<
"\n" << ss.str();
881 throw std::runtime_error(ss.str());
884 return !configuration_ || !configView_;
890 bool ConfigurationTree::isLinkNode(
void)
const
892 return linkColName_ !=
"";
898 const std::string ConfigurationTree::NODE_TYPE_GROUP_TABLE =
"GroupConfigurationNode";
899 const std::string ConfigurationTree::NODE_TYPE_TABLE =
"ConfigurationNode";
900 const std::string ConfigurationTree::NODE_TYPE_GROUP_LINK =
"GroupLinkNode";
901 const std::string ConfigurationTree::NODE_TYPE_UID_LINK =
"UIDLinkNode";
902 const std::string ConfigurationTree::NODE_TYPE_VALUE =
"ValueNode";
903 const std::string ConfigurationTree::NODE_TYPE_UID =
"UIDNode";
904 std::string ConfigurationTree::getNodeType(
void)
const
906 if(isConfigurationNode() && groupId_ !=
"")
return ConfigurationTree::NODE_TYPE_GROUP_TABLE;
907 if(isConfigurationNode())
return ConfigurationTree::NODE_TYPE_TABLE;
908 if(isGroupLinkNode())
return ConfigurationTree::NODE_TYPE_GROUP_LINK;
909 if(isLinkNode())
return ConfigurationTree::NODE_TYPE_UID_LINK;
910 if(isValueNode())
return ConfigurationTree::NODE_TYPE_VALUE;
911 return ConfigurationTree::NODE_TYPE_UID;
917 bool ConfigurationTree::isGroupLinkNode(
void)
const
919 return (isLinkNode() && groupId_ !=
"");
925 bool ConfigurationTree::isUIDLinkNode(
void)
const
927 return (isLinkNode() && groupId_ ==
"");
933 bool ConfigurationTree::isUIDNode(
void)
const
935 return (row_ != ConfigurationView::INVALID && col_ == ConfigurationView::INVALID);
955 std::vector<ConfigurationTree::RecordField> ConfigurationTree::getCommonFields(
956 const std::vector<std::string /*uid*/> &recordList,
957 const std::vector<std::string /*relative-path*/> &fieldAcceptList,
958 const std::vector<std::string /*relative-path*/> &fieldRejectList,
959 unsigned int depth)
const
962 if(!isConfigurationNode())
964 __SS__ <<
"Can only get getCommonFields from a table node! " <<
965 "The node type is " << getNodeType() << std::endl;
966 __MOUT__ <<
"\n" << ss.str() << std::endl;
967 throw std::runtime_error(ss.str());
970 std::vector<ConfigurationTree::RecordField> fieldCandidateList;
971 std::vector<int> fieldCount;
1009 auto tableName = getConfigurationName();
1011 for(
unsigned int i=0;i<recordList.size();++i)
1015 auto recordChildren = getNode(recordList[i]).getChildren();
1016 for(
const auto &fieldNode : recordChildren)
1020 if(fieldNode.second.isValueNode())
1023 if(fieldNode.second.getColumnInfo().getType() ==
1024 ViewColumnInfo::TYPE_AUTHOR ||
1025 fieldNode.second.getColumnInfo().getType() ==
1026 ViewColumnInfo::TYPE_TIMESTAMP)
1033 found = fieldAcceptList.size()?
false:
true;
1034 for(
const auto &fieldFilter : fieldAcceptList)
1035 if(ConfigurationTree::wildCardMatch(
1036 fieldFilter,fieldNode.first))
1075 for(
const auto &fieldFilter : fieldRejectList)
1076 if(ConfigurationTree::wildCardMatch(
1077 fieldFilter,fieldNode.first))
1116 fieldCandidateList.push_back(
1122 &fieldNode.second.getColumnInfo()
1124 fieldCount.push_back(-1);
1130 else if(depth > 0 &&
1131 fieldNode.second.isUIDLinkNode() &&
1132 !fieldNode.second.isDisconnected())
1135 fieldNode.second.recursiveGetCommonFields(
1141 fieldNode.first +
"/",
1154 for(
unsigned int i=0;i<fieldCandidateList.size();++i)
1159 if(fieldCount[i] != -1 &&
1160 fieldCount[i] != (
int)recordList.size())
1165 fieldCount.erase(fieldCount.begin() + i);
1166 fieldCandidateList.erase(fieldCandidateList.begin() + i);
1175 return fieldCandidateList;
1183 std::set<std::string > ConfigurationTree::getUniqueValuesForField(
1184 const std::vector<std::string /*relative-path*/> &recordList,
1185 const std::string &fieldName)
const
1188 if(!isConfigurationNode())
1190 __SS__ <<
"Can only get getCommonFields from a table node! " <<
1191 "The node type is " << getNodeType() << std::endl;
1192 __MOUT__ <<
"\n" << ss.str() << std::endl;
1193 throw std::runtime_error(ss.str());
1196 std::set<std::string > uniqueValues;
1203 for(
unsigned int i=0;i<recordList.size();++i)
1205 __MOUT__ <<
"Checking " << recordList[i] << std::endl;
1213 uniqueValues.emplace(getNode(recordList[i]).getNode(fieldName).getValueAsString(
true));
1216 return uniqueValues;
1222 void ConfigurationTree::recursiveGetCommonFields(
1223 std::vector<ConfigurationTree::RecordField> &fieldCandidateList,
1224 std::vector<int> &fieldCount,
1225 const std::vector<std::string /*relative-path*/> &fieldAcceptList,
1226 const std::vector<std::string /*relative-path*/> &fieldRejectList,
1228 const std::string &relativePathBase,
1255 auto tableName = getConfigurationName();
1256 auto uid = getUIDAsString();
1259 auto recordChildren = getChildren();
1260 for(
const auto &fieldNode : recordChildren)
1262 if(fieldNode.second.isValueNode())
1265 if(fieldNode.second.getColumnInfo().getType() ==
1266 ViewColumnInfo::TYPE_AUTHOR ||
1267 fieldNode.second.getColumnInfo().getType() ==
1268 ViewColumnInfo::TYPE_TIMESTAMP)
1275 found = fieldAcceptList.size()?
false:
true;
1276 for(
const auto &fieldFilter : fieldAcceptList)
1277 if(ConfigurationTree::wildCardMatch(
1278 fieldFilter,fieldNode.first))
1318 for(
const auto &fieldFilter : fieldRejectList)
1319 if(ConfigurationTree::wildCardMatch(
1320 fieldFilter,fieldNode.first))
1361 fieldCandidateList.push_back(
1367 &fieldNode.second.getColumnInfo()
1369 fieldCount.push_back(1);
1376 for(j=0;j<fieldCandidateList.size();++j)
1378 if((relativePathBase + fieldNode.first) ==
1379 (fieldCandidateList[j].relativePath_ +
1380 fieldCandidateList[j].columnName_))
1391 else if(depth > 0 &&
1392 fieldNode.second.isUIDLinkNode() &&
1393 !fieldNode.second.isDisconnected())
1396 fieldNode.second.recursiveGetCommonFields(
1402 (relativePathBase + fieldNode.first) +
"/",
1413 std::vector<std::pair<std::string,ConfigurationTree> > ConfigurationTree::getChildren(
1414 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap)
const
1416 std::vector<std::pair<std::string,ConfigurationTree> > retMap;
1420 bool filtering = filterMap.size();
1422 std::string fieldValue;
1424 std::vector<std::string> childrenNames = getChildrenNames();
1425 for(
auto &childName : childrenNames)
1435 for(
const auto &filterPair:filterMap)
1437 std::string filterPath = childName +
"/" + filterPair.first;
1442 std::istringstream f(filterPair.second);
1446 while (getline(f, fieldValue,
','))
1455 __MOUT__ <<
"\t\tCheck: " << filterPair.first <<
1456 " == " << fieldValue <<
" ??? " <<
1457 this->getNode(filterPath).getValueAsString(
true) <<
1460 if(ConfigurationTree::wildCardMatch(
1461 ConfigurationView::decodeURIComponent(fieldValue),
1462 this->getNode(filterPath).getValueAsString(
true) ))
1480 __SS__ <<
"Failed to access filter path '" <<
1481 filterPath <<
"' - aborting." << std::endl;
1482 __MOUT_ERR__ <<
"\n" << ss.str();
1483 throw std::runtime_error(ss.str());
1491 __MOUT__ <<
"\tChild accepted: " << childName << std::endl;
1494 retMap.push_back(std::pair<std::string,ConfigurationTree>(childName,
1495 this->getNode(childName,
true)));
1506 bool ConfigurationTree::wildCardMatch(
const std::string& needle,
const std::string& haystack)
1513 if(needle.size() == 0)
1516 if(needle[0] ==
'*' &&
1517 needle[needle.size()-1] ==
'*' )
1518 return std::string::npos != haystack.find(needle.substr(1,needle.size()-2));
1520 if(needle[0] ==
'*')
1521 return needle.substr(1) ==
1522 haystack.substr(haystack.size() - (needle.size()-1));
1524 if(needle[needle.size()-1] ==
'*')
1525 return needle.substr(0,needle.size()-1) ==
1526 haystack.substr(0,needle.size()-1);
1529 return needle == haystack;
1540 std::map<std::string,ConfigurationTree> ConfigurationTree::getChildrenMap(
void)
const
1542 std::map<std::string,ConfigurationTree> retMap;
1546 std::vector<std::string> childrenNames = getChildrenNames();
1547 for(
auto& childName : childrenNames)
1550 retMap.insert(std::pair<std::string,ConfigurationTree>(childName, this->getNode(childName)));
1558 bool ConfigurationTree::isConfigurationNode(
void)
const
1560 return (row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID);
1566 std::vector<std::string> ConfigurationTree::getChildrenNames(
void)
const
1568 std::vector<std::string> retSet;
1572 __SS__ <<
"Can not get children names of '" <<
1573 getValueAsString() <<
1574 "' with null configuration view pointer!" << std::endl;
1575 if(isLinkNode() && isDisconnected())
1576 ss <<
" This node is a disconnected link to " <<
1577 getDisconnectedTableName() << std::endl;
1578 __MOUT_ERR__ <<
"\n" << ss.str();
1579 throw std::runtime_error(ss.str());
1582 if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
1587 for(
unsigned int r = 0; r<configView_->getNumberOfRows(); ++r)
1588 if(groupId_ ==
"" ||
1589 configView_->isEntryInGroup(r,childLinkIndex_,groupId_))
1592 retSet.push_back(configView_->getDataView()[r][configView_->getColUID()]);
1594 else if(row_ == ConfigurationView::INVALID)
1595 throw std::runtime_error(
"Malformed ConfigurationTree");
1596 else if(col_ == ConfigurationView::INVALID)
1601 for(
unsigned int c = 0; c<configView_->getNumberOfColumns(); ++c)
1602 if(c == configView_->getColUID() ||
1603 configView_->getColumnInfo(c).isChildLinkGroupID() ||
1604 configView_->getColumnInfo(c).isChildLinkUID())
1607 retSet.push_back(configView_->getColumnInfo(c).getName());
1611 __MOUT__ <<
"\n\nError occurred looking for children of nodeName=" << getValueName() <<
"\n\n" << std::endl;
1612 throw std::runtime_error(
"Invalid depth! getChildrenValues() called from a value point in the Configuration Tree.");
1630 __SS__ <<
"Invalid node for get value." << std::endl;
1631 __MOUT__ << ss.str();
1632 throw std::runtime_error(ss.str());
1635 std::string valueString = configView_->getValueAsString(row_,col_,
true );
1637 if(valueString.size() && valueString[0] ==
'/')
1643 __MOUT__ <<
"Found a valid tree path in value!" << std::endl;
1648 __SS__ <<
"Invalid tree path." << std::endl;
1650 throw std::runtime_error(ss.str());
1656 __SS__ <<
"Invalid value string '" << valueString <<
1657 "' - must start with a '/' character." << std::endl;
1658 throw std::runtime_error(ss.str());