00001 #ifndef _ots_ConfigurationTree_h_
00002 #define _ots_ConfigurationTree_h_
00003
00004 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationView.h"
00005
00006
00007 #include <iostream>
00008 #include <string>
00009 #include <set>
00010
00011
00012 namespace ots
00013 {
00014
00015 class ConfigurationManager;
00016 class ConfigurationBase;
00017 class ConfigurationView;
00018
00019
00020 template<typename T>
00021 struct identity { typedef T type; };
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 class ConfigurationTree
00039 {
00040 friend class ConfigurationGUISupervisor;
00041 friend class Iterator;
00042
00043 public:
00044
00045
00046
00047
00048 ConfigurationTree ();
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 ConfigurationTree (const ConfigurationManager* const& configMgr, const ConfigurationBase* const &config);
00066 ~ConfigurationTree (void);
00067
00068 ConfigurationTree& operator=(const ConfigurationTree& a)
00069 {
00070 __COUT__ << "OPERATOR= COPY CONSTRUCTOR ConfigManager: " << configMgr_ << " configuration: " << configuration_ << std::endl;
00071
00072
00073
00074 __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00075 __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00076 __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00077 __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00078 __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00079 __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00080 __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00081 exit(0);
00082
00083
00084
00085 configMgr_ = a.configMgr_;
00086 configuration_ = a.configuration_;
00087
00088
00089
00090
00091
00092 configView_ = a.configView_;
00093 __COUT__ << "OPERATOR COPY CONSTRUCTOR" << std::endl;
00094 return *this;
00095 };
00096
00097
00098 static const std::string DISCONNECTED_VALUE;
00099 static const std::string VALUE_TYPE_DISCONNECTED;
00100 static const std::string VALUE_TYPE_NODE;
00101
00102 static const std::string NODE_TYPE_GROUP_TABLE;
00103 static const std::string NODE_TYPE_TABLE;
00104 static const std::string NODE_TYPE_GROUP_LINK;
00105 static const std::string NODE_TYPE_UID_LINK;
00106 static const std::string NODE_TYPE_VALUE;
00107 static const std::string NODE_TYPE_UID;
00108 static const std::string NODE_TYPE_ROOT;
00109
00110 struct BitMap
00111 {
00112 BitMap():isDefault_(true), zero_(0) {}
00113
00114 friend ConfigurationTree;
00115 const uint64_t& get (unsigned int row, unsigned int col) const { return isDefault_?zero_:bitmap_[row][col]; }
00116 unsigned int numberOfRows () const { return bitmap_.size(); }
00117 unsigned int numberOfColumns (unsigned int row) const { return bitmap_[row].size(); }
00118
00119 private:
00120 std::vector<std::vector<uint64_t>> bitmap_;
00121 bool isDefault_;
00122 uint64_t zero_;
00123 };
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 template<class T>
00134 void getValue(T& value) const
00135 {
00136 if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
00137 {
00138
00139 try
00140 {
00141 ConfigurationTree valueAsTreeNode = getValueAsTreeNode();
00142
00143 __COUT__ << "Success following path to tree node!" << std::endl;
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 value = handleValidateValueForColumn(configView_,
00154 valueAsTreeNode.getValueAsString(),col_,identity<T>());
00155
00156 __COUT__ << "Successful value!" << std::endl;
00157 return;
00158 }
00159 catch(...)
00160 {
00161
00162 }
00163
00164
00165 configView_->getValue(value,row_,col_);
00166 }
00167 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
00168 {
00169 __SS__ << "Requesting getValue on config node level. Must be a value node." << std::endl;
00170 __COUT_ERR__ << ss.str();
00171 throw std::runtime_error(ss.str());
00172 }
00173 else if(row_ == ConfigurationView::INVALID)
00174 {
00175 __SS__ << "Malformed ConfigurationTree" << std::endl;
00176 __COUT_ERR__ << ss.str();
00177 throw std::runtime_error(ss.str());
00178 }
00179 else if(col_ == ConfigurationView::INVALID)
00180 {
00181 __SS__ << "Requesting getValue on uid node level. Must be a value node." << std::endl;
00182 __COUT_ERR__ << ss.str();
00183 throw std::runtime_error(ss.str());
00184 }
00185 else
00186 {
00187 __SS__ << "Impossible" << std::endl;
00188 __COUT_ERR__ << ss.str();
00189 throw std::runtime_error(ss.str());
00190 }
00191 }
00192
00193
00194 void getValue (std::string& value) const;
00195 void getValueAsBitMap (ConfigurationTree::BitMap& value) const;
00196
00197
00198
00199
00200
00201 template<class T>
00202 T getValue(void) const
00203 {
00204 T value;
00205 ConfigurationTree::getValue<T>(value);
00206 return value;
00207 }
00208
00209
00210 std::string getValue (void) const;
00211 ConfigurationTree::BitMap getValueAsBitMap (void) const;
00212
00213 private:
00214 template<typename T>
00215 T handleValidateValueForColumn(const ConfigurationView* configView, std::string value, unsigned int col, ots::identity<T>) const
00216 {
00217 if(!configView)
00218 {
00219 __SS__ << "Null configView" << std::endl;
00220 __COUT_ERR__ << ss.str();
00221 throw std::runtime_error(ss.str());
00222 }
00223 std::cout << "210:::::" << "handleValidateValueForColumn<T>" << std::endl;
00224 return configView->validateValueForColumn<T>(
00225 value,col);
00226 }
00227
00228 std::string handleValidateValueForColumn(const ConfigurationView* configView, std::string value, unsigned int col, ots::identity<std::string>) const
00229 {
00230 if(!configView)
00231 {
00232 __SS__ << "Null configView" << std::endl;
00233 __COUT_ERR__ << ss.str();
00234 throw std::runtime_error(ss.str());
00235 }
00236 std::cout << "210:::::" << "handleValidateValueForColumn<string>" << std::endl;
00237 return configView->validateValueForColumn(
00238 value,col);
00239 }
00240
00241 public:
00242
00243
00244 ConfigurationTree getNode (const std::string& nodeName, bool doNotThrowOnBrokenUIDLinks=false) const;
00245 ConfigurationTree getBackNode ( std::string nodeName, unsigned int backSteps=1) const;
00246 ConfigurationTree getForwardNode ( std::string nodeName, unsigned int forwardSteps=1) const;
00247
00248
00249
00250 const ConfigurationManager* getConfigurationManager (void) const { return configMgr_; }
00251 const std::string& getConfigurationName (void) const;
00252 const std::string& getFieldConfigurationName (void) const;
00253 const ConfigurationVersion& getConfigurationVersion (void) const;
00254 const time_t& getConfigurationCreationTime(void) const;
00255 std::vector<std::string> getChildrenNames (bool byPriority = false) const;
00256 std::vector<std::pair<std::string,ConfigurationTree> > getChildren (std::map<std::string /*relative-path*/, std::string /*value*/> filterMap = std::map<std::string /*relative-path*/, std::string /*value*/>(), bool byPriority = false) const;
00257 std::map<std::string,ConfigurationTree> getChildrenMap (void) const;
00258 std::string getEscapedValue (void) const;
00259 const std::string& getValueAsString (bool returnLinkTableValue=false) const;
00260 const std::string& getUIDAsString (void) const;
00261 const std::string& getValueDataType (void) const;
00262 const std::string& getValueType (void) const;
00263 const std::string& getValueName (void) const;
00264 std::string getNodeType (void) const;
00265 const std::string& getDisconnectedTableName (void) const;
00266 const std::string& getDisconnectedLinkID (void) const;
00267 const std::string& getChildLinkIndex (void) const;
00268 std::vector<std::string> getFixedChoices (void) const;
00269
00270 public:
00271
00272
00273
00274 bool isDefaultValue (void) const;
00275 bool isRootNode (void) const;
00276 bool isConfigurationNode (void) const;
00277 bool isValueNode (void) const;
00278 bool isDisconnected (void) const;
00279 bool isLinkNode (void) const;
00280 bool isGroupLinkNode (void) const;
00281 bool isUIDLinkNode (void) const;
00282 bool isUIDNode (void) const;
00283
00284
00285 void print (const unsigned int &depth = -1, std::ostream &out = std::cout) const;
00286
00287
00288 friend std::ostream& operator<< (std::ostream& out, const ConfigurationTree& t)
00289 {
00290 out << t.getValueAsString();
00291 return out;
00292 }
00293
00294 protected:
00295 const unsigned int& getRow (void) const;
00296 const unsigned int& getColumn (void) const;
00297 const unsigned int& getFieldRow (void) const;
00298 const unsigned int& getFieldColumn (void) const;
00299 const ViewColumnInfo& getColumnInfo (void) const;
00300
00301
00302 struct RecordField
00303 {
00304 RecordField(const std::string &table, const std::string &uid,
00305 const std::string &columnName, const std::string &relativePath,
00306 const ViewColumnInfo *columnInfo)
00307 :tableName_(table)
00308 ,columnName_(columnName)
00309 ,relativePath_(relativePath)
00310 ,columnInfo_(columnInfo)
00311 {}
00312
00313 std::string tableName_, columnName_, relativePath_;
00314
00315
00316 const ViewColumnInfo *columnInfo_;
00317 };
00318 std::vector<ConfigurationTree::RecordField> getCommonFields(const std::vector<std::string /*relative-path*/> &recordList, const std::vector<std::string /*relative-path*/> &fieldAcceptList, const std::vector<std::string /*relative-path*/> &fieldRejectList, unsigned int depth = -1) const;
00319 std::set<std::string > getUniqueValuesForField(const std::vector<std::string /*relative-path*/> &recordList, const std::string &fieldName) const;
00320
00321 private:
00322
00323 ConfigurationTree(const ConfigurationManager* const& configMgr, const ConfigurationBase* const& config, const std::string& groupId, const ConfigurationBase* const& linkParentConfig, const std::string &linkColName, const std::string &linkColValue, const unsigned int linkBackRow, const unsigned int linkBackCol, const std::string& disconnectedTargetName, const std::string& disconnectedLinkID, const std::string &childLinkIndex, const unsigned int row = ConfigurationView::INVALID, const unsigned int col = ConfigurationView::INVALID);
00324
00325 static ConfigurationTree recurse (const ConfigurationTree& t, const std::string& childPath, bool doNotThrowOnBrokenUIDLinks);
00326 static void recursivePrint(const ConfigurationTree& t, unsigned int depth, std::ostream &out, std::string space);
00327
00328
00329 void recursiveGetCommonFields(std::vector<ConfigurationTree::RecordField> &fieldCandidateList, std::vector<int> &fieldCount, const std::vector<std::string /*relative-path*/> &fieldAcceptList, const std::vector<std::string /*relative-path*/> &fieldRejectList, unsigned int depth, const std::string &relativePathBase, bool inFirstRecord) const;
00330 ConfigurationTree getValueAsTreeNode (void) const;
00331
00332
00333
00334
00335
00336
00337
00338 const ConfigurationManager* configMgr_;
00339 const ConfigurationBase* configuration_;
00340 const std::string groupId_;
00341 const ConfigurationBase* linkParentConfig_;
00342 const std::string linkColName_;
00343 const std::string linkColValue_;
00344 const unsigned int linkBackRow_;
00345 const unsigned int linkBackCol_;
00346 const std::string disconnectedTargetName_;
00347 const std::string disconnectedLinkID_;
00348 const std::string childLinkIndex_;
00349 const unsigned int row_;
00350 const unsigned int col_;
00351 const ConfigurationView* configView_;
00352
00353 };
00354 }
00355
00356 #endif