BeeeOn Gateway  v2020.3.1-2-g6f737dc
Platform to interconnect the IoT world
InfoProvider.h
1 #pragma once
2 
3 #include <set>
4 
5 #include <Poco/SharedPtr.h>
6 #include <Poco/Path.h>
7 #include <Poco/Logger.h>
8 #include <Poco/Exception.h>
9 #include <Poco/SingletonHolder.h>
10 
11 #include "util/SAXHelper.h"
12 #include "util/Loggable.h"
13 
14 namespace BeeeOn {
15 
16 template <typename T>
18  bool operator() (const Poco::SharedPtr<T> &a,
19  const Poco::SharedPtr<T> &b) const
20  {
21  return *a < *b;
22  }
23 };
24 
25 template <typename T>
26 class InfoProvider : public Loggable {
27 public:
28  typedef std::set<Poco::SharedPtr<T>,
30  virtual ~InfoProvider();
31 
32  const Poco::SharedPtr<T> findById(const typename T::ID &id) const;
33 
34  typename InfoSet::const_iterator begin() const
35  {
36  return infoSet().begin();
37  }
38 
39  typename InfoSet::const_iterator end() const
40  {
41  return infoSet().end();
42  }
43 
44 protected:
45  bool registerInfo(const T &info);
46 
47  virtual InfoSet &infoSet();
48  virtual const InfoSet &infoSet() const;
49 
50 private:
51  InfoSet m_infoSet;
52 };
53 
54 template <typename T>
56 {
57 }
58 
59 template <typename T>
60 typename InfoProvider<T>::InfoSet &InfoProvider<T>::infoSet()
61 {
62  return m_infoSet;
63 }
64 
65 template <typename T>
66 const typename InfoProvider<T>::InfoSet &InfoProvider<T>::infoSet() const
67 {
68  return m_infoSet;
69 }
70 
71 template <typename T>
72 const Poco::SharedPtr<T> InfoProvider<T>::findById(const typename T::ID &id) const
73 {
74  Poco::SharedPtr<T> pattern(new T());
75  pattern->setId(id);
76 
77  auto it = infoSet().find(pattern);
78  if (it == infoSet().end())
79  return NULL;
80 
81  return *it;
82 }
83 
84 template <typename T>
85 bool InfoProvider<T>::registerInfo(const T &info)
86 {
87  const Poco::SharedPtr<T> copy(new T(info));
88 
89  if (infoSet().find(copy) != infoSet().end())
90  return false;
91 
92  infoSet().insert(copy);
93  return true;
94 }
95 
96 template <typename T>
97 class NullInfoProvider : public InfoProvider<T> {
98 public:
99  static InfoProvider<T> &instance();
100 
101 protected:
102  typename InfoProvider<T>::InfoSet &infoSet() override;
103  const typename InfoProvider<T>::InfoSet &infoSet() const override;
104 };
105 
106 template <typename T>
107 typename InfoProvider<T>::InfoSet &NullInfoProvider<T>::infoSet()
108 {
109  throw Poco::NotImplementedException(__func__);
110 }
111 
112 template <typename T>
113 const typename InfoProvider<T>::InfoSet &NullInfoProvider<T>::infoSet() const
114 {
115  throw Poco::NotImplementedException(__func__);
116 }
117 
118 template <typename T>
119 InfoProvider<T> &NullInfoProvider<T>::instance()
120 {
121  static Poco::SingletonHolder<NullInfoProvider<T>> singleton;
122  return *singleton.get();
123 }
124 
125 template <typename T>
126 class XmlInfoProvider : public InfoProvider<T> {
127 public:
128  virtual ~XmlInfoProvider();
129 
130 protected:
131  template <typename SAXHandler>
132  void parseFile(const std::string &path,
133  const std::string &infoLabel);
134 };
135 
136 template <typename T>
138 {
139 }
140 
141 template <typename T> template <typename SAXHandler>
142 void XmlInfoProvider<T>::parseFile(const std::string &path,
143  const std::string &infoLabel)
144 {
145  if (path.empty())
146  return;
147 
148  Poco::Path file(path);
149  SAXHandler handler;
150 
151  SAXHelper::parse(file, handler);
152 
153  for (const auto &info : handler) {
154  this->logger().information("register " + infoLabel
155  + " " + info.name()
156  + " with ID " + info.id().toString(),
157  __FILE__, __LINE__);
158 
159  if (this->registerInfo(info))
160  continue;
161 
162  this->logger().error(infoLabel + " " + info.name()
163  + " with ID " + info.id().toString()
164  + " is already registered",
165  __FILE__, __LINE__);
166  }
167 }
168 
169 }
Definition: InfoProvider.h:17
Definition: InfoProvider.h:126
Definition: InfoProvider.h:97
Definition: InfoProvider.h:26
Definition: Loggable.h:19