otsdaq  v1_01_02
 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 //#include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
6 //#include <xercesc/dom/DOMElement.hpp>
7 
8 #include <iostream> // std::cout
9 #include <string>
10 #include <set>
11 
12 
13 namespace ots
14 {
15 
16 class ConfigurationManager;
17 class ConfigurationBase;
18 class ConfigurationView;
19 
21 {
22  friend class ConfigurationGUISupervisor;
23 
24 public:
25  //Note: due to const members, implicit copy constructor exists, but NOT assignment 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 // configuration_ (a.configuration_),
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 // configView_ (a.configView_)
41 // {
42 // std::cout << __PRETTY_FUNCTION__ << std::endl;
43 // //return *this;
44 // }
45 
46  ConfigurationTree (const ConfigurationManager* const& configMgr, const ConfigurationBase* const &config);
47  ~ConfigurationTree (void);
48 
49  ConfigurationTree& operator=(const ConfigurationTree& a)
50  {
51  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR ConfigManager: " << configMgr_ << " configuration: " << configuration_ << std::endl;
52  //Note: Members of the ConfigurationTree are declared constant.
53  // (Refer to comments at top of class declaration for solutions)
54  // So this operator cannot work.. SO I am going to crash just in case it is called by mistake
55  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
56  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
57  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
58  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
59  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
60  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
61  std::cout << __PRETTY_FUNCTION__ << "OPERATOR= COPY CONSTRUCTOR CANNOT BE USED - SO YOUR CODE IS WRONG! Crashing now." << std::endl;
62  exit(0);
63 
64  //copy to const members is not allowed.. but would look like this:
65 
66  configMgr_ = a.configMgr_;
67  configuration_ = a.configuration_;
68  //groupId_ = a.groupId_;
69  //linkColName_ = a.linkColName_;
70  //childLinkIndex_ = a.childLinkIndex_;
71  //row_ = a.row_;
72  //col_ = a.col_;
73  configView_ = a.configView_;
74  std::cout << __PRETTY_FUNCTION__ << "OPERATOR COPY CONSTRUCTOR" << std::endl;
75  return *this;
76  };
77 
78 
79  static const std::string DISCONNECTED_VALUE;
80  static const std::string VALUE_TYPE_DISCONNECTED;
81  static const std::string VALUE_TYPE_NODE;
82 
83  static const std::string NODE_TYPE_GROUP_TABLE;
84  static const std::string NODE_TYPE_TABLE;
85  static const std::string NODE_TYPE_GROUP_LINK;
86  static const std::string NODE_TYPE_UID_LINK;
87  static const std::string NODE_TYPE_VALUE;
88  static const std::string NODE_TYPE_UID;
89 
90 
91  //Methods
92 
93 
94  //==============================================================================
95  //getValue (not std::string value)
96  // throw exception unless it value node
97  template<class T>
98  void getValue(T& value) const
99  {
100  if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID) //this node is a value node
101  configView_->getValue(value,row_,col_);
102  else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID) //this node is config node maybe with groupId
103  throw std::runtime_error("Requesting getValue on config node level. Must be a value node.");
104  else if(row_ == ConfigurationView::INVALID)
105  {
106  std::cout << __COUT_HDR_FL__ << std::endl;
107  throw std::runtime_error("Malformed ConfigurationTree");
108  }
109  else if(col_ == ConfigurationView::INVALID) //this node is uid node
110  throw std::runtime_error("Requesting getValue on uid node level. Must be a value node.");
111  else
112  {
113  std::cout << __COUT_HDR_FL__ << std::endl;
114  throw std::runtime_error("Impossible");
115  }
116  }
117 
118  //==============================================================================
119  //getValue (not std::string value)
120  // throw exception unless it value node
121  template<class T>
122  T getValue(void) const
123  {
124  T value;
125  if(row_ != ConfigurationView::INVALID && col_ != ConfigurationView::INVALID) //this node is a value node
126  {
127  configView_->getValue(value,row_,col_);
128  return value;
129  }
130  else if(row_ == ConfigurationView::INVALID && col_ == ConfigurationView::INVALID) //this node is config node maybe with groupId
131  throw std::runtime_error("Requesting getValue on config node level. Must be a value node.");
132  else if(row_ == ConfigurationView::INVALID)
133  {
134  std::cout << __COUT_HDR_FL__ << std::endl;
135  throw std::runtime_error("Malformed ConfigurationTree");
136  }
137  else if(col_ == ConfigurationView::INVALID) //this node is uid node
138  throw std::runtime_error("Requesting getValue on uid node level. Must be a value node.");
139  else
140  {
141  std::cout << __COUT_HDR_FL__ << std::endl;
142  throw std::runtime_error("Impossible");
143  }
144  }
145 
146  //navigating between nodes
147  ConfigurationTree getNode (const std::string& nodeName, bool doNotThrowOnBrokenUIDLinks=false) const;
148  ConfigurationTree getBackNode ( std::string nodeName, unsigned int backSteps=1) const;
149 
150 
151  //extracting information from node
152  const std::string& getConfigurationName (void) const;
153  const ConfigurationVersion& getConfigurationVersion (void) const;
154  const time_t& getConfigurationCreationTime(void) const;
155  std::vector<std::string> getChildrenNames (void) const;
156  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;
157  std::map<std::string,ConfigurationTree> getChildrenMap (void) const;
158  void getValue (std::string& value) const;
159  std::string getValue (void) const;
160  std::string getEscapedValue (void) const;
161  const std::string& getValueAsString (bool returnLinkTableValue=false) const;
162  const std::string& getUIDAsString (void) const;
163  const std::string& getValueDataType (void) const;
164  const std::string& getValueType (void) const;
165  const std::string& getValueName (void) const;
166  std::string getNodeType (void) const;
167  const std::string& getDisconnectedTableName (void) const;
168  const std::string& getDisconnectedLinkID (void) const;
169  const std::string& getChildLinkIndex (void) const;
170  std::vector<std::string> getFixedChoices (void) const;
171 
172 protected:
173  const unsigned int& getRow (void) const;
174  const unsigned int& getColumn (void) const;
175  const ViewColumnInfo& getColumnInfo (void) const;
176 
177  //extracting information from a list of records
178  struct RecordField
179  {
180  RecordField(const std::string &table, const std::string &uid,
181  const std::string &columnName, const std::string &relativePath,
182  const ViewColumnInfo *columnInfo)
183  :tableName_(table)
184  ,columnName_(columnName)
185  ,relativePath_(relativePath)
186  ,columnInfo_(columnInfo)
187  {}
188 
189  std::string tableName_, columnName_, relativePath_;
190  //relativePath_ is relative to record uid node, not including columnName_
191 
192  const ViewColumnInfo *columnInfo_;
193  };
194  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;
195  std::set<std::string /*unique-value*/> getUniqueValuesForField(const std::vector<std::string /*relative-path*/> &recordList, const std::string &fieldName) const;
196 
197 
198 public:
199 
200 
201  //boolean info
202  bool isDefaultValue (void) const;
203  bool isConfigurationNode (void) const;
204  bool isValueNode (void) const;
205  bool isDisconnected (void) const;
206  bool isLinkNode (void) const;
207  bool isGroupLinkNode (void) const;
208  bool isUIDLinkNode (void) const;
209  bool isUIDNode (void) const;
210 
211 
212  void print (const unsigned int &depth = -1, std::ostream &out = std::cout) const;
213 
214  //make stream output easy
215  friend std::ostream& operator<< (std::ostream& out, const ConfigurationTree& t)
216  {
217  out << t.getValueAsString();
218  return out;
219  }
220 private:
221  //privately ONLY allow full access to member variables through constructor
222  ConfigurationTree(const ConfigurationManager* const& configMgr, const ConfigurationBase* const& config, const std::string& groupId, 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);
223 
224  static ConfigurationTree recurse (const ConfigurationTree& t, const std::string& childPath);
225  static void recursivePrint(const ConfigurationTree& t, unsigned int depth, std::ostream &out, std::string space);
226 
227  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;
228 
229  //std::string getRecordFieldValueAsString(std::string fieldName) const;
230 
231  //Any given ConfigurationTree is either a config, uid, or value node:
232  // - config node is a pointer to a config table
233  // - uid node is a pointer to a row in a config table
234  // - value node is a pointer to a cell in a config table
235  //
236  //Assumption: uid column is present
237  const ConfigurationManager* configMgr_;
238  const ConfigurationBase* configuration_; //config node
239  const std::string groupId_; //group config node
240  const std::string linkColName_; //link node field name
241  const std::string linkColValue_; //link node field value
242  const std::string disconnectedTargetName_; //only used if disconnected to determine target table name
243  const std::string disconnectedLinkID_; //only used if disconnected to determine target link ID
244  const std::string childLinkIndex_;//child link index
245  const unsigned int row_; //uid node
246  const unsigned int col_; //value node
247  const ConfigurationView* configView_;
248 
249 };
250 }
251 
252 #endif