otsdaq  v1_01_03
 All Classes Namespaces Functions
ConfigurationTree.h
1 #ifndef _ots_ConfigurationTree_h_
2 #define _ots_ConfigurationTree_h_
3 
4 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationView.h"
5 
6 
7 #include <iostream> // std::cout
8 #include <string>
9 #include <set>
10 
11 
12 namespace ots
13 {
14 
15 class ConfigurationManager;
16 class ConfigurationBase;
17 class ConfigurationView;
18 
19 
20 template<typename T>
21 struct identity { typedef T type; };
22 
23 
24 //
25 //template <class T> T handleValidateValueForColumn (ConfigurationView* configView, std::string value, unsigned int col)
26 //{
27 // std::cout << "22:::::" << "handleValidateValueForColumn<T>" << std::endl;
28 // return configView->validateValueForColumn<T>(
29 // value,col);
30 //}
31 //template <> std::string handleValidateValueForColumn<std::string>(ConfigurationView* configView, std::string value, unsigned int col)
32 //{
33 // std::cout << "22:::::" << "handleValidateValueForColumn<std::string>" << std::endl;
34 // return configView->validateValueForColumn(
35 // value,col);
36 //}
37 
39 {
40  friend class ConfigurationGUISupervisor;
41 
42 public:
43  //Note: due to const members, implicit copy constructor exists, but NOT assignment operator=
44  // ... so ConfigurationTree t = mytree.GetNode(nodeString); //ok
45  // ... or ConfigurationTree t(mytree.GetNode(nodeString)); //ok
46  // ... but mytree = mytree.GetNode(nodeString); //does NOT work
48 // ConfigurationTree(const ConfigurationTree& a)
49 // :
50 // configMgr_ (a.configMgr_),
51 // configuration_ (a.configuration_),
52 // groupId_ (a.groupId_),
53 // linkColName_ (a.linkColName_),
54 // disconnectedTargetName_ (a.disconnectedTargetName_),
55 // childLinkIndex_ (a.childLinkIndex_),
56 // row_ (a.row_),
57 // col_ (a.col_),
58 // configView_ (a.configView_)
59 // {
60 // std::cout << __PRETTY_FUNCTION__ << std::endl;
61 // //return *this;
62 // }
63 
64  ConfigurationTree (const ConfigurationManager* const& configMgr, const ConfigurationBase* const &config);
65  ~ConfigurationTree (void);
66 
67  ConfigurationTree& operator=(const ConfigurationTree& a)
68  {
69  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR ConfigManager: " << configMgr_ << " configuration: " << configuration_ << std::endl;
70  //Note: Members of the ConfigurationTree are declared constant.
71  // (Refer to comments at top of class declaration for solutions)
72  // So this operator cannot work.. SO I am going to crash just in case it is called by mistake
73  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
74  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
75  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
76  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
77  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
78  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
79  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
80  exit(0);
81 
82  //copy to const members is not allowed.. but would look like this:
83 
84  configMgr_ = a.configMgr_;
85  configuration_ = a.configuration_;
86  //groupId_ = a.groupId_;
87  //linkColName_ = a.linkColName_;
88  //childLinkIndex_ = a.childLinkIndex_;
89  //row_ = a.row_;
90  //col_ = a.col_;
91  configView_ = a.configView_;
92  std::cout << __PRETTY_FUNCTION__ << "OPERATOR COPY CONSTRUCTOR" << std::endl;
93  return *this;
94  };
95 
96 
97  static const std::string DISCONNECTED_VALUE;
98  static const std::string VALUE_TYPE_DISCONNECTED;
99  static const std::string VALUE_TYPE_NODE;
100 
101  static const std::string NODE_TYPE_GROUP_TABLE;
102  static const std::string NODE_TYPE_TABLE;
103  static const std::string NODE_TYPE_GROUP_LINK;
104  static const std::string NODE_TYPE_UID_LINK;
105  static const std::string NODE_TYPE_VALUE;
106  static const std::string NODE_TYPE_UID;
107 
108 
109  //Methods
110 
111 
112  //==============================================================================
113  //getValue (not std::string value)
114  // throw exception unless it value node
115  template<class T>
116  void getValue(T& value) const
117  {
118  if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID) //this node is a value node
119  {
120  //attempt to interpret the value as a tree node path itself
121  try
122  {
123  ConfigurationTree valueAsTreeNode = getValueAsTreeNode();
124  //valueAsTreeNode.getValue<T>(value);
125  __MOUT__ << "Success following path to tree node!" << std::endl;
126  //value has been interpreted as a tree node value
127  //now verify result under the rules of this column
128 // if(typeid(std::string) == typeid(value) ||
129 // typeid(std::basic_string<char>) == typeid(value))
130 // value = configView_->validateValueForColumn(
131 // valueAsTreeNode.getValueAsString(),col_);
132 // else
133  // value = (T)configView_->validateValueForColumn<T>(
134  // valueAsTreeNode.getValueAsString(),col_);
135  value = handleValidateValueForColumn(configView_,
136  valueAsTreeNode.getValueAsString(),col_,identity<T>());
137 
138  __MOUT__ << "Successful value!" << std::endl;
139  return;
140  }
141  catch(...) //tree node path interpretation failed
142  {
143  //__MOUT__ << "Invalid path, just returning normal value." << std::endl;
144  }
145 
146  //else normal return
147  configView_->getValue(value,row_,col_);
148  }
149  else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID) //this node is config node maybe with groupId
150  throw std::runtime_error("Requesting getValue on config node level. Must be a value node.");
151  else if(row_ == ConfigurationView::INVALID)
152  {
153  std::cout << __COUT_HDR_FL__ << std::endl;
154  throw std::runtime_error("Malformed ConfigurationTree");
155  }
156  else if(col_ == ConfigurationView::INVALID) //this node is uid node
157  throw std::runtime_error("Requesting getValue on uid node level. Must be a value node.");
158  else
159  {
160  std::cout << __COUT_HDR_FL__ << std::endl;
161  throw std::runtime_error("Impossible");
162  }
163  }
164  //special version of getValue for string type
165  // Note: necessary because types of std::basic_string<char> cause compiler problems if no string specific function
166  void getValue (std::string& value) const;
167 
168 
169  //==============================================================================
170  //getValue (not std::string value)
171  // throw exception unless it value node
172  template<class T>
173  T getValue(void) const
174  {
175  T value;
176 // if(typeid(std::basic_string<char>) == typeid(value) ||
177 // typeid(std::string) == typeid(value))
178 // {
179 // std::string stringValue;
180 // ConfigurationTree::getValue(stringValue);
181 // return stringValue;
182 // }
183 // else
184  ConfigurationTree::getValue<T>(value);
185  return value;
186 // if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID) //this node is a value node
187 // {
188 // configView_->getValue(value,row_,col_);
189 // return value;
190 // }
191 // else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID) //this node is config node maybe with groupId
192 // throw std::runtime_error("Requesting getValue on config node level. Must be a value node.");
193 // else if(row_ == ConfigurationView::INVALID)
194 // {
195 // std::cout << __COUT_HDR_FL__ << std::endl;
196 // throw std::runtime_error("Malformed ConfigurationTree");
197 // }
198 // else if(col_ == ConfigurationView::INVALID) //this node is uid node
199 // throw std::runtime_error("Requesting getValue on uid node level. Must be a value node.");
200 // else
201 // {
202 // std::cout << __COUT_HDR_FL__ << std::endl;
203 // throw std::runtime_error("Impossible");
204 // }
205  }
206  //special version of getValue for string type
207  // Note: necessary because types of std::basic_string<char> cause compiler problems if no string specific function
208  std::string getValue (void) const;
209 
210 private:
211  template<typename T>
212  T handleValidateValueForColumn(const ConfigurationView* configView, std::string value, unsigned int col, ots::identity<T>) const
213  {
214  if(!configView)
215  {
216  __SS__ << "Null configView" << std::endl;
217  __MOUT_ERR__ << ss.str();
218  throw std::runtime_error(ss.str());
219  }
220  std::cout << "210:::::" << "handleValidateValueForColumn<T>" << std::endl;
221  return configView->validateValueForColumn<T>(
222  value,col);
223  }
224 
225  std::string handleValidateValueForColumn(const ConfigurationView* configView, std::string value, unsigned int col, ots::identity<std::string>) const
226  {
227  if(!configView)
228  {
229  __SS__ << "Null configView" << std::endl;
230  __MOUT_ERR__ << ss.str();
231  throw std::runtime_error(ss.str());
232  }
233  std::cout << "210:::::" << "handleValidateValueForColumn<string>" << std::endl;
234  return configView->validateValueForColumn(
235  value,col);
236  }
237 
238 public:
239 
240  //navigating between nodes
241  ConfigurationTree getNode (const std::string& nodeName, bool doNotThrowOnBrokenUIDLinks=false) const;
242  ConfigurationTree getBackNode ( std::string nodeName, unsigned int backSteps=1) const;
243 
244 
245  //extracting information from node
246  const std::string& getConfigurationName (void) const;
247  const ConfigurationVersion& getConfigurationVersion (void) const;
248  const time_t& getConfigurationCreationTime(void) const;
249  std::vector<std::string> getChildrenNames (void) const;
250  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;
251  std::map<std::string,ConfigurationTree> getChildrenMap (void) const;
252  std::string getEscapedValue (void) const;
253  const std::string& getValueAsString (bool returnLinkTableValue=false) const;
254  const std::string& getUIDAsString (void) const;
255  const std::string& getValueDataType (void) const;
256  const std::string& getValueType (void) const;
257  const std::string& getValueName (void) const;
258  std::string getNodeType (void) const;
259  const std::string& getDisconnectedTableName (void) const;
260  const std::string& getDisconnectedLinkID (void) const;
261  const std::string& getChildLinkIndex (void) const;
262  std::vector<std::string> getFixedChoices (void) const;
263 
264 public:
265 
266 
267  //boolean info
268  bool isDefaultValue (void) const;
269  bool isConfigurationNode (void) const;
270  bool isValueNode (void) const;
271  bool isDisconnected (void) const;
272  bool isLinkNode (void) const;
273  bool isGroupLinkNode (void) const;
274  bool isUIDLinkNode (void) const;
275  bool isUIDNode (void) const;
276 
277 
278  void print (const unsigned int &depth = -1, std::ostream &out = std::cout) const;
279 
280  //make stream output easy
281  friend std::ostream& operator<< (std::ostream& out, const ConfigurationTree& t)
282  {
283  out << t.getValueAsString();
284  return out;
285  }
286 
287 protected:
288  const unsigned int& getRow (void) const;
289  const unsigned int& getColumn (void) const;
290  const ViewColumnInfo& getColumnInfo (void) const;
291 
292  //extracting information from a list of records
293  struct RecordField
294  {
295  RecordField(const std::string &table, const std::string &uid,
296  const std::string &columnName, const std::string &relativePath,
297  const ViewColumnInfo *columnInfo)
298  :tableName_(table)
299  ,columnName_(columnName)
300  ,relativePath_(relativePath)
301  ,columnInfo_(columnInfo)
302  {}
303 
304  std::string tableName_, columnName_, relativePath_;
305  //relativePath_ is relative to record uid node, not including columnName_
306 
307  const ViewColumnInfo *columnInfo_;
308  };
309  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;
310  std::set<std::string /*unique-value*/> getUniqueValuesForField(const std::vector<std::string /*relative-path*/> &recordList, const std::string &fieldName) const;
311 
312 private:
313  //privately ONLY allow full access to member variables through constructor
314  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 std::string& disconnectedTargetName, const std::string& disconnectedLinkID, const std::string &childLinkIndex, const unsigned int row = ConfigurationView::INVALID, const unsigned int col = ConfigurationView::INVALID);
315 
316  static ConfigurationTree recurse (const ConfigurationTree& t, const std::string& childPath, bool doNotThrowOnBrokenUIDLinks);
317  static void recursivePrint(const ConfigurationTree& t, unsigned int depth, std::ostream &out, std::string space);
318  static bool wildCardMatch (const std::string& needle, const std::string& haystack);
319 
320  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;
321  ConfigurationTree getValueAsTreeNode (void) const;
322 
323  //Any given ConfigurationTree is either a config, uid, or value node:
324  // - config node is a pointer to a config table
325  // - uid node is a pointer to a row in a config table
326  // - value node is a pointer to a cell in a config table
327  //
328  //Assumption: uid column is present
329  const ConfigurationManager* configMgr_;
330  const ConfigurationBase* configuration_; //config node
331  const std::string groupId_; //group config node
332  const ConfigurationBase* linkParentConfig_; //link node parent config pointer (could be used to traverse backwards through tree)
333  const std::string linkColName_; //link node field name
334  const std::string linkColValue_; //link node field value
335  const std::string disconnectedTargetName_; //only used if disconnected to determine target table name
336  const std::string disconnectedLinkID_; //only used if disconnected to determine target link ID
337  const std::string childLinkIndex_;//child link index
338  const unsigned int row_; //uid node
339  const unsigned int col_; //value node
340  const ConfigurationView* configView_;
341 
342 };
343 }
344 
345 #endif