Line data Source code
1 : // DUNE DAQ modification notice:
2 : // This file has been modified from the original ATLAS dbe source for the DUNE DAQ project.
3 : // Fork baseline commit: dbe-02-12-17 (2022-05-12).
4 : // Renamed since fork: no.
5 :
6 : /*
7 : * config_api_graph.cpp
8 : *
9 : * Created on: Apr 20, 2016
10 : * Author: Leonidas Georgopoulos
11 : */
12 :
13 : #include "dbe/config_api_graph.hpp"
14 : #include "dbe/config_api_info.hpp"
15 : #include "dbe/confobject_desc.hpp"
16 : #include "dbe/dbcontroller.hpp"
17 : #include "dbe/messenger.hpp"
18 :
19 : #include "conffwk/Schema.hpp"
20 :
21 : #include <algorithm>
22 :
23 : using namespace dunedaq::conffwk;
24 :
25 : //------------------------------------------------------------------------------------------
26 : // DBE::CONFIG::API::GRAPH NAMESPACE
27 : //------------------------------------------------------------------------------------------
28 : namespace dbe {
29 : namespace config {
30 : namespace api {
31 : namespace graph {
32 :
33 : //------------------------------------------------------------------------------------------
34 : namespace linked {
35 : namespace through {
36 : //------------------------------------------------------------------------------------------
37 : //------------------------------------------------------------------------------------------
38 : /*
39 : * Objects referenced by the given object through a specific attribute
40 : */
41 : template<>
42 : tref
43 0 : attribute<tref>(tref object, dunedaq::conffwk::attribute_t const& attr)
44 : {
45 0 : return object.get<tref>(attr.p_name);
46 : }
47 :
48 : template<>
49 : std::vector<tref>
50 0 : attribute<std::vector<tref>>(tref item, dunedaq::conffwk::attribute_t const& attr)
51 : {
52 0 : if (attr.p_type == dunedaq::conffwk::class_type) {
53 0 : if (attr.p_is_multi_value) {
54 0 : std::vector<tref> adj;
55 0 : item.get(attr.p_name, adj);
56 : return adj;
57 0 : } else if (attr.p_is_not_null) {
58 0 : try {
59 0 : return { attribute<tref>(item, attr) };
60 0 : } catch (daq::dbe::config_object_retrieval_result_is_null const& e) {
61 0 : if (attr.p_is_not_null) {
62 0 : WARN("Query returned null value for an attr that has p_is_not_null set true",
63 : "Program parsing data validation failure",
64 : item.full_name(),
65 : " for attribute ",
66 0 : attr.p_name);
67 : } else {
68 0 : DEBUG("Query returned null value", "Program parsing data validation");
69 : }
70 0 : }
71 : }
72 : }
73 :
74 0 : return {};
75 0 : }
76 : //------------------------------------------------------------------------------------------
77 :
78 : //------------------------------------------------------------------------------------------
79 : /*
80 : * Objects referenced by the given object through a specific relation
81 : */
82 : template<>
83 : tref
84 0 : relation<tref>(tref object, dunedaq::conffwk::relationship_t const& r)
85 : {
86 0 : return object.get<tref>(r.p_name);
87 : }
88 :
89 : template<>
90 : std::vector<tref>
91 0 : relation<std::vector<tref>>(tref item, dunedaq::conffwk::relationship_t const& r)
92 : {
93 0 : if (dbe::config::api::info::relation::is_simple(r)) {
94 0 : try {
95 0 : return { through::relation<tref>(item, r) };
96 0 : } catch (daq::dbe::config_object_retrieval_result_is_null const& e) {
97 0 : return {};
98 0 : }
99 : } else {
100 0 : std::vector<tref> adjacent;
101 0 : item.get(r.p_name, adjacent);
102 0 : return adjacent;
103 0 : }
104 0 : }
105 :
106 : template<>
107 : QStringList
108 0 : relation<QStringList>(tref item, dunedaq::conffwk::relationship_t const& r)
109 : {
110 0 : QStringList result;
111 0 : std::vector<tref> adjacent = relation<std::vector<tref>>(item, r);
112 :
113 0 : for (auto const& x : adjacent) {
114 0 : result.push_back(x.UID().c_str());
115 : }
116 :
117 0 : return result;
118 0 : }
119 :
120 : template<>
121 : std::vector<dbe::config_object_description<std::string>>
122 0 : relation<std::vector<dbe::config_object_description<std::string>>>(tref object,
123 : dunedaq::conffwk::relationship_t const& relation)
124 : {
125 0 : std::vector<dbe::config_object_description<std::string>> result;
126 :
127 0 : std::vector<tref> adjacent = linked::through::relation<std::vector<tref>>(object, relation);
128 :
129 0 : for (auto const& x : adjacent) {
130 0 : result.push_back(x);
131 : }
132 :
133 0 : return result;
134 0 : }
135 :
136 : //------------------------------------------------------------------------------------------
137 : } // end namespace through
138 : } // end namespace link
139 :
140 : //------------------------------------------------------------------------------------------
141 : template<typename T>
142 : inline T
143 0 : direct::linked(ConfigObject& input, dunedaq::conffwk::relationship_t const& relation)
144 : {
145 0 : T value;
146 0 : input.get(relation.p_name, value);
147 0 : return value;
148 0 : }
149 :
150 : template ConfigObject
151 : direct::linked<ConfigObject>(ConfigObject&, dunedaq::conffwk::relationship_t const&);
152 :
153 : template std::vector<ConfigObject>
154 : direct::linked<std::vector<ConfigObject>>(ConfigObject&, dunedaq::conffwk::relationship_t const&);
155 : //------------------------------------------------------------------------------------------
156 :
157 : //------------------------------------------------------------------------------------------
158 : /*
159 : * Retrieve objects referenced by an object through any of its relations
160 : */
161 : template<typename T>
162 : std::vector<T>
163 0 : linked::through::relations(inner::configobject::tref const& o)
164 : {
165 0 : dunedaq::conffwk::class_t classdef{ info::onclass::definition(o.class_name(), false) };
166 :
167 0 : std::vector<T> voisins;
168 :
169 0 : for (dunedaq::conffwk::relationship_t const& r : classdef.p_relationships) {
170 0 : std::vector<T> a = relation<std::vector<T>>(o, r);
171 0 : voisins.insert(voisins.end(), a.begin(), a.end());
172 : }
173 :
174 0 : voisins.erase(std::unique(std::begin(voisins), std::end(voisins)), std::end(voisins));
175 0 : return voisins;
176 0 : }
177 : template std::vector<tref>
178 : linked::through::relations<tref>(tref const&);
179 :
180 : /*
181 : * Retrieve objects linked by an object through any of its attributes
182 : */
183 : template<typename T>
184 : std::vector<T>
185 0 : linked::through::attributes(inner::configobject::tref const& o)
186 : {
187 0 : dunedaq::conffwk::class_t classdef{ info::onclass::definition(o.class_name(), true) };
188 :
189 0 : std::vector<T> voisins;
190 :
191 0 : for (dunedaq::conffwk::attribute_t const& attr : classdef.p_attributes) {
192 0 : std::vector<tref> a = attribute<std::vector<T>>(o, attr);
193 0 : voisins.insert(voisins.end(), a.begin(), a.end());
194 : }
195 :
196 0 : voisins.erase(std::unique(std::begin(voisins), std::end(voisins)), std::end(voisins));
197 0 : return voisins;
198 0 : }
199 : template std::vector<tref>
200 : linked::through::attributes<tref>(tref const&);
201 : //------------------------------------------------------------------------------------------
202 :
203 : //------------------------------------------------------------------------------------------
204 : /*
205 : * Retrieve links by operating directly on a ConfigObject
206 : */
207 : template<typename T>
208 : inline T
209 0 : direct::linked(ConfigObject& input, dunedaq::conffwk::attribute_t const& relation)
210 : {
211 0 : T value;
212 0 : input.get(relation.p_name, value);
213 0 : return value;
214 0 : }
215 :
216 : template<>
217 : inline QStringList
218 : direct::linked<QStringList>(ConfigObject& input, dunedaq::conffwk::relationship_t const& relation)
219 : {
220 : QStringList result;
221 : std::vector<ConfigObject> adjacent;
222 :
223 : if (info::relation::is_simple(relation)) {
224 : adjacent = { direct::linked<ConfigObject>(input, relation) };
225 : } else {
226 : adjacent = direct::linked<std::vector<ConfigObject>>(input, relation);
227 : }
228 :
229 : for (auto const& x : adjacent) {
230 : result.push_back(x.UID().c_str());
231 : }
232 :
233 : return result;
234 : }
235 :
236 : template ConfigObject
237 : direct::linked<ConfigObject>(ConfigObject&, dunedaq::conffwk::attribute_t const&);
238 : template std::vector<ConfigObject>
239 : direct::linked<std::vector<ConfigObject>>(ConfigObject&, dunedaq::conffwk::attribute_t const&);
240 : template QStringList
241 : direct::linked<QStringList>(ConfigObject&, dunedaq::conffwk::relationship_t const&);
242 : //------------------------------------------------------------------------------------------
243 :
244 : template tref
245 : linked::through::attribute<tref>(inner::configobject::tref, dunedaq::conffwk::attribute_t const&);
246 : template std::vector<tref>
247 : linked::through::attribute<std::vector<tref>>(inner::configobject::tref, dunedaq::conffwk::attribute_t const&);
248 : template tref
249 : linked::through::relation<tref>(tref, dunedaq::conffwk::relationship_t const&);
250 : template std::vector<tref>
251 : linked::through::relation<std::vector<tref>>(tref, dunedaq::conffwk::relationship_t const&);
252 : template QStringList
253 : linked::through::relation<QStringList>(tref, dunedaq::conffwk::relationship_t const&);
254 : template std::vector<dbe::config_object_description<std::string>>
255 : linked::through::relation<std::vector<dbe::config_object_description<std::string>>>(
256 : dbe::inner::configobject::tref,
257 : dunedaq::conffwk::relationship_t const&);
258 : //------------------------------------------------------------------------------------------
259 :
260 : //------------------------------------------------------------------------------------------
261 : namespace linked {
262 : namespace by {
263 : /*
264 : * Get objects that are linked by a given object
265 : */
266 : template<typename T>
267 : std::vector<T>
268 0 : object(inner::configobject::tref const& o)
269 : {
270 0 : std::vector<T> links = through::attributes<T>(o);
271 0 : std::vector<T> rlinks = through::relations<T>(o);
272 :
273 0 : if (not rlinks.empty()) {
274 0 : links.insert(links.end(), rlinks.begin(), rlinks.end());
275 : }
276 :
277 0 : links.erase(std::unique(links.begin(), links.end()), links.end());
278 :
279 0 : return links;
280 0 : }
281 :
282 : } // end namespace by
283 : } // end namespace link
284 : template std::vector<inner::configobject::tref>
285 : linked::by::object<inner::configobject::tref>(inner::configobject::tref const&);
286 : //------------------------------------------------------------------------------------------
287 :
288 : //------------------------------------------------------------------------------------------
289 : namespace linked {
290 : namespace to {
291 :
292 : /*
293 : * Get objects which link to a given object
294 : */
295 : template<>
296 : std::vector<inner::configobject::tref>
297 0 : object<inner::configobject::tref>(inner::configobject::tref const& o)
298 : {
299 : // Use with caution ... takes for ever to complete due to the underlying
300 : // ConfigObject implementation
301 0 : return o.referenced_by("*", false);
302 : }
303 :
304 : } // end namespace to
305 : } // end namespace link
306 : template std::vector<inner::configobject::tref>
307 : linked::to::object<inner::configobject::tref>(inner::configobject::tref const&);
308 : //------------------------------------------------------------------------------------------
309 : }
310 : }
311 : }
312 : }
313 : //------------------------------------------------------------------------------------------
|