DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
oks_check_schema.cxx
Go to the documentation of this file.
1
10
11#include "CLI/CLI.hpp"
12#include "logging/Logging.hpp"
13#include "oks/class.hpp"
14#include "oks/file.hpp"
15#include "oks/kernel.hpp"
16#include "oks/relationship.hpp"
17
18#include <fmt/core.h>
19#include <set>
20#include <string>
21
22using namespace dunedaq::oks;
23
24
25
26int main(int argc, char **argv) {
27 enum Exitcode : int {SUCCESS, BADCMD, NOFILE, LOADFAIL,
28 BADRELATIONSHIP, UNRESOLVED,
29 MISSING_INCLUDE};
30
31 CLI::App app{"Check consistency of OKS schema file\n"+
32 fmt::format("Return codes: {} Success, file is OK\n", Exitcode::SUCCESS)+
33 fmt::format(" {} Bad command line\n", Exitcode::BADCMD)+
34 fmt::format(" {} Failed to find file\n", Exitcode::NOFILE)+
35 fmt::format(" {} Failed to load file -- invalid schema\n", Exitcode::LOADFAIL)+
36 fmt::format(" {} File contains relationship to non loaded class\n", Exitcode::BADRELATIONSHIP)+
37 fmt::format(" {} File contains object with relationship to non loaded class/object\n", Exitcode::UNRESOLVED)+
38 fmt::format(" {} File refers to class in file not directly included\n", Exitcode::MISSING_INCLUDE)
39 };
40
41 std::string filename;
42 app.add_option("-f,--file", filename, "Schema file")
43 ->required();
44
45 CLI11_PARSE(app, argc, argv);
46
47 OksKernel kernel;
48 OksFile* file{nullptr};
49 try {
50 file = kernel.load_file(filename);
51 }
52 catch (FailedLoadFile& fail) {
53 TLOG() << fail.what() << "\n";
54 return Exitcode::LOADFAIL;
55 }
56 catch (CanNotOpenFile& fail) {
57 TLOG() << fail.what() << "\n";
58 return Exitcode::NOFILE;
59 }
60 catch (std::exception& exc) {
61 TLOG() << exc.what() << "\n";
62 return Exitcode::LOADFAIL;
63 }
64
65 if (file == nullptr) {
66 TLOG() << "Failed to load " << filename;
67 return Exitcode::LOADFAIL;
68 }
69
70 std::set<std::string> includes;
71 for (const auto& ifile : file->get_include_files()) {
72 includes.insert(ifile);
73 TLOG_DEBUG(2) << "direct inserting " << ifile << "\n";
74 }
75
76 Exitcode result=Exitcode::SUCCESS;
77
78 if (filename.ends_with(".schema.xml")) {
79 // Check classes defined in this schema file
80 for (auto [name, oks_class] : kernel.classes()) {
81
82 if (file->get_full_file_name() != oks_class->get_file()->get_full_file_name()) {
83 // Class not defined in this file
84 continue;
85 }
86
87 auto cfile = oks_class->get_file()->get_short_file_name();
88 if (cfile != file->get_short_file_name() && !includes.contains(cfile)) {
89 TLOG() << "Error " << filename << " misses include of " << cfile << " required by " << name;
90 if (result==Exitcode::SUCCESS) {
91 result = Exitcode::MISSING_INCLUDE;
92 }
93 }
94 auto relationships = oks_class->direct_relationships();
95 if (relationships != nullptr) {
96 for (auto rel: *relationships) {
97 auto rel_class = rel->get_class_type();
98 if (rel_class == nullptr) {
99 TLOG() << "Error class '" << name
100 << "' has relationship '" << rel->get_name()
101 << "' to a class '" << rel->get_type()
102 << "' that is not loaded\n";
103 if (result==Exitcode::SUCCESS) {
104 result = Exitcode::BADRELATIONSHIP;
105 }
106 }
107
108 }
109 }
110 // Could check super-classes but we wouldn't have got past the
111 // load if they referred to a missing class.
112 }
113 } else if (filename.ends_with(".data.xml")) {
114
115 auto check_relationship = [&](OksData* data) {
116 auto relobj = data->data.OBJECT;
117 if (relobj == nullptr) {
118 return;
119 }
120 auto ofile_name = relobj->get_file()->get_short_file_name();
121 if (file->get_short_file_name() != ofile_name && !includes.contains(ofile_name)) {
122 TLOG() << "Error " << filename << " misses include of " << ofile_name
123 << " required by " << relobj->GetId();
124 if (result==Exitcode::SUCCESS) {
125 result = Exitcode::MISSING_INCLUDE;
126 }
127 }
128 };
129
130 auto data_objs = kernel.create_list_of_data_objects(file);
131 for (auto obj : *data_objs) {
132 // Check that any objects defined in this data file have their
133 // corresponding schema file included directly in this file
134 auto oks_class = obj->GetClass();
135 auto cfile = oks_class->get_file()->get_short_file_name();
136 if (!includes.contains(cfile)) {
137 TLOG() << "Error " << filename << " misses include of " << cfile
138 << " required by " << obj->GetId()
139 << " of class " << oks_class->get_name();
140 if (result==Exitcode::SUCCESS) {
141 result = Exitcode::MISSING_INCLUDE;
142 }
143 }
144
145 // Check that any objects referenced by objects in this file are
146 // either defined in this file or one that is directly included
147 auto relationships = oks_class->all_relationships();
148 if (relationships != nullptr) {
149 for (auto rel: *relationships) {
150 auto relval = obj->GetRelationshipValue(rel->get_name());
151 if (relval == nullptr) {
152 continue;
153 }
154 if (rel->get_high_cardinality_constraint() == OksRelationship::Many) {
155 for(OksData::List::iterator iter = relval->data.LIST->begin();
156 iter != relval->data.LIST->end(); ++iter) {
157 check_relationship(*iter);
158 }
159 } else {
160 check_relationship(relval);
161 }
162 }
163 }
164 }
165 delete data_objs;
166 }
167
168 auto status = kernel.get_bind_objects_status();
169 if (!status.empty()) {
170 if (result==Exitcode::SUCCESS) {
171 result = Exitcode::UNRESOLVED;
172 }
173 }
174
175 return result;
176}
Cannot open file.
Definition kernel.hpp:140
Cannot load file.
Definition kernel.hpp:61
Provides interface to the OKS XML schema and data files.
Definition file.hpp:345
Provides interface to the OKS kernel.
Definition kernel.hpp:582
OksFile * load_file(const std::string &name, bool bind=true)
Load OKS database file.
Definition kernel.cpp:1793
std::list< OksObject * > * create_list_of_data_objects(OksFile *) const
Creates list of objects which belong to given file.
Definition kernel.cpp:4332
const OksClass::Map & classes() const
Get classes.
Definition kernel.hpp:1772
const std::string & get_bind_objects_status() const noexcept
Return status of oks objects binding.
Definition kernel.hpp:2000
virtual const char * what() const noexcept
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
#define TLOG(...)
Definition macro.hpp:22
msgpack::object obj
int main(int argc, char **argv)
the structure to pass common parameters to various read() methods of OksData and OksObject class
Definition object.hpp:454