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