otsdaq  v2_04_02
ConfigurationTree.h
1 #ifndef _ots_ConfigurationTree_h_
2 #define _ots_ConfigurationTree_h_
3 
4 #include "otsdaq/TableCore/TableView.h"
5 
6 namespace ots
7 {
8 class ConfigurationManager;
9 class TableBase;
10 
11 template<typename T>
12 struct identity
13 {
14  typedef T type;
15 };
16 
18 {
19  friend class ConfigurationGUISupervisor;
20  friend class Iterator;
21 
22  // clang-format off
23  public:
24  // Note: due to const members, implicit copy constructor exists, but NOT assignment
25  // operator=
26  // ... so ConfigurationTree t = mytree.GetNode(nodeString); //OK
27  // ... or ConfigurationTree t(mytree.GetNode(nodeString)); //OK
28  // ... but mytree = mytree.GetNode(nodeString); //does NOT work
30  // ConfigurationTree(const ConfigurationTree& a)
31  // :
32  // configMgr_ (a.configMgr_),
33  // table_ (a.table_),
34  // groupId_ (a.groupId_),
35  // linkColName_ (a.linkColName_),
36  // disconnectedTargetName_ (a.disconnectedTargetName_),
37  // childLinkIndex_ (a.childLinkIndex_),
38  // row_ (a.row_),
39  // col_ (a.col_),
40  // tableView_ (a.tableView_)
41  // {
42  // __COUT__ << std::endl;
43  // //return *this;
44  // }
45 
46  ConfigurationTree(const ConfigurationManager* const& configMgr,
47  const TableBase* const& config);
48  ~ConfigurationTree(void);
49 
50  ConfigurationTree& operator=(const ConfigurationTree& a)
51  {
52  __COUT__ << "OPERATOR= COPY CONSTRUCTOR ConfigManager: " << configMgr_
53  << " configuration: " << table_ << std::endl;
54  // Note: Members of the ConfigurationTree are declared constant.
55  // (Refer to comments at top of class declaration for solutions)
56  // So this operator cannot work.. SO I am going to crash just in case it is
57  // called by mistake
58  __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - ConfigurationTree is a "
59  "const class. SO YOUR CODE IS WRONG! You should probably instantiate "
60  "and initialize another ConfigurationTree, rather than assigning to "
61  "an existing ConfigurationTree. Crashing now."
62  << std::endl;
63  __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - ConfigurationTree is a "
64  "const class. SO YOUR CODE IS WRONG! You should probably instantiate "
65  "and initialize another ConfigurationTree, rather than assigning to "
66  "an existing ConfigurationTree. Crashing now."
67  << std::endl;
68  __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - ConfigurationTree is a "
69  "const class. SO YOUR CODE IS WRONG! You should probably instantiate "
70  "and initialize another ConfigurationTree, rather than assigning to "
71  "an existing ConfigurationTree. Crashing now."
72  << std::endl;
73  __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - ConfigurationTree is a "
74  "const class. SO YOUR CODE IS WRONG! You should probably instantiate "
75  "and initialize another ConfigurationTree, rather than assigning to "
76  "an existing ConfigurationTree. Crashing now."
77  << std::endl;
78  __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - ConfigurationTree is a "
79  "const class. SO YOUR CODE IS WRONG! You should probably instantiate "
80  "and initialize another ConfigurationTree, rather than assigning to "
81  "an existing ConfigurationTree. Crashing now."
82  << std::endl;
83  __COUT__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - ConfigurationTree is a "
84  "const class. SO YOUR CODE IS WRONG! You should probably instantiate "
85  "and initialize another ConfigurationTree, rather than assigning to "
86  "an existing ConfigurationTree. Crashing now."
87  << std::endl;
88 
89  StringMacros::stackTrace();
90  exit(0);
91 
92  // copy to const members is not allowed.. but would look like this:
93 
94  configMgr_ = a.configMgr_;
95  table_ = a.table_;
96  // groupId_ = a.groupId_;
97  // linkColName_ = a.linkColName_;
98  // childLinkIndex_ = a.childLinkIndex_;
99  // row_ = a.row_;
100  // col_ = a.col_;
101  tableView_ = a.tableView_;
102  __COUT__ << "OPERATOR COPY CONSTRUCTOR" << std::endl;
103  return *this;
104  };
105 
106  static const std::string DISCONNECTED_VALUE;
107  static const std::string VALUE_TYPE_DISCONNECTED;
108  static const std::string VALUE_TYPE_NODE;
109 
110  static const std::string NODE_TYPE_GROUP_TABLE;
111  static const std::string NODE_TYPE_TABLE;
112  static const std::string NODE_TYPE_GROUP_LINK;
113  static const std::string NODE_TYPE_UID_LINK;
114  static const std::string NODE_TYPE_VALUE;
115  static const std::string NODE_TYPE_UID;
116  static const std::string NODE_TYPE_ROOT;
117 
118  static const std::string ROOT_NAME;
119 
120  struct BitMap
121  {
122  BitMap() : isDefault_(true), zero_(0) {}
123 
124  friend ConfigurationTree; // so ConfigurationTree can access private
125  const uint64_t& get(unsigned int row, unsigned int col) const
126  {
127  return isDefault_ ? zero_ : bitmap_[row][col];
128  }
129  unsigned int numberOfRows() const { return bitmap_.size(); }
130  unsigned int numberOfColumns(unsigned int row) const
131  {
132  return bitmap_[row].size();
133  }
134 
135  private:
136  std::vector<std::vector<uint64_t>> bitmap_;
137  bool isDefault_; // when default always return 0
138  uint64_t zero_;
139  };
140 
141  // Methods
142 
143  //==============================================================================
144  // getValue (not std::string value)
145  // throw exception unless it value node
146  // NOTE: can not overload functions based on return type, so T& passed as value
147  template<class T>
148  void getValue (T& value) const; // defined in included .icc source
149  // special version of getValue for string type
150  // Note: necessary because types of std::basic_string<char> cause compiler problems
151  // if no string specific function
152  void getValue (std::string& value) const;
153  void getValueAsBitMap (ConfigurationTree::BitMap& value) const;
154 
155  //==============================================================================
156  // getValue (not std::string value)
157  // throw exception unless it value node
158  // NOTE: can not overload functions based on return type, so calls function with T&
159  // passed as value
160  template<class T>
161  T getValue (void) const; // defined in included .icc source
162  // special version of getValue for string type
163  // Note: necessary because types of std::basic_string<char> cause compiler problems
164  // if no string specific function
165  std::string getValue (void) const;
166  ConfigurationTree::BitMap getValueAsBitMap (void) const;
167 
168  private:
169  template<typename T>
170  T handleValidateValueForColumn(
171  const TableView* configView,
172  std::string value,
173  unsigned int col,
174  ots::identity<T>) const; // defined in included .icc source
175  std::string handleValidateValueForColumn(
176  const TableView* configView,
177  std::string value,
178  unsigned int col,
180 
181  public:
182  // navigating between nodes
183  ConfigurationTree getNode (const std::string& nodeName, bool doNotThrowOnBrokenUIDLinks = false) const;
184  ConfigurationTree getBackNode (std::string nodeName, unsigned int backSteps = 1) const;
185  ConfigurationTree getForwardNode (std::string nodeName, unsigned int forwardSteps = 1) const;
186 
187  // extracting information from node
188  const ConfigurationManager* getConfigurationManager (void) const { return configMgr_; }
189  const std::string& getTableName (void) const;
190  const std::string& getFieldTableName (void) const;
191  const TableVersion& getTableVersion (void) const;
192  const time_t& getTableCreationTime (void) const;
193  std::vector<std::vector<std::string>> getChildrenNamesByPriority (bool onlyStatusTrue = false) const;
194  std::vector<std::string> getChildrenNames (bool byPriority = false, bool onlyStatusTrue = false) const;
195  std::vector<std::vector<std::pair<
196  std::string, ConfigurationTree>>> getChildrenByPriority (std::map<std::string /*relative-path*/,
197  std::string /*value*/> filterMap = std::map<std::string /*relative-path*/, std::string /*value*/>(),
198  bool onlyStatusTrue = false) const;
199  std::vector<std::pair<std::string,
200  ConfigurationTree>> getChildren (std::map<std::string /*relative-path*/,
201  std::string /*value*/> filterMap = std::map<std::string /*relative-path*/, std::string /*value*/>(),
202  bool byPriority = false,
203  bool onlyStatusTrue = false) const;
204  std::map<std::string, ConfigurationTree> getChildrenMap (void) const;
205  std::string getEscapedValue (void) const;
206  const std::string& getValueAsString (bool returnLinkTableValue = false) const;
207  const std::string& getUIDAsString (void) const;
208  const std::string& getValueDataType (void) const;
209  const std::string& getValueType (void) const;
210  const std::string& getValueName (void) const;
211  inline const std::string& getFieldName (void) const { return getValueName(); } //alias for getValueName
212  std::string getNodeType (void) const;
213  const unsigned int& getNodeRow (void) const;
214  const std::string& getDisconnectedTableName (void) const;
215  const std::string& getDisconnectedLinkID (void) const;
216  const std::string& getChildLinkIndex (void) const;
217  std::vector<std::string> getFixedChoices (void) const;
218 
219  public:
220  // boolean info
221  bool isDefaultValue (void) const;
222  inline bool isRootNode (void) const;
223  inline bool isTableNode (void) const;
224  bool isValueNode (void) const;
225  bool isValueBoolType (void) const;
226  bool isValueNumberDataType (void) const;
227  bool isDisconnected (void) const;
228  bool isLinkNode (void) const;
229  bool isGroupLinkNode (void) const;
230  bool isUIDLinkNode (void) const;
231  bool isGroupIDNode (void) const;
232  bool isUIDNode (void) const;
233  bool isEnabled (void) const; //same as status()
234  inline bool status (void) const; //same as isEnabled()
235 
236  void print (const unsigned int& depth = -1, std::ostream& out = std::cout) const;
237  std::string nodeDump (void) const; // used for debugging (when throwing exception)
238 
239  // make stream output easy
240  friend std::ostream& operator<< (
241  std::ostream& out, const ConfigurationTree& t)
242  {
243  out << t.getValueAsString();
244  return out;
245  }
246 
247  protected:
248  const unsigned int& getRow (void) const;
249  const unsigned int& getColumn (void) const;
250  const unsigned int& getFieldRow (void) const;
251  const unsigned int& getFieldColumn (void) const;
252  const TableViewColumnInfo& getColumnInfo (void) const;
253 
254  // extracting information from a list of records
255  struct RecordField
256  {
257  RecordField(const std::string& table,
258  const std::string& uid,
259  const std::string& columnName,
260  const std::string& relativePath,
261  const TableViewColumnInfo* columnInfo)
262  : tableName_(table)
263  , columnName_(columnName)
264  , relativePath_(relativePath)
265  , columnInfo_(columnInfo)
266  {
267  }
268 
269  std::string tableName_, columnName_, relativePath_;
270  // relativePath_ is relative to record uid node, not including columnName_
271 
272  const TableViewColumnInfo* columnInfo_;
273  };
274  std::vector<ConfigurationTree::RecordField> getCommonFields (
275  const std::vector<std::string /*relative-path*/>& recordList,
276  const std::vector<std::string /*relative-path*/>& fieldAcceptList,
277  const std::vector<std::string /*relative-path*/>& fieldRejectList,
278  unsigned int depth = -1,
279  bool autoSelectFilterFields = false) const;
280  std::set<std::string /*unique-value*/> getUniqueValuesForField (
281  const std::vector<std::string /*relative-path*/>& recordList,
282  const std::string& fieldName,
283  std::string* fieldGroupIDChildLinkIndex = 0) const;
284 
285  private:
286  // private constructor: ONLY privately allow full access to member variables through constructor
287  ConfigurationTree(const ConfigurationManager* const& configMgr,
288  const TableBase* const& config,
289  const std::string& groupId,
290  const TableBase* const& linkParentConfig,
291  const std::string& linkColName,
292  const std::string& linkColValue,
293  const unsigned int linkBackRow,
294  const unsigned int linkBackCol,
295  const std::string& disconnectedTargetName,
296  const std::string& disconnectedLinkID,
297  const std::string& childLinkIndex,
298  const unsigned int row = TableView::INVALID,
299  const unsigned int col = TableView::INVALID);
300 
301  static ConfigurationTree recurse (const ConfigurationTree& t, const std::string& childPath, bool doNotThrowOnBrokenUIDLinks, const std::string& originalNodeString);
302  ConfigurationTree recursiveGetNode (const std::string& nodeName, bool doNotThrowOnBrokenUIDLinks, const std::string& originalNodeString) const;
303  static void recursivePrint (const ConfigurationTree& t, unsigned int depth, std::ostream& out, std::string space);
304 
305  void recursiveGetCommonFields (
306  std::vector<ConfigurationTree::RecordField>& fieldCandidateList,
307  std::vector<int>& fieldCount,
308  const std::vector<std::string /*relative-path*/>& fieldAcceptList,
309  const std::vector<std::string /*relative-path*/>& fieldRejectList,
310  unsigned int depth,
311  const std::string& relativePathBase,
312  bool inFirstRecord) const;
313  ConfigurationTree getValueAsTreeNode (void) const;
314 
315  // Any given ConfigurationTree is either a config, uid, or value node:
316  // - config node is a pointer to a config table
317  // - uid node is a pointer to a row in a config table
318  // - value node is a pointer to a cell in a config table
319  //
320  // Assumption: uid column is present
321  const ConfigurationManager* configMgr_; // root node
322  const TableBase* table_; // config node
323  const std::string groupId_; // group config node
324  const TableBase* linkParentConfig_; // link node parent config pointer (could be used
325  // to traverse backwards through tree)
326  const std::string linkColName_; // link node field name
327  const std::string linkColValue_; // link node field value
328  const unsigned int linkBackRow_; // source table link row
329  const unsigned int linkBackCol_; // source table link col
330  const std::string disconnectedTargetName_; // only used if disconnected to determine
331  // target table name
332  const std::string disconnectedLinkID_; // only used if disconnected to determine target link ID
333  const std::string childLinkIndex_; // child link index
334  const unsigned int row_; // uid node
335  const unsigned int col_; // value node
336  const TableView* tableView_;
337 };
338 
339 #include "otsdaq/ConfigurationInterface/ConfigurationTree.icc" //define template functions
340 
341 // clang-format on
342 } // namespace ots
343 
344 #endif