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