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
00042 public:
00043
00044
00045
00046
00047 ConfigurationTree ();
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 ConfigurationTree (const ConfigurationManager* const& configMgr, const ConfigurationBase* const &config);
00065 ~ConfigurationTree (void);
00066
00067 ConfigurationTree& operator=(const ConfigurationTree& a)
00068 {
00069 std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR ConfigManager: " << configMgr_ << " configuration: " << configuration_ << std::endl;
00070
00071
00072
00073 std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00074 std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00075 std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00076 std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00077 std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00078 std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00079 std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
00080 exit(0);
00081
00082
00083
00084 configMgr_ = a.configMgr_;
00085 configuration_ = a.configuration_;
00086
00087
00088
00089
00090
00091 configView_ = a.configView_;
00092 std::cout << __PRETTY_FUNCTION__ << "OPERATOR COPY CONSTRUCTOR" << std::endl;
00093 return *this;
00094 };
00095
00096
00097 static const std::string DISCONNECTED_VALUE;
00098 static const std::string VALUE_TYPE_DISCONNECTED;
00099 static const std::string VALUE_TYPE_NODE;
00100
00101 static const std::string NODE_TYPE_GROUP_TABLE;
00102 static const std::string NODE_TYPE_TABLE;
00103 static const std::string NODE_TYPE_GROUP_LINK;
00104 static const std::string NODE_TYPE_UID_LINK;
00105 static const std::string NODE_TYPE_VALUE;
00106 static const std::string NODE_TYPE_UID;
00107
00108
00109
00110
00111
00112
00113
00114
00115 template<class T>
00116 void getValue(T& value) const
00117 {
00118 if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID)
00119 {
00120
00121 try
00122 {
00123 ConfigurationTree valueAsTreeNode = getValueAsTreeNode();
00124
00125 __COUT__ << "Success following path to tree node!" << std::endl;
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 value = handleValidateValueForColumn(configView_,
00136 valueAsTreeNode.getValueAsString(),col_,identity<T>());
00137
00138 __COUT__ << "Successful value!" << std::endl;
00139 return;
00140 }
00141 catch(...)
00142 {
00143
00144 }
00145
00146
00147 configView_->getValue(value,row_,col_);
00148 }
00149 else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID)
00150 {
00151 __SS__ << "Requesting getValue on config node level. Must be a value node." << std::endl;
00152 __COUT_ERR__ << ss.str();
00153 throw std::runtime_error(ss.str());
00154 }
00155 else if(row_ == ConfigurationView::INVALID)
00156 {
00157 __SS__ << "Malformed ConfigurationTree" << std::endl;
00158 __COUT_ERR__ << ss.str();
00159 throw std::runtime_error(ss.str());
00160 }
00161 else if(col_ == ConfigurationView::INVALID)
00162 {
00163 __SS__ << "Requesting getValue on uid node level. Must be a value node." << std::endl;
00164 __COUT_ERR__ << ss.str();
00165 throw std::runtime_error(ss.str());
00166 }
00167 else
00168 {
00169 __SS__ << "Impossible" << std::endl;
00170 __COUT_ERR__ << ss.str();
00171 throw std::runtime_error(ss.str());
00172 }
00173 }
00174
00175
00176 void getValue (std::string& value) const;
00177
00178
00179
00180
00181
00182 template<class T>
00183 T getValue(void) const
00184 {
00185 T value;
00186 ConfigurationTree::getValue<T>(value);
00187 return value;
00188 }
00189
00190
00191 std::string getValue (void) const;
00192
00193 private:
00194 template<typename T>
00195 T handleValidateValueForColumn(const ConfigurationView* configView, std::string value, unsigned int col, ots::identity<T>) const
00196 {
00197 if(!configView)
00198 {
00199 __SS__ << "Null configView" << std::endl;
00200 __COUT_ERR__ << ss.str();
00201 throw std::runtime_error(ss.str());
00202 }
00203 std::cout << "210:::::" << "handleValidateValueForColumn<T>" << std::endl;
00204 return configView->validateValueForColumn<T>(
00205 value,col);
00206 }
00207
00208 std::string handleValidateValueForColumn(const ConfigurationView* configView, std::string value, unsigned int col, ots::identity<std::string>) const
00209 {
00210 if(!configView)
00211 {
00212 __SS__ << "Null configView" << std::endl;
00213 __COUT_ERR__ << ss.str();
00214 throw std::runtime_error(ss.str());
00215 }
00216 std::cout << "210:::::" << "handleValidateValueForColumn<string>" << std::endl;
00217 return configView->validateValueForColumn(
00218 value,col);
00219 }
00220
00221 public:
00222
00223
00224 ConfigurationTree getNode (const std::string& nodeName, bool doNotThrowOnBrokenUIDLinks=false) const;
00225 ConfigurationTree getBackNode ( std::string nodeName, unsigned int backSteps=1) const;
00226
00227
00228
00229 const std::string& getConfigurationName (void) const;
00230 const std::string& getFieldConfigurationName (void) const;
00231 const ConfigurationVersion& getConfigurationVersion (void) const;
00232 const time_t& getConfigurationCreationTime(void) const;
00233 std::vector<std::string> getChildrenNames (void) const;
00234 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;
00235 std::map<std::string,ConfigurationTree> getChildrenMap (void) const;
00236 std::string getEscapedValue (void) const;
00237 const std::string& getValueAsString (bool returnLinkTableValue=false) const;
00238 const std::string& getUIDAsString (void) const;
00239 const std::string& getValueDataType (void) const;
00240 const std::string& getValueType (void) const;
00241 const std::string& getValueName (void) const;
00242 std::string getNodeType (void) const;
00243 const std::string& getDisconnectedTableName (void) const;
00244 const std::string& getDisconnectedLinkID (void) const;
00245 const std::string& getChildLinkIndex (void) const;
00246 std::vector<std::string> getFixedChoices (void) const;
00247
00248 public:
00249
00250
00251
00252 bool isDefaultValue (void) const;
00253 bool isConfigurationNode (void) const;
00254 bool isValueNode (void) const;
00255 bool isDisconnected (void) const;
00256 bool isLinkNode (void) const;
00257 bool isGroupLinkNode (void) const;
00258 bool isUIDLinkNode (void) const;
00259 bool isUIDNode (void) const;
00260
00261
00262 void print (const unsigned int &depth = -1, std::ostream &out = std::cout) const;
00263
00264
00265 friend std::ostream& operator<< (std::ostream& out, const ConfigurationTree& t)
00266 {
00267 out << t.getValueAsString();
00268 return out;
00269 }
00270
00271 protected:
00272 const unsigned int& getRow (void) const;
00273 const unsigned int& getColumn (void) const;
00274 const unsigned int& getFieldRow (void) const;
00275 const unsigned int& getFieldColumn (void) const;
00276 const ViewColumnInfo& getColumnInfo (void) const;
00277
00278
00279 struct RecordField
00280 {
00281 RecordField(const std::string &table, const std::string &uid,
00282 const std::string &columnName, const std::string &relativePath,
00283 const ViewColumnInfo *columnInfo)
00284 :tableName_(table)
00285 ,columnName_(columnName)
00286 ,relativePath_(relativePath)
00287 ,columnInfo_(columnInfo)
00288 {}
00289
00290 std::string tableName_, columnName_, relativePath_;
00291
00292
00293 const ViewColumnInfo *columnInfo_;
00294 };
00295 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;
00296 std::set<std::string > getUniqueValuesForField(const std::vector<std::string /*relative-path*/> &recordList, const std::string &fieldName) const;
00297
00298 private:
00299
00300 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);
00301
00302 static ConfigurationTree recurse (const ConfigurationTree& t, const std::string& childPath, bool doNotThrowOnBrokenUIDLinks);
00303 static void recursivePrint(const ConfigurationTree& t, unsigned int depth, std::ostream &out, std::string space);
00304 static bool wildCardMatch (const std::string& needle, const std::string& haystack);
00305
00306 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;
00307 ConfigurationTree getValueAsTreeNode (void) const;
00308
00309
00310
00311
00312
00313
00314
00315 const ConfigurationManager* configMgr_;
00316 const ConfigurationBase* configuration_;
00317 const std::string groupId_;
00318 const ConfigurationBase* linkParentConfig_;
00319 const std::string linkColName_;
00320 const std::string linkColValue_;
00321 const unsigned int linkBackRow_;
00322 const unsigned int linkBackCol_;
00323 const std::string disconnectedTargetName_;
00324 const std::string disconnectedLinkID_;
00325 const std::string childLinkIndex_;
00326 const unsigned int row_;
00327 const unsigned int col_;
00328 const ConfigurationView* configView_;
00329
00330 };
00331 }
00332
00333 #endif