00001 #include "otsdaq-core/ConfigurationInterface/ConfigurationTree.h"
00002
00003 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationBase.h"
00004 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
00005 #include <typeinfo>
00006 #include "otsdaq-core/Macros/StringMacros.h"
00007 #if MESSAGEFACILITY_HEX_VERSION > 0x20100
00008 #include <boost/stacktrace.hpp>
00009 #endif
00010
00011 using namespace ots;
00012
00013
00014 #undef __MF_SUBJECT__
00015 #define __MF_SUBJECT__ "ConfigurationTree"
00016
00017 const std::string ConfigurationTree::DISCONNECTED_VALUE = "X";
00018 const std::string ConfigurationTree::VALUE_TYPE_DISCONNECTED = "Disconnected";
00019 const std::string ConfigurationTree::VALUE_TYPE_NODE = "Node";
00020
00021
00022 ConfigurationTree::ConfigurationTree()
00023 : configMgr_ (0),
00024 configuration_ (0),
00025 groupId_ (""),
00026 linkParentConfig_ (0),
00027 linkColName_ (""),
00028 linkColValue_ (""),
00029 linkBackRow_ (0),
00030 linkBackCol_ (0),
00031 disconnectedTargetName_ (""),
00032 disconnectedLinkID_ (""),
00033 childLinkIndex_ (""),
00034 row_ (0),
00035 col_ (0),
00036 configView_ (0)
00037 {
00038
00039
00040 }
00041
00042 ConfigurationTree::ConfigurationTree(const ConfigurationManager* const &configMgr,
00043 const ConfigurationBase* const &config)
00044 : ConfigurationTree(configMgr, config, "" , 0 ,
00045 "" , "" ,
00046 ConfigurationView::INVALID , ConfigurationView::INVALID ,
00047 "" ,
00048 "" , "" ,
00049 ConfigurationView::INVALID , ConfigurationView::INVALID )
00050 {
00051
00052
00053 }
00054
00055
00056 ConfigurationTree::ConfigurationTree(
00057 const ConfigurationManager* const& configMgr,
00058 const ConfigurationBase* const& config,
00059 const std::string& groupId,
00060 const ConfigurationBase* const& linkParentConfig,
00061 const std::string& linkColName,
00062 const std::string& linkColValue,
00063 const unsigned int linkBackRow,
00064 const unsigned int linkBackCol,
00065 const std::string& disconnectedTargetName,
00066 const std::string& disconnectedLinkID,
00067 const std::string& childLinkIndex,
00068 const unsigned int row,
00069 const unsigned int col)
00070 : configMgr_ (configMgr),
00071 configuration_ (config),
00072 groupId_ (groupId),
00073 linkParentConfig_ (linkParentConfig),
00074 linkColName_ (linkColName),
00075 linkColValue_ (linkColValue),
00076 linkBackRow_ (linkBackRow),
00077 linkBackCol_ (linkBackCol),
00078 disconnectedTargetName_ (disconnectedTargetName),
00079 disconnectedLinkID_ (disconnectedLinkID),
00080 childLinkIndex_ (childLinkIndex),
00081 row_ (row),
00082 col_ (col),
00083 configView_ (0)
00084 {
00085
00086
00087 if(!configMgr_)
00088 {
00089 std::stringstream ss;
00090 ss << __COUT_HDR_FL__ << "Invalid empty pointer given to tree!\n" <<
00091 "\n\tconfigMgr_=" << configMgr_ <<
00092 "\n\tconfiguration_=" << configuration_ <<
00093 "\n\tconfigView_=" << configView_ <<
00094 std::endl;
00095 __COUT__ << "\n" << ss.str();
00096 throw std::runtime_error(ss.str());
00097 }
00098
00099 if(configuration_)
00100 configView_ = &(configuration_->getView());
00101
00102
00103 if(configView_ &&
00104 configView_->getColumnInfo(configView_->getColUID()).getType() != ViewColumnInfo::TYPE_UID)
00105 {
00106 __SS__ << "Missing UID column (must column of type " << ViewColumnInfo::TYPE_UID <<
00107 ") in config view : " << configView_->getTableName() << std::endl;
00108 __COUT__ << "\n" << ss.str();
00109 throw std::runtime_error(ss.str());
00110 }
00111 }
00112
00113
00114
00115 ConfigurationTree::~ConfigurationTree(void)
00116 {
00117
00118 }
00119
00120
00121
00122
00123
00124
00125
00126 void ConfigurationTree::print(const unsigned int &depth, std::ostream &out) const
00127 {
00128 recursivePrint(*this,depth,out,"\t");
00129 }
00130
00131
00132 void ConfigurationTree::recursivePrint(const ConfigurationTree &t, unsigned int depth, std::ostream &out, std::string space)
00133 {
00134 if(t.isValueNode())
00135 out << space << t.getValueName() << " :\t" << t.getValueAsString() << std::endl;
00136 else
00137 {
00138 if(t.isLinkNode())
00139 {
00140 out << space << t.getValueName();
00141 if(t.isDisconnected())
00142 {
00143 out << " :\t" << t.getValueAsString() << std::endl;
00144 return;
00145 }
00146 out << " (" <<
00147 (t.isGroupLinkNode()?"Group":"U") <<
00148 "ID=" << t.getValueAsString() <<
00149 ") : " << std::endl;
00150 }
00151 else
00152 out << space << t.getValueAsString() << " : " << std::endl;
00153
00154
00155
00156 if(depth >= 1)
00157 {
00158 auto C = t.getChildren();
00159 if(!C.empty())
00160 out << space << "{" << std::endl;
00161 for(auto &c:C)
00162 recursivePrint(c.second,depth-1,out,space + " ");
00163 if(!C.empty())
00164 out << space << "}" << std::endl;
00165 }
00166 }
00167 }
00168
00169
00170
00171
00172
00173
00174 void ConfigurationTree::getValue(std::string& value) const
00175 {
00176
00177
00178 if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
00179 {
00180
00181 try
00182 {
00183 ConfigurationTree valueAsTreeNode = getValueAsTreeNode();
00184
00185 __COUT__ << "Success following path to tree node!" << std::endl;
00186
00187
00188
00189
00190
00191
00192 value = configView_->validateValueForColumn(
00193 valueAsTreeNode.getValueAsString(),col_);
00194
00195
00196 __COUT__ << "Successful value!" << std::endl;
00197
00198
00199
00200
00201
00202 return;
00203 }
00204 catch(...)
00205 {
00206
00207 }
00208
00209
00210 configView_->getValue(value,row_,col_);
00211 }
00212 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
00213 {
00214 if(isLinkNode() && isDisconnected())
00215 value = (groupId_ == "") ? getValueName():groupId_;
00216 else
00217 value = (groupId_ == "") ? configuration_->getConfigurationName():groupId_;
00218 }
00219 else if(row_ == ConfigurationView::INVALID)
00220 {
00221 __SS__ << "Malformed ConfigurationTree" << std::endl;
00222 __COUT_ERR__ << ss.str();
00223 throw std::runtime_error(ss.str());
00224 }
00225 else if(col_ == ConfigurationView::INVALID)
00226 configView_->getValue(value,row_,configView_->getColUID());
00227 else
00228 {
00229 __SS__ << "Impossible." << std::endl;
00230 __COUT_ERR__ << ss.str();
00231 throw std::runtime_error(ss.str());
00232 }
00233
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00247
00248 std::string ConfigurationTree::getValue() const
00249 {
00250 std::string value;
00251 ConfigurationTree::getValue(value);
00252 return value;
00253 }
00254
00255
00256
00257
00258
00259
00260 void ConfigurationTree::getValueAsBitMap(ConfigurationTree::BitMap& bitmap) const
00261 {
00262
00263
00264 if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
00265 {
00266 std::string bitmapString;
00267 configView_->getValue(bitmapString,row_,col_);
00268
00269 __COUTV__(bitmapString);
00270 if(bitmapString == ViewColumnInfo::DATATYPE_STRING_DEFAULT)
00271 {
00272 bitmap.isDefault_ = true;
00273 return;
00274 }
00275 else
00276 bitmap.isDefault_ = false;
00277
00278
00279 {
00280 bitmap.bitmap_.clear();
00281 int row = -1;
00282 bool openRow = false;
00283 unsigned int startInt = -1;
00284 for(unsigned int i=0; i<bitmapString.length(); i++)
00285 {
00286 __COUTV__(bitmapString[i]);
00287 __COUTV__(row);
00288 __COUTV__(openRow);
00289 __COUTV__(startInt);
00290 __COUTV__(i);
00291
00292 if(!openRow)
00293 {
00294 if(bitmapString[i] == '[')
00295 {
00296 openRow = true;
00297 ++row;
00298 bitmap.bitmap_.push_back(std::vector<uint64_t>());
00299 }
00300 else if(bitmapString[i] == ']')
00301 {
00302 break;
00303 }
00304 else if(bitmapString[i] == ',')
00305 {
00306 __SS__ << "Too many ']' or ',' characters in bit map configuration" << std::endl;
00307 __SS_THROW__;
00308 }
00309 }
00310 else if(startInt == (unsigned int)-1)
00311 {
00312 if(bitmapString[i] == ']')
00313 {
00314 openRow = false;
00315 }
00316 else if(bitmapString[i] >= '0' && bitmapString[i] <= '9')
00317 {
00318 startInt = i;
00319 }
00320 else if(bitmapString[i] == ',')
00321 {
00322 __SS__ << "Too many ',' characters in bit map configuration" << std::endl;
00323 __SS_THROW__;
00324 }
00325 }
00326 else
00327 {
00328
00329
00330 if(bitmapString[i] == ']')
00331 {
00332 openRow = false;
00333 bitmap.bitmap_[row].push_back(strtoul(
00334 bitmapString.substr(startInt,i-startInt).c_str(),0,0));
00335 startInt = -1;
00336 }
00337 else if(bitmapString[i] == ',')
00338 {
00339 bitmap.bitmap_[row].push_back(strtoul(
00340 bitmapString.substr(startInt,i-startInt).c_str(),0,0));
00341 startInt = -1;
00342 }
00343 }
00344 }
00345
00346 for(unsigned int r = 0; r<bitmap.bitmap_.size(); ++r)
00347 {
00348 for(unsigned int c = 0; c<bitmap.bitmap_[r].size(); ++c)
00349 {
00350 __COUT__ << r << "," << c << " = " << bitmap.bitmap_[r][c] << __E__;
00351 }
00352 __COUT__ << "================" << __E__;
00353 }
00354 }
00355
00356 }
00357 else
00358 {
00359 __SS__ << "Requesting getValue must be on a value node." << std::endl;
00360 __COUT_ERR__ << ss.str();
00361 throw std::runtime_error(ss.str());
00362 }
00363
00364 }
00365
00366
00367
00368
00369
00370 ConfigurationTree::BitMap ConfigurationTree::getValueAsBitMap() const
00371 {
00372 ConfigurationTree::BitMap value;
00373 ConfigurationTree::getValueAsBitMap(value);
00374 return value;
00375 }
00376
00377
00378
00379
00380 std::string ConfigurationTree::getEscapedValue() const
00381 {
00382 if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
00383 return configView_->getEscapedValueAsString(row_,col_);
00384
00385 __SS__ << "Can not get escaped value except from a value node!" <<
00386 " This node is type '" << getNodeType() << "." << std::endl;
00387 __COUT_ERR__ << "\n" << ss.str();
00388 throw std::runtime_error(ss.str());
00389 }
00390
00391
00392
00393 const std::string& ConfigurationTree::getConfigurationName(void) const
00394 {
00395 if(!configuration_)
00396 {
00397 __SS__ << "Can not get configuration name of node with no configuration pointer!" << std::endl;
00398 throw std::runtime_error(ss.str());
00399 }
00400 return configuration_->getConfigurationName();
00401 }
00402
00403
00404
00405
00406
00407 const std::string& ConfigurationTree::getFieldConfigurationName(void) const
00408 {
00409
00410 if(isLinkNode())
00411 {
00412 if(!linkParentConfig_)
00413 {
00414 __SS__ << "Can not get configuration name of link node field with no parent configuration pointer!" << std::endl;
00415 throw std::runtime_error(ss.str());
00416 }
00417 return linkParentConfig_->getConfigurationName();
00418 }
00419 else
00420 return getConfigurationName();
00421 }
00422
00423
00424
00425 const std::string& ConfigurationTree::getDisconnectedTableName(void) const
00426 {
00427 if(isLinkNode() && isDisconnected()) return disconnectedTargetName_;
00428
00429 __SS__ << "Can not get disconnected target name of node unless it is a disconnected link node!" << std::endl;
00430 throw std::runtime_error(ss.str());
00431 }
00432
00433
00434
00435 const std::string& ConfigurationTree::getDisconnectedLinkID(void) const
00436 {
00437 if(isLinkNode() && isDisconnected()) return disconnectedLinkID_;
00438
00439 __SS__ << "Can not get disconnected target name of node unless it is a disconnected link node!" << std::endl;
00440 throw std::runtime_error(ss.str());
00441 }
00442
00443
00444
00445 const ConfigurationVersion& ConfigurationTree::getConfigurationVersion(void) const
00446 {
00447 if(!configView_)
00448 {
00449 __SS__ << "Can not get configuration version of node with no config view pointer!" << std::endl;
00450 throw std::runtime_error(ss.str());
00451 }
00452 return configView_->getVersion();
00453 }
00454
00455
00456
00457 const time_t& ConfigurationTree::getConfigurationCreationTime(void) const
00458 {
00459 if(!configView_)
00460 {
00461 __SS__ << "Can not get configuration creation time of node with no config view pointer!" << std::endl;
00462 throw std::runtime_error(ss.str());
00463 }
00464 return configView_->getCreationTime();
00465 }
00466
00467
00468
00469
00470
00471
00472 std::vector<std::string> ConfigurationTree::getFixedChoices(void) const
00473 {
00474 if(getValueType() != ViewColumnInfo::TYPE_FIXED_CHOICE_DATA &&
00475 getValueType() != ViewColumnInfo::TYPE_BITMAP_DATA &&
00476 !isLinkNode())
00477 {
00478 __SS__ << "Can not get fixed choices of node with value type of '" <<
00479 getValueType() << ".' Node must be a link or a value node with type '" <<
00480 ViewColumnInfo::TYPE_BITMAP_DATA << "' or '" <<
00481 ViewColumnInfo::TYPE_FIXED_CHOICE_DATA << ".'" << std::endl;
00482 throw std::runtime_error(ss.str());
00483 }
00484
00485 std::vector<std::string> retVec;
00486
00487 if(isLinkNode())
00488 {
00489 if(!linkParentConfig_)
00490 {
00491 __SS__ << "Can not get fixed choices of node with no parent config view pointer!" << std::endl;
00492 throw std::runtime_error(ss.str());
00493 }
00494
00495
00496
00497
00498
00499
00500
00501 const ConfigurationView* parentView = &(linkParentConfig_->getView());
00502 int c = parentView->findCol(linkColName_);
00503
00504 std::pair<unsigned int , unsigned int > linkPair;
00505 bool isGroupLink;
00506 parentView->getChildLink(c, isGroupLink, linkPair);
00507 c = linkPair.first;
00508
00509 std::vector<std::string> choices = parentView->getColumnInfo(c).getDataChoices();
00510 for(const auto &choice:choices)
00511 retVec.push_back(choice);
00512
00513 return retVec;
00514 }
00515
00516 if(!configView_)
00517 {
00518 __SS__ << "Can not get fixed choices of node with no config view pointer!" << std::endl;
00519 throw std::runtime_error(ss.str());
00520 }
00521
00522
00523 retVec.push_back(configView_->getColumnInfo(col_).getDefaultValue());
00524 std::vector<std::string> choices = configView_->getColumnInfo(col_).getDataChoices();
00525 for(const auto &choice:choices)
00526 retVec.push_back(choice);
00527
00528 return retVec;
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 const std::string& ConfigurationTree::getValueAsString(bool returnLinkTableValue) const
00540 {
00541 if(isLinkNode())
00542 {
00543 if(returnLinkTableValue)
00544 return linkColValue_;
00545 else if(isDisconnected())
00546 return ConfigurationTree::DISCONNECTED_VALUE;
00547 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
00548 return (groupId_ == "")?configuration_->getConfigurationName():groupId_;
00549 else if(col_ == ConfigurationView::INVALID)
00550 return configView_->getDataView()[row_][configView_->getColUID()];
00551 else
00552 {
00553 __SS__ << "Impossible Link." << std::endl;
00554 __COUT_ERR__ << ss.str();
00555 throw std::runtime_error(ss.str());
00556 }
00557 }
00558 else if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
00559 return configView_->getDataView()[row_][col_];
00560 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
00561 return (groupId_ == "")?configuration_->getConfigurationName():groupId_;
00562 else if(row_ == ConfigurationView::INVALID)
00563 {
00564 __SS__ << "Malformed ConfigurationTree" << std::endl;
00565 __COUT_ERR__ << ss.str();
00566 throw std::runtime_error(ss.str());
00567 }
00568 else if(col_ == ConfigurationView::INVALID)
00569 return configView_->getDataView()[row_][configView_->getColUID()];
00570 else
00571 {
00572 __SS__ << "Impossible." << std::endl;
00573 __COUT_ERR__ << ss.str();
00574 throw std::runtime_error(ss.str());
00575 }
00576 }
00577
00578
00579
00580
00581
00582 const std::string& ConfigurationTree::getUIDAsString(void) const
00583 {
00584 if(isValueNode() || isUIDLinkNode())
00585 return configView_->getDataView()[row_][configView_->getColUID()];
00586
00587 {
00588 __SS__ << "Can not get UID of node with type '" <<
00589 getNodeType() << ".' Node type must be '" <<
00590 ConfigurationTree::NODE_TYPE_VALUE << "' or '" <<
00591 ConfigurationTree::NODE_TYPE_UID_LINK << ".'" << std::endl;
00592 throw std::runtime_error(ss.str());
00593 }
00594 }
00595
00596
00597
00598
00599 const std::string& ConfigurationTree::getValueDataType(void) const
00600 {
00601 if(isValueNode())
00602 return configView_->getColumnInfo(col_).getDataType();
00603 else
00604 return ViewColumnInfo::DATATYPE_STRING;
00605 }
00606
00607
00608
00609
00610 bool ConfigurationTree::isDefaultValue(void) const
00611 {
00612 if(!isValueNode()) return false;
00613
00614 if(getValueDataType() == ViewColumnInfo::DATATYPE_STRING)
00615 {
00616 if(getValueType() == ViewColumnInfo::TYPE_ON_OFF ||
00617 getValueType() == ViewColumnInfo::TYPE_TRUE_FALSE ||
00618 getValueType() == ViewColumnInfo::TYPE_YES_NO)
00619 return getValueAsString() == ViewColumnInfo::DATATYPE_BOOL_DEFAULT;
00620 else if(getValueType() == ViewColumnInfo::TYPE_COMMENT)
00621 return getValueAsString() == ViewColumnInfo::DATATYPE_COMMENT_DEFAULT ||
00622 getValueAsString() == "";
00623 else
00624 return getValueAsString() == ViewColumnInfo::DATATYPE_STRING_DEFAULT;
00625 }
00626 else if(getValueDataType() == ViewColumnInfo::DATATYPE_NUMBER)
00627 return getValueAsString() == ViewColumnInfo::DATATYPE_NUMBER_DEFAULT;
00628 else if(getValueDataType() == ViewColumnInfo::DATATYPE_TIME)
00629 return getValueAsString() == ViewColumnInfo::DATATYPE_TIME_DEFAULT;
00630 else
00631 return false;
00632 }
00633
00634
00635
00636
00637 const std::string& ConfigurationTree::getValueType(void) const
00638 {
00639 if(isValueNode())
00640 return configView_->getColumnInfo(col_).getType();
00641 else if(isLinkNode() && isDisconnected())
00642 return ConfigurationTree::VALUE_TYPE_DISCONNECTED;
00643 else
00644 return ConfigurationTree::VALUE_TYPE_NODE;
00645 }
00646
00647
00648
00649
00650 const ViewColumnInfo& ConfigurationTree::getColumnInfo(void) const
00651 {
00652 if(isValueNode())
00653 return configView_->getColumnInfo(col_);
00654 else
00655 {
00656 __SS__ << "Can only get column info from a value node! " <<
00657 "The node type is " << getNodeType() << std::endl;
00658 __COUT__ << "\n" << ss.str() << std::endl;
00659 throw std::runtime_error(ss.str());
00660 }
00661
00662 }
00663
00664
00665
00666 const unsigned int& ConfigurationTree::getRow(void) const
00667 {
00668 return row_;
00669 }
00670
00671
00672
00673 const unsigned int& ConfigurationTree::getColumn(void) const
00674 {
00675 return col_;
00676 }
00677
00678
00679
00680
00681 const unsigned int& ConfigurationTree::getFieldRow(void) const
00682 {
00683 if(isLinkNode())
00684 {
00685
00686 return linkBackRow_;
00687 }
00688 else
00689 return row_;
00690 }
00691
00692
00693
00694
00695 const unsigned int& ConfigurationTree::getFieldColumn(void) const
00696 {
00697 if(isLinkNode())
00698 {
00699
00700 return linkBackCol_;
00701 }
00702 else
00703 return col_;
00704 }
00705
00706
00707
00708 const std::string& ConfigurationTree::getChildLinkIndex(void) const
00709 {
00710 if(!isLinkNode())
00711 {
00712 __SS__ << "Can only get link ID from a link! " <<
00713 "The node type is " << getNodeType() << std::endl;
00714 __COUT__ << "\n" << ss.str() << std::endl;
00715 throw std::runtime_error(ss.str());
00716 }
00717 return childLinkIndex_;
00718 }
00719
00720
00721
00722
00723 const std::string& ConfigurationTree::getValueName(void) const
00724 {
00725 if(isValueNode())
00726 return configView_->getColumnInfo(col_).getName();
00727 else if(isLinkNode())
00728 return linkColName_;
00729 else
00730 {
00731 __SS__ << "Can only get value name of a value node!" << std::endl;
00732 __COUT__ << "\n" << ss.str() << std::endl;
00733 throw std::runtime_error(ss.str());
00734 }
00735
00736 }
00737
00738
00739
00740
00741 ConfigurationTree ConfigurationTree::recurse(const ConfigurationTree& tree,
00742 const std::string& childPath, bool doNotThrowOnBrokenUIDLinks)
00743 {
00744
00745
00746 if(childPath.length() <= 1)
00747 return tree;
00748 return tree.getNode(childPath,doNotThrowOnBrokenUIDLinks);
00749 }
00750
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784 ConfigurationTree ConfigurationTree::getNode(const std::string &nodeString,
00785 bool doNotThrowOnBrokenUIDLinks) const
00786 {
00787
00788
00789
00790
00791 if(nodeString.length() < 1)
00792 {
00793 __SS__ << "Invalid empty node name! Looking for child node from node '" <<
00794 getValue() << "'..." << std::endl;
00795 __COUT_ERR__ << ss.str();
00796 throw std::runtime_error(ss.str());
00797 }
00798
00799 bool startingSlash = nodeString[0] == '/';
00800
00801 std::string nodeName = nodeString.substr(startingSlash?1:0, nodeString.find('/',1)-(startingSlash?1:0));
00802
00803
00804 std::string childPath = nodeString.substr(nodeName.length() + (startingSlash?1:0));
00805
00806
00807
00808
00809 try
00810 {
00811
00812
00813 if(!configuration_)
00814 {
00815
00816
00817 return recurse(
00818 configMgr_->getNode(nodeName),
00819 childPath, doNotThrowOnBrokenUIDLinks);
00820 }
00821 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
00822 {
00823
00824
00825 if(!configView_)
00826 {
00827 __SS__ << "Missing configView pointer! Likely attempting to access a child node through a disconnected link node." << std::endl;
00828 __COUT_ERR__ << "\n" << ss.str();
00829 throw std::runtime_error(ss.str());
00830 }
00831
00832
00833 return recurse(ConfigurationTree(
00834 configMgr_,
00835 configuration_,
00836 "",
00837 0 ,
00838 "",
00839 "",
00840 ConfigurationView::INVALID , ConfigurationView::INVALID ,
00841 "",
00842 "",
00843 "",
00844
00845 (groupId_ == "")?
00846 configView_->findRow(configView_->getColUID(),nodeName)
00847 : configView_->findRowInGroup(configView_->getColUID(),
00848 nodeName,groupId_,childLinkIndex_) ),
00849 childPath, doNotThrowOnBrokenUIDLinks);
00850 }
00851 else if(row_ == ConfigurationView::INVALID)
00852 {
00853 __SS__ << "Malformed ConfigurationTree" << std::endl;
00854 __COUT_ERR__ << "\n" << ss.str();
00855 throw std::runtime_error(ss.str());
00856 }
00857 else if(col_ == ConfigurationView::INVALID)
00858 {
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 if(!configView_)
00870 {
00871 __SS__ << "Missing configView pointer! Likely attempting to access a child node through a disconnected link node." << std::endl;
00872 __COUT_ERR__ << "\n" << ss.str();
00873 throw std::runtime_error(ss.str());
00874 }
00875
00876 unsigned int c = configView_->findCol(nodeName);
00877 std::pair<unsigned int , unsigned int > linkPair;
00878 bool isGroupLink, isLink;
00879 if((isLink = configView_->getChildLink(c, isGroupLink, linkPair)) &&
00880 !isGroupLink)
00881 {
00882
00883
00884
00885
00886
00887 const ConfigurationBase* childConfig;
00888 try
00889 {
00890 childConfig = configMgr_->getConfigurationByName(configView_->getDataView()[row_][linkPair.first]);
00891 childConfig->getView();
00892
00893 if(doNotThrowOnBrokenUIDLinks)
00894 {
00895 childConfig->getView().findRow(childConfig->getView().getColUID(),
00896 configView_->getDataView()[row_][linkPair.second]);
00897 }
00898 }
00899 catch(...)
00900 {
00901
00902
00903
00904
00905
00906
00907 return ConfigurationTree(
00908 configMgr_,
00909 0,
00910 "",
00911 configuration_,
00912 nodeName,
00913 configView_->getDataView()[row_][c],
00914 row_ , c ,
00915 configView_->getDataView()[row_][linkPair.first],
00916 configView_->getDataView()[row_][linkPair.second],
00917 configView_->getColumnInfo(c).getChildLinkIndex());
00918 }
00919
00920 return recurse(
00921 ConfigurationTree(
00922 configMgr_,
00923 childConfig,
00924 "",
00925 configuration_,
00926 nodeName,
00927 configView_->getDataView()[row_][c],
00928 row_ , c ,
00929 "",
00930 "",
00931 configView_->getColumnInfo(c).getChildLinkIndex(),
00932 childConfig->getView().findRow(childConfig->getView().getColUID(),
00933 configView_->getDataView()[row_][linkPair.second])
00934 ),
00935 childPath, doNotThrowOnBrokenUIDLinks);
00936 }
00937 else if(isLink)
00938 {
00939
00940
00941
00942
00943
00944 const ConfigurationBase* childConfig;
00945 try
00946 {
00947 childConfig = configMgr_->getConfigurationByName(
00948 configView_->getDataView()[row_][linkPair.first]);
00949 childConfig->getView();
00950 }
00951 catch(...)
00952 {
00953 if(configView_->getDataView()[row_][linkPair.first] !=
00954 ViewColumnInfo::DATATYPE_LINK_DEFAULT)
00955 __COUT_WARN__ << "Found disconnected node! Failed link target from nodeName=" <<
00956 nodeName << " to table:id=" <<
00957 configView_->getDataView()[row_][linkPair.first] << ":" <<
00958 configView_->getDataView()[row_][linkPair.second] <<
00959 std::endl;
00960
00961
00962 return ConfigurationTree(configMgr_,0,
00963 configView_->getDataView()[row_][linkPair.second],
00964 configuration_,
00965 nodeName,
00966 configView_->getDataView()[row_][c],
00967 row_ , c ,
00968 configView_->getDataView()[row_][linkPair.first],
00969 configView_->getDataView()[row_][linkPair.second],
00970 configView_->getColumnInfo(c).getChildLinkIndex()
00971 );
00972 }
00973
00974 return recurse(
00975 ConfigurationTree(
00976 configMgr_,
00977 childConfig,
00978 configView_->getDataView()[row_][linkPair.second],
00979 configuration_,
00980 nodeName,
00981 configView_->getDataView()[row_][c],
00982 row_ , c ,
00983 "",
00984 "",
00985 configView_->getColumnInfo(c).getChildLinkIndex()
00986 ),
00987 childPath, doNotThrowOnBrokenUIDLinks);
00988 }
00989 else
00990 {
00991
00992
00993 return ConfigurationTree(
00994 configMgr_,
00995 configuration_,"",
00996 0 ,
00997 "","",
00998 ConfigurationView::INVALID , ConfigurationView::INVALID ,
00999 "","","",
01000 row_,c);
01001 }
01002 }
01003
01004 }
01005 catch(std::runtime_error &e)
01006 {
01007 __SS__ << "\n\nError occurred descending from node '" << getValue() <<
01008 "' in table '" << getConfigurationName() <<
01009 "' looking for child '" << nodeName << "'\n\n" << std::endl;
01010 ss << "--- Additional error detail: \n\n" << e.what() << std::endl;
01011 #if MESSAGEFACILITY_HEX_VERSION > 0x20100
01012 ss << boost::stacktrace::stacktrace();
01013 #endif
01014 throw std::runtime_error(ss.str());
01015 }
01016 catch(...)
01017 {
01018 __SS__ << "\n\nError occurred descending from node '" << getValue() <<
01019 "' in table '" << getConfigurationName() <<
01020 "' looking for child '" << nodeName << "'\n\n" << std::endl;
01021 #if MESSAGEFACILITY_HEX_VERSION > 0x20100
01022 ss << boost::stacktrace::stacktrace();
01023 #endif
01024 throw std::runtime_error(ss.str());
01025 }
01026
01027
01028 __SS__ << "\n\nError occurred descending from node '" << getValue() <<
01029 "' in table '" << getConfigurationName() <<
01030 "' looking for child '" << nodeName << "'\n\n" <<
01031 "Invalid depth! getNode() called from a value point in the Configuration Tree." << std::endl;
01032 #if MESSAGEFACILITY_HEX_VERSION > 0x20100
01033 ss << boost::stacktrace::stacktrace();
01034 #endif
01035 throw std::runtime_error(ss.str());
01036 }
01037
01038
01039
01040 ConfigurationTree ConfigurationTree::getBackNode(std::string nodeName, unsigned int backSteps) const
01041 {
01042 for(unsigned int i=0; i<backSteps; i++)
01043 nodeName = nodeName.substr(0, nodeName.find_last_of('/'));
01044
01045 return getNode(nodeName);
01046 }
01047
01048
01049 ConfigurationTree ConfigurationTree::getForwardNode(std::string nodeName, unsigned int forwardSteps) const
01050 {
01051 unsigned int s = 0;
01052
01053
01054 while(s < nodeName.length() && nodeName[s] == '/') ++s;
01055
01056 for(unsigned int i=0; i<forwardSteps; i++)
01057 s = nodeName.find('/',s) + 1;
01058
01059 return getNode(nodeName.substr(0,s));
01060 }
01061
01062
01063
01064 bool ConfigurationTree::isValueNode(void) const
01065 {
01066 return (row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID);
01067 }
01068
01069
01070
01071
01072
01073
01074 bool ConfigurationTree::isDisconnected(void) const
01075 {
01076 if(!isLinkNode())
01077 {
01078 __SS__ << "\n\nError occurred testing link connection at node with value '" <<
01079 getValue() <<
01080 "' in table '" << getConfigurationName() <<
01081 "'\n\n" << std::endl;
01082 ss << "This is not a Link node! It is node type '" <<
01083 getNodeType() << ".' Only a Link node can be disconnected." << std::endl;
01084
01085 throw std::runtime_error(ss.str());
01086 }
01087
01088 return !configuration_ || !configView_;
01089 }
01090
01091
01092
01093
01094 bool ConfigurationTree::isLinkNode(void) const
01095 {
01096 return linkColName_ != "";
01097 }
01098
01099
01100
01101
01102 const std::string ConfigurationTree::NODE_TYPE_GROUP_TABLE = "GroupConfigurationNode";
01103 const std::string ConfigurationTree::NODE_TYPE_TABLE = "ConfigurationNode";
01104 const std::string ConfigurationTree::NODE_TYPE_GROUP_LINK = "GroupLinkNode";
01105 const std::string ConfigurationTree::NODE_TYPE_UID_LINK = "UIDLinkNode";
01106 const std::string ConfigurationTree::NODE_TYPE_VALUE = "ValueNode";
01107 const std::string ConfigurationTree::NODE_TYPE_UID = "UIDNode";
01108 const std::string ConfigurationTree::NODE_TYPE_ROOT = "RootNode";
01109
01110 std::string ConfigurationTree::getNodeType(void) const
01111 {
01112 if(!configuration_) return ConfigurationTree::NODE_TYPE_ROOT;
01113 if(isConfigurationNode() && groupId_ != "") return ConfigurationTree::NODE_TYPE_GROUP_TABLE;
01114 if(isConfigurationNode()) return ConfigurationTree::NODE_TYPE_TABLE;
01115 if(isGroupLinkNode()) return ConfigurationTree::NODE_TYPE_GROUP_LINK;
01116 if(isLinkNode()) return ConfigurationTree::NODE_TYPE_UID_LINK;
01117 if(isValueNode()) return ConfigurationTree::NODE_TYPE_VALUE;
01118 return ConfigurationTree::NODE_TYPE_UID;
01119 }
01120
01121
01122
01123
01124 bool ConfigurationTree::isGroupLinkNode(void) const
01125 {
01126 return (isLinkNode() && groupId_ != "");
01127 }
01128
01129
01130
01131
01132 bool ConfigurationTree::isUIDLinkNode(void) const
01133 {
01134 return (isLinkNode() && groupId_ == "");
01135 }
01136
01137
01138
01139
01140 bool ConfigurationTree::isUIDNode(void) const
01141 {
01142 return (row_ != ConfigurationView::INVALID && col_ == ConfigurationView::INVALID);
01143 }
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162 std::vector<ConfigurationTree::RecordField> ConfigurationTree::getCommonFields(
01163 const std::vector<std::string /*uid*/> &recordList,
01164 const std::vector<std::string /*relative-path*/> &fieldAcceptList,
01165 const std::vector<std::string /*relative-path*/> &fieldRejectList,
01166 unsigned int depth) const
01167 {
01168
01169 if(!isRootNode() && !isConfigurationNode())
01170 {
01171 __SS__ << "Can only get getCommonFields from a root or table node! " <<
01172 "The node type is " << getNodeType() << std::endl;
01173 __COUT__ << "\n" << ss.str() << std::endl;
01174 throw std::runtime_error(ss.str());
01175 }
01176
01177 std::vector<ConfigurationTree::RecordField> fieldCandidateList;
01178 std::vector<int> fieldCount;
01179
01180 --depth;
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215 bool found;
01216
01217
01218 for(unsigned int i=0;i<recordList.size();++i)
01219 {
01220
01221
01222 auto recordChildren = getNode(recordList[i]).getChildren();
01223 for(const auto &fieldNode : recordChildren)
01224 {
01225
01226
01227 if(fieldNode.second.isValueNode())
01228 {
01229
01230 if(fieldNode.second.getColumnInfo().getType() ==
01231 ViewColumnInfo::TYPE_AUTHOR ||
01232 fieldNode.second.getColumnInfo().getType() ==
01233 ViewColumnInfo::TYPE_TIMESTAMP)
01234 continue;
01235
01236
01237 if(!i)
01238 {
01239
01240 found = fieldAcceptList.size()?false:true;
01241 for(const auto &fieldFilter : fieldAcceptList)
01242 if(StringMacros::wildCardMatch(
01243 fieldFilter,fieldNode.first))
01244 {
01245 found = true;
01246 break;
01247 }
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277 if(found)
01278 {
01279
01280
01281 found = true;
01282 for(const auto &fieldFilter : fieldRejectList)
01283 if(StringMacros::wildCardMatch(
01284 fieldFilter,fieldNode.first))
01285 {
01286 found = false;
01287 break;
01288 }
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318 }
01319
01320
01321 if(found)
01322 {
01323 fieldCandidateList.push_back(
01324 ConfigurationTree::RecordField(
01325 fieldNode.second.getConfigurationName(),
01326 recordList[i],
01327 fieldNode.first,
01328 "",
01329 &fieldNode.second.getColumnInfo()
01330 ));
01331 fieldCount.push_back(-1);
01332 }
01333 }
01334
01335
01336 }
01337 else if(depth > 0 &&
01338 fieldNode.second.isUIDLinkNode() &&
01339 !fieldNode.second.isDisconnected())
01340 {
01341
01342 fieldNode.second.recursiveGetCommonFields(
01343 fieldCandidateList,
01344 fieldCount,
01345 fieldAcceptList,
01346 fieldRejectList,
01347 depth,
01348 fieldNode.first + "/",
01349 !i
01350 );
01351 }
01352 }
01353
01354 }
01355
01356
01357
01358
01359
01360
01361 for(unsigned int i=0;i<fieldCandidateList.size();++i)
01362 {
01363
01364
01365
01366 if(fieldCount[i] != -1 &&
01367 fieldCount[i] != (int)recordList.size())
01368 {
01369
01370
01371
01372 fieldCount.erase(fieldCount.begin() + i);
01373 fieldCandidateList.erase(fieldCandidateList.begin() + i);
01374 --i;
01375 }
01376 }
01377
01378
01379
01380
01381
01382 return fieldCandidateList;
01383 }
01384
01385
01386
01387
01388
01389
01390 std::set<std::string > ConfigurationTree::getUniqueValuesForField(
01391 const std::vector<std::string /*relative-path*/> &recordList,
01392 const std::string &fieldName) const
01393 {
01394
01395 if(!isConfigurationNode())
01396 {
01397 __SS__ << "Can only get getCommonFields from a table node! " <<
01398 "The node type is " << getNodeType() << std::endl;
01399 __COUT__ << "\n" << ss.str() << std::endl;
01400 throw std::runtime_error(ss.str());
01401 }
01402
01403 std::set<std::string > uniqueValues;
01404
01405
01406
01407
01408
01409
01410 for(unsigned int i=0;i<recordList.size();++i)
01411 {
01412 __COUT__ << "Checking " << recordList[i] << std::endl;
01413
01414
01415
01416
01417
01418
01419
01420 uniqueValues.emplace(getNode(recordList[i]).getNode(fieldName).getValueAsString(true));
01421 }
01422
01423 return uniqueValues;
01424 }
01425
01426
01427
01428
01429 void ConfigurationTree::recursiveGetCommonFields(
01430 std::vector<ConfigurationTree::RecordField> &fieldCandidateList,
01431 std::vector<int> &fieldCount,
01432 const std::vector<std::string /*relative-path*/> &fieldAcceptList,
01433 const std::vector<std::string /*relative-path*/> &fieldRejectList,
01434 unsigned int depth,
01435 const std::string &relativePathBase,
01436 bool inFirstRecord
01437 ) const
01438 {
01439 --depth;
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461 bool found;
01462 auto tableName = getConfigurationName();
01463 auto uid = getUIDAsString();
01464 unsigned int j;
01465
01466 auto recordChildren = getChildren();
01467 for(const auto &fieldNode : recordChildren)
01468 {
01469 if(fieldNode.second.isValueNode())
01470 {
01471
01472 if(fieldNode.second.getColumnInfo().getType() ==
01473 ViewColumnInfo::TYPE_AUTHOR ||
01474 fieldNode.second.getColumnInfo().getType() ==
01475 ViewColumnInfo::TYPE_TIMESTAMP)
01476 continue;
01477
01478
01479 if(inFirstRecord)
01480 {
01481
01482 found = fieldAcceptList.size()?false:true;
01483 for(const auto &fieldFilter : fieldAcceptList)
01484 if(StringMacros::wildCardMatch(
01485 fieldFilter,fieldNode.first))
01486 {
01487 found = true;
01488 break;
01489 }
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520 if(found)
01521 {
01522
01523
01524 found = true;
01525 for(const auto &fieldFilter : fieldRejectList)
01526 if(StringMacros::wildCardMatch(
01527 fieldFilter,fieldNode.first))
01528 {
01529 found = false;
01530 break;
01531 }
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561 }
01562
01563
01564 if(found)
01565 {
01566
01567
01568 fieldCandidateList.push_back(
01569 ConfigurationTree::RecordField(
01570 tableName,
01571 uid,
01572 fieldNode.first,
01573 relativePathBase,
01574 &fieldNode.second.getColumnInfo()
01575 ));
01576 fieldCount.push_back(1);
01577 }
01578 }
01579 else
01580 {
01581
01582
01583 for(j=0;j<fieldCandidateList.size();++j)
01584 {
01585 if((relativePathBase + fieldNode.first) ==
01586 (fieldCandidateList[j].relativePath_ +
01587 fieldCandidateList[j].columnName_))
01588 {
01589
01590
01591
01592 ++fieldCount[j];
01593 break;
01594 }
01595 }
01596 }
01597 }
01598 else if(depth > 0 &&
01599 fieldNode.second.isUIDLinkNode() &&
01600 !fieldNode.second.isDisconnected())
01601 {
01602
01603 fieldNode.second.recursiveGetCommonFields(
01604 fieldCandidateList,
01605 fieldCount,
01606 fieldAcceptList,
01607 fieldRejectList,
01608 depth,
01609 (relativePathBase + fieldNode.first) + "/",
01610 inFirstRecord
01611 );
01612 }
01613 }
01614 }
01615
01616
01617
01618
01619
01620 std::vector<std::pair<std::string,ConfigurationTree> > ConfigurationTree::getChildren(
01621 std::map<std::string /*relative-path*/, std::string /*value*/> filterMap,
01622 bool byPriority) const
01623 {
01624 std::vector<std::pair<std::string,ConfigurationTree> > retVector;
01625
01626
01627
01628 bool filtering = filterMap.size();
01629 bool skip;
01630 std::string fieldValue;
01631
01632 std::vector<std::string> childrenNames = getChildrenNames(byPriority);
01633 for(auto &childName : childrenNames)
01634 {
01635
01636
01637 if(filtering)
01638 {
01639
01640 skip = false;
01641
01642
01643 for(const auto &filterPair:filterMap)
01644 {
01645 std::string filterPath = childName + "/" + filterPair.first;
01646 try
01647 {
01648
01649
01650 std::istringstream f(filterPair.second);
01651
01652 skip = true;
01653
01654 while (getline(f, fieldValue, ','))
01655 {
01656
01657
01658
01659
01660
01661
01662
01663 __COUT__ << "\t\tCheck: " << filterPair.first <<
01664 " == " << fieldValue << " ??? " <<
01665 this->getNode(filterPath).getValueAsString(true) <<
01666 std::endl;
01667
01668 if(StringMacros::wildCardMatch(
01669 StringMacros::decodeURIComponent(fieldValue),
01670 this->getNode(filterPath).getValueAsString(true) ))
01671 {
01672
01673 skip = false;
01674 break;
01675 }
01676
01677
01678
01679
01680
01681
01682
01683
01684 }
01685 }
01686 catch(...)
01687 {
01688 __SS__ << "Failed to access filter path '" <<
01689 filterPath << "' - aborting." << std::endl;
01690 __COUT_ERR__ << "\n" << ss.str();
01691 throw std::runtime_error(ss.str());
01692 }
01693
01694 if(skip) break;
01695 }
01696
01697 if(skip) continue;
01698
01699 __COUT__ << "\tChild accepted: " << childName << std::endl;
01700 }
01701
01702 retVector.push_back(std::pair<std::string,ConfigurationTree>(childName,
01703 this->getNode(childName, true)));
01704 }
01705
01706
01707 return retVector;
01708 }
01709
01714
01715
01716
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748 std::map<std::string,ConfigurationTree> ConfigurationTree::getChildrenMap(void) const
01749 {
01750 std::map<std::string,ConfigurationTree> retMap;
01751
01752
01753
01754 std::vector<std::string> childrenNames = getChildrenNames();
01755 for(auto& childName : childrenNames)
01756 {
01757
01758 retMap.insert(std::pair<std::string,ConfigurationTree>(childName, this->getNode(childName)));
01759 }
01760
01761
01762 return retMap;
01763 }
01764
01765
01766 bool ConfigurationTree::isRootNode(void) const
01767 {
01768 return (!configuration_);
01769 }
01770
01771
01772 bool ConfigurationTree::isConfigurationNode(void) const
01773 {
01774 return (configuration_ &&
01775 row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID);
01776 }
01777
01778
01779
01780
01781 std::vector<std::string> ConfigurationTree::getChildrenNames(bool byPriority) const
01782 {
01783 std::vector<std::string > retVector;
01784
01785 if(!configView_)
01786 {
01787 __SS__ << "Can not get children names of '" <<
01788 getValueAsString() <<
01789 "' with null configuration view pointer!" << std::endl;
01790 if(isLinkNode() && isDisconnected())
01791 ss << " This node is a disconnected link to " <<
01792 getDisconnectedTableName() << std::endl;
01793
01794 throw std::runtime_error(ss.str());
01795 }
01796
01797 if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
01798 {
01799
01800
01801
01802 if(byPriority)
01803 {
01804 try
01805 {
01806 std::map<uint64_t , std::vector< unsigned int > > orderedByPriority;
01807 std::vector<std::string > retPrioritySet;
01808
01809 unsigned int col = configView_->getColPriority();
01810 uint64_t tmpPriority;
01811
01812 for(unsigned int r = 0; r<configView_->getNumberOfRows(); ++r)
01813 if(groupId_ == "" ||
01814 configView_->isEntryInGroup(r,childLinkIndex_,groupId_))
01815 {
01816 configView_->getValue(tmpPriority,r,col);
01817
01818 orderedByPriority[tmpPriority?tmpPriority:100].push_back(r);
01819 }
01820
01821
01822
01823
01824 for (const auto& priorityChildRowVector : orderedByPriority)
01825 for (const auto& priorityChildRow : priorityChildRowVector.second)
01826 retVector.push_back(configView_->getDataView()[priorityChildRow][configView_->getColUID()]);
01827
01828 __COUT__ << "Returning priority children list." << __E__;
01829 return retVector;
01830 }
01831 catch(std::runtime_error& e)
01832 {
01833 __COUT_WARN__ << "Error identifying priority. Assuming all children have equal priority (Error: " <<
01834 e.what() << __E__;
01835 retVector.clear();
01836 }
01837 }
01838
01839
01840 for(unsigned int r = 0; r<configView_->getNumberOfRows(); ++r)
01841 if(groupId_ == "" ||
01842 configView_->isEntryInGroup(r,childLinkIndex_,groupId_))
01843
01844
01845 retVector.push_back(configView_->getDataView()[r][configView_->getColUID()]);
01846
01847 }
01848 else if(row_ == ConfigurationView::INVALID)
01849 {
01850 __SS__ << "Malformed ConfigurationTree" << std::endl;
01851 __COUT_ERR__ << ss.str();
01852 throw std::runtime_error(ss.str());
01853 }
01854 else if(col_ == ConfigurationView::INVALID)
01855 {
01856
01857
01858
01859 for(unsigned int c = 0; c<configView_->getNumberOfColumns(); ++c)
01860 if(c == configView_->getColUID() ||
01861 configView_->getColumnInfo(c).isChildLinkGroupID() ||
01862 configView_->getColumnInfo(c).isChildLinkUID())
01863 continue;
01864 else
01865 retVector.push_back(configView_->getColumnInfo(c).getName());
01866 }
01867 else
01868 {
01869
01870 __SS__ << "\n\nError occurred looking for children of nodeName=" << getValueName() << "\n\n" <<
01871 "Invalid depth! getChildrenValues() called from a value point in the Configuration Tree." << std::endl;
01872 __COUT_ERR__ << ss.str();
01873 throw std::runtime_error(ss.str());
01874 }
01875
01876 return retVector;
01877 }
01878
01879
01880
01881
01882
01883
01884 ConfigurationTree ConfigurationTree::getValueAsTreeNode(void) const
01885 {
01886
01887
01888
01889 if(!configView_)
01890 {
01891 __SS__ << "Invalid node for get value." << std::endl;
01892 __COUT__ << ss.str();
01893 throw std::runtime_error(ss.str());
01894 }
01895
01896 std::string valueString = configView_->getValueAsString(row_,col_,true );
01897
01898 if(valueString.size() && valueString[0] == '/')
01899 {
01900
01901 try
01902 {
01903 ConfigurationTree retNode = configMgr_->getNode(valueString);
01904 __COUT__ << "Found a valid tree path in value!" << std::endl;
01905 return retNode;
01906 }
01907 catch(...)
01908 {
01909 __SS__ << "Invalid tree path." << std::endl;
01910
01911 throw std::runtime_error(ss.str());
01912 }
01913 }
01914
01915
01916 {
01917 __SS__ << "Invalid value string '" << valueString <<
01918 "' - must start with a '/' character." << std::endl;
01919 throw std::runtime_error(ss.str());
01920 }
01921 }
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932