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