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
00111
00112
00113
00114
00115
00116
00117 template<class T>
00118 void getValue(T& value) const
00119 {
00120 if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
00121 {
00122
00123 try
00124 {
00125 ConfigurationTree valueAsTreeNode = getValueAsTreeNode();
00126
00127 __COUT__ << "Success following path to tree node!" << std::endl;
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 value = handleValidateValueForColumn(configView_,
00138 valueAsTreeNode.getValueAsString(),col_,identity<T>());
00139
00140 __COUT__ << "Successful value!" << std::endl;
00141 return;
00142 }
00143 catch(...)
00144 {
00145
00146 }
00147
00148
00149 configView_->getValue(value,row_,col_);
00150 }
00151 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
00152 {
00153 __SS__ << "Requesting getValue on config node level. Must be a value node." << std::endl;
00154 __COUT_ERR__ << ss.str();
00155 throw std::runtime_error(ss.str());
00156 }
00157 else if(row_ == ConfigurationView::INVALID)
00158 {
00159 __SS__ << "Malformed ConfigurationTree" << std::endl;
00160 __COUT_ERR__ << ss.str();
00161 throw std::runtime_error(ss.str());
00162 }
00163 else if(col_ == ConfigurationView::INVALID)
00164 {
00165 __SS__ << "Requesting getValue on uid node level. Must be a value node." << std::endl;
00166 __COUT_ERR__ << ss.str();
00167 throw std::runtime_error(ss.str());
00168 }
00169 else
00170 {
00171 __SS__ << "Impossible" << std::endl;
00172 __COUT_ERR__ << ss.str();
00173 throw std::runtime_error(ss.str());
00174 }
00175 }
00176
00177
00178 void getValue (std::string& value) const;
00179
00180
00181
00182
00183
00184 template<class T>
00185 T getValue(void) const
00186 {
00187 T value;
00188 ConfigurationTree::getValue<T>(value);
00189 return value;
00190 }
00191
00192
00193 std::string getValue (void) const;
00194
00195 private:
00196 template<typename T>
00197 T handleValidateValueForColumn(const ConfigurationView* configView, std::string value, unsigned int col, ots::identity<T>) const
00198 {
00199 if(!configView)
00200 {
00201 __SS__ << "Null configView" << std::endl;
00202 __COUT_ERR__ << ss.str();
00203 throw std::runtime_error(ss.str());
00204 }
00205 std::cout << "210:::::" << "handleValidateValueForColumn<T>" << std::endl;
00206 return configView->validateValueForColumn<T>(
00207 value,col);
00208 }
00209
00210 std::string handleValidateValueForColumn(const ConfigurationView* configView, std::string value, unsigned int col, ots::identity<std::string>) const
00211 {
00212 if(!configView)
00213 {
00214 __SS__ << "Null configView" << std::endl;
00215 __COUT_ERR__ << ss.str();
00216 throw std::runtime_error(ss.str());
00217 }
00218 std::cout << "210:::::" << "handleValidateValueForColumn<string>" << std::endl;
00219 return configView->validateValueForColumn(
00220 value,col);
00221 }
00222
00223 public:
00224
00225
00226 ConfigurationTree getNode (const std::string& nodeName, bool doNotThrowOnBrokenUIDLinks=false) const;
00227 ConfigurationTree getBackNode ( std::string nodeName, unsigned int backSteps=1) const;
00228 ConfigurationTree getForwardNode ( std::string nodeName, unsigned int forwardSteps=1) const;
00229
00230
00231
00232 const ConfigurationManager* getConfigurationManager (void) const { return configMgr_; }
00233 const std::string& getConfigurationName (void) const;
00234 const std::string& getFieldConfigurationName (void) const;
00235 const ConfigurationVersion& getConfigurationVersion (void) const;
00236 const time_t& getConfigurationCreationTime(void) const;
00237 std::vector<std::string> getChildrenNames (void) const;
00238 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*/>()) const;
00239 std::map<std::string,ConfigurationTree> getChildrenMap (void) const;
00240 std::string getEscapedValue (void) const;
00241 const std::string& getValueAsString (bool returnLinkTableValue=false) const;
00242 const std::string& getUIDAsString (void) const;
00243 const std::string& getValueDataType (void) const;
00244 const std::string& getValueType (void) const;
00245 const std::string& getValueName (void) const;
00246 std::string getNodeType (void) const;
00247 const std::string& getDisconnectedTableName (void) const;
00248 const std::string& getDisconnectedLinkID (void) const;
00249 const std::string& getChildLinkIndex (void) const;
00250 std::vector<std::string> getFixedChoices (void) const;
00251
00252 public:
00253
00254
00255
00256 bool isDefaultValue (void) const;
00257 bool isRootNode (void) const;
00258 bool isConfigurationNode (void) const;
00259 bool isValueNode (void) const;
00260 bool isDisconnected (void) const;
00261 bool isLinkNode (void) const;
00262 bool isGroupLinkNode (void) const;
00263 bool isUIDLinkNode (void) const;
00264 bool isUIDNode (void) const;
00265
00266
00267 void print (const unsigned int &depth = -1, std::ostream &out = std::cout) const;
00268
00269
00270 friend std::ostream& operator<< (std::ostream& out, const ConfigurationTree& t)
00271 {
00272 out << t.getValueAsString();
00273 return out;
00274 }
00275
00276 protected:
00277 const unsigned int& getRow (void) const;
00278 const unsigned int& getColumn (void) const;
00279 const unsigned int& getFieldRow (void) const;
00280 const unsigned int& getFieldColumn (void) const;
00281 const ViewColumnInfo& getColumnInfo (void) const;
00282
00283
00284 struct RecordField
00285 {
00286 RecordField(const std::string &table, const std::string &uid,
00287 const std::string &columnName, const std::string &relativePath,
00288 const ViewColumnInfo *columnInfo)
00289 :tableName_(table)
00290 ,columnName_(columnName)
00291 ,relativePath_(relativePath)
00292 ,columnInfo_(columnInfo)
00293 {}
00294
00295 std::string tableName_, columnName_, relativePath_;
00296
00297
00298 const ViewColumnInfo *columnInfo_;
00299 };
00300 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;
00301 std::set<std::string > getUniqueValuesForField(const std::vector<std::string /*relative-path*/> &recordList, const std::string &fieldName) const;
00302
00303 private:
00304
00305 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);
00306
00307 static ConfigurationTree recurse (const ConfigurationTree& t, const std::string& childPath, bool doNotThrowOnBrokenUIDLinks);
00308 static void recursivePrint(const ConfigurationTree& t, unsigned int depth, std::ostream &out, std::string space);
00309 static bool wildCardMatch (const std::string& needle, const std::string& haystack);
00310
00311 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;
00312 ConfigurationTree getValueAsTreeNode (void) const;
00313
00314
00315
00316
00317
00318
00319
00320 const ConfigurationManager* configMgr_;
00321 const ConfigurationBase* configuration_;
00322 const std::string groupId_;
00323 const ConfigurationBase* linkParentConfig_;
00324 const std::string linkColName_;
00325 const std::string linkColValue_;
00326 const unsigned int linkBackRow_;
00327 const unsigned int linkBackCol_;
00328 const std::string disconnectedTargetName_;
00329 const std::string disconnectedLinkID_;
00330 const std::string childLinkIndex_;
00331 const unsigned int row_;
00332 const unsigned int col_;
00333 const ConfigurationView* configView_;
00334
00335 };
00336 }
00337
00338 #endif