knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
OntologyParser.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of KnowRob, please consult
3  * https://github.com/knowrob/knowrob for license details.
4  */
5 
6 #include <filesystem>
7 #include "knowrob/semweb/OntologyParser.h"
8 #include "knowrob/semweb/OntologyError.h"
9 #include "knowrob/semweb/owl.h"
10 #include "knowrob/semweb/PrefixRegistry.h"
11 #include "knowrob/semweb/ImportHierarchy.h"
12 #include "knowrob/knowrob.h"
13 #include "knowrob/Logger.h"
14 
15 namespace fs = std::filesystem;
16 using namespace knowrob;
17 
18 namespace knowrob {
19  struct RaptorUserData {
20  OntologyParser *parser;
21  TripleHandler callback;
22  };
23 }
24 
25 static void processTriple(void *userData, raptor_statement *statement) {
26  auto x = (RaptorUserData *) userData;
27  x->parser->add(statement, x->callback);
28 }
29 
30 static void procesNamespace([[maybe_unused]] void *userData, raptor_namespace *nspace) {
31  auto r_prefix = raptor_namespace_get_prefix(nspace);
32  if (!r_prefix) return;
33 
34  auto r_uri = raptor_namespace_get_uri(nspace);
35  if (!r_uri) return;
36  auto r_uriString = raptor_uri_as_string(r_uri);
37 
39  std::string_view((const char *) r_prefix),
40  std::string_view((const char *) r_uriString));
41 }
42 
43 static void raptor_log(void *, raptor_log_message *message) {
44  switch (message->level) {
45  case RAPTOR_LOG_LEVEL_ERROR:
46  case RAPTOR_LOG_LEVEL_FATAL:
47  KB_ERROR("[raptor] {}", message->text);
48  break;
49  case RAPTOR_LOG_LEVEL_WARN:
50  KB_WARN("[raptor] {}", message->text);
51  break;
52  case RAPTOR_LOG_LEVEL_NONE:
53  case RAPTOR_LOG_LEVEL_TRACE:
54  case RAPTOR_LOG_LEVEL_DEBUG:
55  case RAPTOR_LOG_LEVEL_INFO:
56  break;
57  }
58 }
59 
60 OntologyParser::OntologyParser(const std::string_view &fileURI, knowrob::semweb::TripleFormat format) {
61  world_ = createWorld();
62  parser_ = createParser(format);
63  // raptor can report namespaces
64  raptor_parser_set_namespace_handler(parser_, nullptr, procesNamespace);
65 
66  if (fs::exists(fileURI)) {
67  // Parse the content of a local file URI
68  auto escapedString = raptor_uri_filename_to_uri_string(fileURI.data());
69  uri_ = raptor_new_uri(world_, (unsigned char *) escapedString);
70  doParse_ = [this]() {
71  return raptor_parser_parse_file(parser_, uri_, uriBase_);
72  };
73  raptor_free_memory(escapedString);
74  } else {
75  // Parse the content from a remote file URI
76  uri_ = raptor_new_uri(world_, (const unsigned char *) fileURI.data());
77  doParse_ = [this]() {
78  return raptor_parser_parse_uri(parser_, uri_, uriBase_);
79  };
80  }
81  uriBase_ = raptor_uri_copy(uri_);
82 }
83 
85  raptor_free_parser(parser_);
86  raptor_free_uri(uri_);
87  raptor_free_uri(uriBase_);
88  raptor_free_world(world_);
89 }
90 
91 raptor_world *OntologyParser::createWorld() {
92  auto world = raptor_new_world();
93  // redirect log messages to the knowrob logger
94  raptor_world_set_log_handler(world, nullptr, raptor_log);
95  if (raptor_world_open(world) != 0) {
96  throw OntologyError("failed to initialize raptor library.");
97  }
98  return world;
99 }
100 
102  return raptor_new_parser(world_, tripleFormatMimeType(format).data());
103 }
104 
106  if (frame_) {
107  if (frame_->confidence.has_value()) {
108  triple->setConfidence(frame_->confidence.value());
109  triple->setIsUncertain(true);
110  }
111  if (frame_->perspective) {
112  triple->setPerspective(frame_->perspective->iri());
113  }
114  if (frame_->uncertain) {
115  triple->setIsUncertain(true);
116  }
117  if (frame_->occasional) {
118  triple->setIsOccasional(true);
119  }
120  if (frame_->begin.has_value()) {
121  triple->setBegin(frame_->begin.value());
122  }
123  if (frame_->end.has_value()) {
124  triple->setEnd(frame_->end.value());
125  }
126  }
127 }
128 
129 void OntologyParser::add(raptor_statement *statement, const TripleHandler &callback) {
130  auto batchSize = GlobalSettings::batchSize();
131  if (!currentBatch_) {
132  if (origin_.empty()) {
133  KB_WARN("No origin set for ontology parser, falling back to \"user\" origin.");
134  currentBatch_ = std::make_shared<RaptorContainer>(batchSize, ImportHierarchy::ORIGIN_USER);
135  } else {
136  currentBatch_ = std::make_shared<RaptorContainer>(batchSize, origin_);
137  }
138  }
139  // add to batch, map into knowrob data structures
140  auto triple = currentBatch_->add(statement);
141  if (filter_ && !filter_(*triple)) {
142  currentBatch_->rollbackLast();
143  return;
144  }
145  applyFrame(triple);
146  // remember imports
147  if (triple && owl::imports->stringForm() == triple->predicate()) {
148  imports_.emplace_back(triple->valueAsString());
149  }
150  // flush if batch is full
151  if (currentBatch_->size() >= batchSize) {
152  flush(callback);
153  }
154 }
155 
156 void OntologyParser::flush(const TripleHandler &callback) {
157  if (!currentBatch_) return;
158  // reduce vector size to actual number of elements
159  currentBatch_->shrink();
160  // call the callback with the current batch, note that the callback
161  // holds a reference on the batch which is only deleted after the callback lifts the reference.
162  //KB_DEBUG("flushing {} triples with origin {}", currentBatch_->size(), currentBatch_->origin());
163  callback(currentBatch_);
164  currentBatch_ = nullptr;
165 }
166 
167 
168 bool OntologyParser::run(const TripleHandler &callback) {
169  // call processTriple for each loaded triple
170  RaptorUserData userData = {const_cast<OntologyParser *>(this), callback};
171  raptor_parser_set_statement_handler(parser_, &userData, processTriple);
172 
173  // make sure blanks are generated with proper prefix.
174  raptor_world_set_generate_bnodeid_parameters(
175  raptor_parser_get_world(parser_),
176  blankPrefix_.data(), 1);
177 
178  auto exit_status = doParse_();
179  if (exit_status == 0) {
180  flush(callback);
181  } else {
182  currentBatch_ = nullptr;
183  }
184  return (exit_status == 0);
185 }
#define KB_ERROR
Definition: Logger.h:28
#define KB_WARN
Definition: Logger.h:27
static uint32_t batchSize()
Definition: knowrob.h:68
static constexpr std::string_view ORIGIN_USER
raptor_parser * parser_
raptor_parser * createParser(knowrob::semweb::TripleFormat format)
OntologyParser(const std::string_view &fileURI, semweb::TripleFormat format)
void flush(const TripleHandler &callback)
bool run(const TripleHandler &callback)
std::function< int()> doParse_
static raptor_world * createWorld()
GraphSelectorPtr frame_
std::vector< std::string > imports_
void applyFrame(Triple *triple)
void add(raptor_statement *statement, const TripleHandler &callback)
std::shared_ptr< RaptorContainer > currentBatch_
static void registerPrefix(std::string_view prefix, std::string_view uri)
void setConfidence(double confidence)
Definition: Triple.h:307
virtual void setPerspective(std::string_view perspective)=0
void setIsUncertain(bool isUncertain)
Definition: Triple.h:292
void setIsOccasional(bool isOccasional)
Definition: Triple.h:287
void setBegin(double begin)
Definition: Triple.h:297
void setEnd(double end)
Definition: Triple.h:302
const IRIAtomPtr imports
Definition: owl.h:15
std::string_view tripleFormatMimeType(TripleFormat format)
std::function< void(const TripleContainerPtr &)> TripleHandler