Line data Source code
1 : // DUNE DAQ modification notice:
2 : // This file has been modified from the original ATLAS oks source for the DUNE DAQ project.
3 : // Fork baseline commit: oks-08-03-04 (2022-04-14).
4 : // Renamed since fork: no.
5 :
6 : #define _OksBuildDll_
7 :
8 : #include "oks/relationship.hpp"
9 : #include "oks/xml.hpp"
10 : #include "oks/class.hpp"
11 : #include "oks/kernel.hpp"
12 : #include "oks/cstring.hpp"
13 :
14 : #include <sstream>
15 :
16 : namespace dunedaq {
17 : namespace oks {
18 :
19 : const char OksRelationship::relationship_xml_tag[] = "relationship";
20 : const char OksRelationship::name_xml_attr[] = "name";
21 : const char OksRelationship::description_xml_attr[] = "description";
22 : const char OksRelationship::class_type_xml_attr[] = "class-type";
23 : const char OksRelationship::low_cc_xml_attr[] = "low-cc";
24 : const char OksRelationship::high_cc_xml_attr[] = "high-cc";
25 : const char OksRelationship::is_composite_xml_attr[] = "is-composite";
26 : const char OksRelationship::is_exclusive_xml_attr[] = "is-exclusive";
27 : const char OksRelationship::is_dependent_xml_attr[] = "is-dependent";
28 : const char OksRelationship::ordered_xml_attr[] = "ordered";
29 :
30 :
31 : OksRelationship::CardinalityConstraint
32 10864 : OksRelationship::str2card(const char * s) noexcept
33 : {
34 10864 : return (
35 10864 : oks::cmp_str3(s, "one") ? One :
36 5489 : oks::cmp_str4(s, "zero") ? Zero :
37 : Many
38 10864 : );
39 : }
40 :
41 : const char *
42 0 : OksRelationship::card2str(CardinalityConstraint cc) noexcept
43 : {
44 0 : return (
45 0 : cc == Zero ? "zero" :
46 0 : cc == One ? "one" :
47 : "many"
48 0 : );
49 : }
50 :
51 0 : OksRelationship::OksRelationship(const std::string& nm, OksClass * p) :
52 0 : p_name (nm),
53 0 : p_low_cc (Zero),
54 0 : p_high_cc (Many),
55 0 : p_composite (false),
56 0 : p_exclusive (false),
57 0 : p_dependent (false),
58 0 : p_class (p),
59 0 : p_class_type (nullptr),
60 0 : p_ordered (false)
61 : {
62 0 : oks::validate_not_empty(p_name, "relationship name");
63 0 : }
64 :
65 0 : OksRelationship::OksRelationship(const std::string& nm, const std::string& rc,
66 : CardinalityConstraint l_cc, CardinalityConstraint h_cc,
67 0 : bool cm, bool excl, bool dp, const std::string& desc, OksClass * p) :
68 0 : p_name (nm),
69 0 : p_rclass (rc),
70 0 : p_low_cc (l_cc),
71 0 : p_high_cc (h_cc),
72 0 : p_composite (cm),
73 0 : p_exclusive (excl),
74 0 : p_dependent (dp),
75 0 : p_description (desc),
76 0 : p_class (p),
77 0 : p_class_type (nullptr),
78 0 : p_ordered (false)
79 : {
80 0 : oks::validate_not_empty(p_name, "relationship name");
81 0 : oks::validate_not_empty(p_rclass, "relationship class");
82 0 : }
83 :
84 : bool
85 315 : OksRelationship::operator==(const class OksRelationship &r) const
86 : {
87 315 : return (
88 315 : ( this == &r ) ||
89 : (
90 0 : ( p_name == r.p_name ) &&
91 0 : ( p_rclass == r.p_rclass ) &&
92 0 : ( p_low_cc == r.p_low_cc ) &&
93 : ( p_high_cc == r.p_high_cc ) &&
94 : ( p_composite == r.p_composite ) &&
95 0 : ( p_exclusive == r.p_exclusive ) &&
96 0 : ( p_dependent == r.p_dependent ) &&
97 0 : ( p_description == r.p_description ) &&
98 0 : ( p_ordered == r.p_ordered )
99 : )
100 315 : );
101 : }
102 :
103 : std::ostream&
104 0 : operator<<(std::ostream& s, const OksRelationship& r)
105 : {
106 0 : s << "Relationship name: \"" << r.p_name << "\"\n"
107 0 : " class type: \"" << r.p_rclass << "\"\n"
108 0 : " low cardinality constraint is " << OksRelationship::card2str(r.p_low_cc) << "\n"
109 0 : " high cardinality constraint is " << OksRelationship::card2str(r.p_high_cc) << "\n"
110 0 : " is" << (r.p_composite == true ? "" : " not") << " composite reference\n"
111 0 : " is" << (r.p_exclusive == true ? "" : " not") << " exclusive reference\n"
112 0 : " is " << (r.p_dependent == true ? "dependent" : "shared") << " reference\n"
113 0 : " has description: \"" << r.p_description << "\"\n"
114 0 : " is " << (r.p_ordered == true ? "ordered" : "unordered") << std::endl;
115 :
116 0 : return s;
117 : }
118 :
119 :
120 : void
121 0 : OksRelationship::save(OksXmlOutputStream& s) const
122 : {
123 0 : s.put(" ");
124 :
125 0 : s.put_start_tag(relationship_xml_tag, sizeof(relationship_xml_tag) - 1);
126 :
127 0 : s.put_attribute(name_xml_attr, sizeof(name_xml_attr) - 1, p_name.c_str());
128 :
129 0 : if (!p_description.empty())
130 0 : s.put_attribute(description_xml_attr, sizeof(description_xml_attr) - 1, p_description.c_str());
131 :
132 0 : s.put_attribute(class_type_xml_attr, sizeof(class_type_xml_attr) - 1, p_rclass.c_str());
133 0 : s.put_attribute(low_cc_xml_attr, sizeof(low_cc_xml_attr) - 1, card2str(p_low_cc));
134 0 : s.put_attribute(high_cc_xml_attr, sizeof(high_cc_xml_attr) - 1, card2str(p_high_cc));
135 0 : s.put_attribute(is_composite_xml_attr, sizeof(is_composite_xml_attr) - 1, oks::xml::bool2str(p_composite));
136 0 : s.put_attribute(is_exclusive_xml_attr, sizeof(is_exclusive_xml_attr) - 1, oks::xml::bool2str(p_exclusive));
137 0 : s.put_attribute(is_dependent_xml_attr, sizeof(is_dependent_xml_attr) - 1, oks::xml::bool2str(p_dependent));
138 :
139 0 : if (p_ordered)
140 0 : s.put_attribute(ordered_xml_attr, sizeof(ordered_xml_attr) - 1, oks::xml::bool2str(p_ordered));
141 :
142 0 : s.put_end_tag();
143 0 : }
144 :
145 :
146 5432 : OksRelationship::OksRelationship(OksXmlInputStream& s, OksClass *parent) :
147 5432 : p_low_cc (Zero),
148 5432 : p_high_cc (Many),
149 5432 : p_composite (false),
150 5432 : p_exclusive (false),
151 5432 : p_dependent (false),
152 5432 : p_class (parent),
153 5432 : p_class_type (nullptr),
154 5432 : p_ordered (false)
155 : {
156 45970 : try {
157 86508 : while(true) {
158 45970 : OksXmlAttribute attr(s);
159 :
160 : // check for close of tag
161 :
162 45970 : if(oks::cmp_str1(attr.name(), "/")) { break; }
163 :
164 :
165 : // check for known oks-relationship' attributes
166 :
167 40538 : else if(oks::cmp_str4(attr.name(), name_xml_attr)) p_name.assign(attr.value(), attr.value_len());
168 35106 : else if(oks::cmp_str11(attr.name(), description_xml_attr)) p_description.assign(attr.value(), attr.value_len());
169 32601 : else if(oks::cmp_str10(attr.name(), class_type_xml_attr)) p_rclass.assign(attr.value(), attr.value_len());
170 27169 : else if(oks::cmp_str6(attr.name(), low_cc_xml_attr)) p_low_cc = str2card(attr.value());
171 21737 : else if(oks::cmp_str7(attr.name(), high_cc_xml_attr)) p_high_cc = str2card(attr.value());
172 16305 : else if(oks::cmp_str12(attr.name(), is_composite_xml_attr)) p_composite = oks::xml::str2bool(attr.value());
173 10873 : else if(oks::cmp_str12(attr.name(), is_exclusive_xml_attr)) p_exclusive = oks::xml::str2bool(attr.value());
174 5441 : else if(oks::cmp_str12(attr.name(), is_dependent_xml_attr)) p_dependent = oks::xml::str2bool(attr.value());
175 9 : else if(oks::cmp_str7(attr.name(), ordered_xml_attr)) p_ordered = oks::xml::str2bool(attr.value());
176 0 : else if(!strcmp(attr.name(), "multi-value-implementation")) {
177 0 : s.error_msg("OksRelationship::OksRelationship(OksXmlInputStream&)")
178 0 : << "Obsolete oks-relationship\'s attribute \'" << attr.name() << "\'\n";
179 : }
180 : else {
181 0 : s.throw_unexpected_attribute(attr.name());
182 : }
183 40538 : }
184 : }
185 0 : catch(oks::exception & e) {
186 0 : throw oks::FailedRead("xml attribute", e);
187 0 : }
188 0 : catch (std::exception & e) {
189 0 : throw oks::FailedRead("xml attribute", e.what());
190 0 : }
191 :
192 :
193 : // check validity of read values
194 :
195 5432 : try {
196 5432 : oks::validate_not_empty(p_name, "relationship name");
197 5432 : oks::validate_not_empty(p_rclass, "relationship class");
198 : }
199 0 : catch(std::exception& ex) {
200 0 : throw oks::FailedRead("oks relationship", oks::BadFileData(ex.what(), s.get_line_no(), s.get_line_pos()));
201 0 : }
202 5432 : }
203 :
204 :
205 : void
206 0 : OksRelationship::set_name(const std::string& new_name)
207 : {
208 : // ignore when name is the same
209 :
210 0 : if(p_name == new_name) return;
211 :
212 :
213 : // additional checks are required,
214 : // if the relationship already belongs to some class
215 :
216 0 : if(p_class) {
217 :
218 : // check maximum allowed length for relationship name
219 :
220 0 : try {
221 0 : oks::validate_not_empty(new_name, "name");
222 : }
223 0 : catch(std::exception& ex) {
224 0 : throw oks::SetOperationFailed("OksRelationship::set_name", ex.what());
225 0 : }
226 :
227 :
228 : // having a direct relationship with the same name is an error
229 :
230 0 : if(p_class->find_direct_relationship(new_name) != 0) {
231 0 : std::ostringstream text;
232 0 : text << "Class \"" << p_class->get_name() << "\" already has direct relationship \"" << new_name << '\"';
233 0 : throw oks::SetOperationFailed("OksRelationship::set_name", text.str());
234 0 : }
235 :
236 :
237 : // check possibility to lock the file
238 :
239 0 : p_class->lock_file("OksRelationship::set_name");
240 :
241 :
242 : // probably a non-direct relationship already exists
243 :
244 0 : OksRelationship * r = p_class->find_relationship(new_name);
245 :
246 :
247 : // change the name
248 :
249 0 : p_name = new_name;
250 :
251 :
252 : // registrate the change
253 :
254 0 : p_class->registrate_class_change(OksClass::ChangeRelationshipsList, (const void *)r);
255 : }
256 : else {
257 0 : p_name = new_name;
258 : }
259 : }
260 :
261 : void
262 0 : OksRelationship::set_type(const std::string& cn)
263 : {
264 0 : if(p_rclass == cn) return;
265 :
266 0 : if(!p_class || !p_class->p_kernel || (p_class_type = p_class->p_kernel->find_class(cn)) != 0) {
267 0 : if(p_class) p_class->lock_file("OksRelationship::set_type");
268 :
269 0 : p_rclass = cn;
270 :
271 0 : if(p_class) {
272 0 : p_class->registrate_class_change(OksClass::ChangeRelationshipClassType, (const void *)this);
273 0 : p_class->registrate_relationship_change(this);
274 : }
275 : }
276 : else {
277 0 : std::ostringstream text;
278 0 : text << "cannot find class \"" << cn << '\"';
279 0 : throw oks::SetOperationFailed("OksRelationship::set_type", text.str());
280 0 : }
281 : }
282 :
283 : void
284 0 : OksRelationship::set_description(const std::string& desc)
285 : {
286 0 : if(p_description != desc) {
287 0 : if(p_class) p_class->lock_file("OksRelationship::set_description");
288 :
289 0 : p_description = desc;
290 :
291 0 : if(p_class) p_class->registrate_class_change(OksClass::ChangeRelationshipDescription, (const void *)this);
292 : }
293 0 : }
294 :
295 : void
296 0 : OksRelationship::set_low_cardinality_constraint(CardinalityConstraint l_cc)
297 : {
298 0 : if(p_low_cc != l_cc) {
299 0 : if(p_class) p_class->lock_file("OksRelationship::set_low_cardinality_constraint");
300 :
301 0 : CardinalityConstraint old_cc = p_low_cc;
302 :
303 0 : p_low_cc = l_cc;
304 :
305 0 : if(p_class) {
306 0 : p_class->registrate_class_change(OksClass::ChangeRelationshipLowCC, (const void *)this);
307 :
308 0 : if(p_low_cc == Many || old_cc == Many) p_class->registrate_relationship_change(this);
309 : }
310 : }
311 0 : }
312 :
313 : void
314 0 : OksRelationship::set_high_cardinality_constraint(CardinalityConstraint h_cc)
315 : {
316 0 : if(p_high_cc != h_cc) {
317 0 : if(p_class) p_class->lock_file("OksRelationship::set_high_cardinality_constraint");
318 :
319 0 : CardinalityConstraint old_cc = p_high_cc;
320 :
321 0 : p_high_cc = h_cc;
322 :
323 0 : if(p_class) {
324 0 : p_class->registrate_class_change(OksClass::ChangeRelationshipHighCC, (const void *)this);
325 :
326 0 : if(p_high_cc == Many || old_cc == Many) p_class->registrate_relationship_change(this);
327 : }
328 : }
329 0 : }
330 :
331 : void
332 0 : OksRelationship::set_is_composite(bool cm)
333 : {
334 0 : if(p_composite != cm) {
335 0 : if(p_class) p_class->lock_file("OksRelationship::set_is_composite");
336 :
337 0 : p_composite = cm;
338 :
339 0 : if(p_class) p_class->registrate_class_change(OksClass::ChangeRelationshipComposite, (const void *)this);
340 : }
341 0 : }
342 :
343 : void
344 0 : OksRelationship::set_is_exclusive(bool ex)
345 : {
346 0 : if(p_exclusive != ex) {
347 0 : if(p_class) p_class->lock_file("OksRelationship::set_is_exclusive");
348 :
349 0 : p_exclusive = ex;
350 :
351 0 : if(p_class) p_class->registrate_class_change(OksClass::ChangeRelationshipExclusive, (const void *)this);
352 : }
353 0 : }
354 :
355 : void
356 0 : OksRelationship::set_is_dependent(bool dp)
357 : {
358 0 : if(p_dependent != dp) {
359 0 : if(p_class) p_class->lock_file("OksRelationship::set_is_dependent");
360 :
361 0 : p_dependent = dp;
362 :
363 0 : if(p_class) p_class->registrate_class_change(OksClass::ChangeRelationshipDependent, (const void *)this);
364 : }
365 0 : }
366 :
367 : } // namespace oks
368 : } // namespace dunedaq
|