| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #ifndef MARMOTTA_RDF_MODEL_H |
| #define MARMOTTA_RDF_MODEL_H |
| |
| #include <string> |
| #include <iostream> |
| |
| #include "model/model.pb.h" |
| |
| /* |
| * This namespace contains the model definition for the C++ version of |
| * Marmotta. |
| * |
| * All objects are backed by proto messages, but offer more convenient |
| * high-level constructs. |
| * |
| * All objects implement copy as well as efficient move operations for |
| * constructors and assignment operators. Converting back and forth between |
| * a proto message and a model object is therefore very cheap. |
| */ |
| namespace marmotta { |
| namespace rdf { |
| |
| /** |
| * RDF namespace, consisting of a prefix and a URI. |
| */ |
| class Namespace { |
| public: |
| /* |
| * default constructor, creates empty namespace. |
| */ |
| Namespace() {} |
| |
| /** |
| * Create a new namespace from the given prefix and uri (0-terminated |
| * C-style strings). |
| */ |
| Namespace(const char* prefix, const char* uri) { |
| // Raptor sends us a nullptr for the base NS. |
| if (prefix != nullptr) { |
| internal_.set_prefix(prefix); |
| } |
| internal_.set_uri(uri); |
| } |
| |
| /** |
| * Create a new namespace from the given prefix and uri. |
| */ |
| Namespace(const std::string &prefix, const std::string &uri) { |
| internal_.set_prefix(prefix); |
| internal_.set_uri(uri); |
| } |
| |
| /** |
| * Create a new namespace from a namespace proto message. |
| */ |
| Namespace(const proto::Namespace &ns) : internal_(ns) { }; |
| |
| /** |
| * Create a new namespace from a namespace proto message (move constructor). |
| */ |
| Namespace(proto::Namespace &&ns) { |
| internal_.Swap(&ns); |
| }; |
| |
| /** |
| * Get the prefix used to identify this namespace. |
| */ |
| const std::string &getPrefix() const { |
| return internal_.prefix(); |
| } |
| |
| /** |
| * Set the prefix used to identify this namespace. |
| */ |
| void setPrefix(const std::string &prefix) { |
| internal_.set_prefix(prefix); |
| } |
| |
| /** |
| * Get the URI identified by this namespace. |
| */ |
| const std::string &getUri() const { |
| return internal_.uri(); |
| } |
| |
| /** |
| * Set the URI identified by this namespace. |
| */ |
| void setUri(const std::string &uri) { |
| internal_.set_uri(uri); |
| } |
| |
| /** |
| * Get a reference to the proto message wrapped by the Namespace object. |
| */ |
| const proto::Namespace& getMessage() const { |
| return internal_; |
| } |
| |
| private: |
| proto::Namespace internal_; |
| }; |
| |
| /** |
| * RDF URI implementation, backed by a URI proto message. |
| */ |
| class URI { |
| public: |
| /** |
| * Default constructor, creates an empty URI. |
| */ |
| URI() { } |
| |
| /** |
| * Create an URI object from the URI string passed as argument. |
| */ |
| URI(const std::string &uri) { |
| internal_.set_uri(uri); |
| } |
| |
| /** |
| * Create an URI object from the URI string passed as argument. |
| */ |
| URI(const char* uri) { |
| internal_.set_uri(uri); |
| } |
| |
| /** |
| * Create an URI object from the proto message passed as argument (copy |
| * constructor). |
| */ |
| URI(const proto::URI &uri) : internal_(uri) { } |
| |
| /** |
| * Create an URI object from the proto message passed as argument (move |
| * constructor, the original proto message is invalidated). |
| */ |
| URI(proto::URI &&uri) { |
| internal_.Swap(&uri); |
| } |
| |
| /** |
| * Copy constructor, create an URI from another URI. |
| */ |
| URI(const URI &other) : internal_(other.internal_) {}; |
| |
| /** |
| * Move constructor, create an URI from another URI, invalidating the |
| * original URI. |
| */ |
| URI(URI&& uri) { |
| internal_.Swap(&uri.internal_); |
| } |
| |
| URI & operator=(proto::URI &&other); |
| URI & operator=(const URI &other); |
| URI & operator=(URI &&other); |
| |
| /** |
| * Get the string representation of the URI. |
| */ |
| const std::string &getUri() const { |
| return internal_.uri(); |
| } |
| |
| /** |
| * Set the string representation of the URI. |
| */ |
| void setUri(const std::string &uri) { |
| internal_.set_uri(uri); |
| } |
| |
| /** |
| * Get a canonical string representation of the URI. |
| */ |
| const std::string &stringValue() const { |
| return internal_.uri(); |
| } |
| |
| /** |
| * Get a Turtle representation of the URI. |
| */ |
| std::string as_turtle() const; |
| |
| /** |
| * Get a reference to the proto message wrapped by the URI object. |
| */ |
| const proto::URI& getMessage() const { |
| return internal_; |
| } |
| |
| private: |
| proto::URI internal_; |
| |
| friend class Value; |
| friend class Resource; |
| friend class Statement; |
| }; |
| |
| /** |
| * RDF Blank node implementation, backed by a BNode proto message. |
| */ |
| class BNode { |
| public: |
| /** |
| * Default constructor, creates empty BNode. |
| */ |
| BNode() { } |
| |
| /** |
| * Create a new BNode using the ID passed as argument. |
| */ |
| BNode(const std::string &id) { |
| internal_.set_id(id); |
| } |
| |
| /** |
| * Create a new BNode using the ID passed as argument. |
| */ |
| BNode(const char* id) { |
| internal_.set_id(id); |
| } |
| |
| /** |
| * Create a new BNode from the proto message passed as argument (copy |
| * constructor). |
| */ |
| BNode(const proto::BNode &n) : internal_(n) { } |
| |
| /** |
| * Create a new BNode from the proto message passed as argument (move |
| * constructor, original message is invalidated). |
| */ |
| BNode(proto::BNode &&n) { |
| internal_.Swap(&n); |
| }; |
| |
| /** |
| * Copy constructor, create a BNode from another BNode. |
| */ |
| BNode(const BNode &n) : internal_(n.internal_) {}; |
| |
| /** |
| * Move constructor, create a BNode from another BNode. The other BNode |
| * is invalidated. |
| */ |
| BNode(BNode &&n) { |
| internal_.Swap(&n.internal_); |
| }; |
| |
| BNode & operator=(proto::BNode &&other);; |
| BNode & operator=(const BNode &other);; |
| BNode & operator=(BNode &&other);; |
| |
| /** |
| * Return the id of this blank node. |
| */ |
| const std::string &getId() const { |
| return internal_.id(); |
| } |
| |
| /** |
| * Set the id of this blank node. |
| */ |
| void setId(const std::string &id) { |
| internal_.set_id(id); |
| } |
| |
| /** |
| * Get a canonical string representation of the URI. |
| */ |
| const std::string &stringValue() const { |
| return internal_.id(); |
| } |
| |
| /** |
| * Get a Turtle representation of the URI. |
| */ |
| std::string as_turtle() const; |
| |
| /** |
| * Get a reference to the proto message wrapped by the BNode object. |
| */ |
| const proto::BNode& getMessage() const { |
| return internal_; |
| } |
| |
| private: |
| proto::BNode internal_; |
| |
| friend class Value; |
| friend class Resource; |
| }; |
| |
| |
| class StringLiteral { |
| public: |
| StringLiteral() { } |
| |
| StringLiteral(const std::string &content) { |
| internal_.set_content(content); |
| } |
| |
| StringLiteral(const std::string &content, const std::string &language) { |
| internal_.set_content(content); |
| internal_.set_language(language); |
| } |
| |
| StringLiteral(const proto::StringLiteral &other) : internal_(other) { }; |
| |
| StringLiteral(proto::StringLiteral &&other) { |
| internal_.Swap(&other); |
| } |
| |
| StringLiteral(const StringLiteral &other) : internal_(other.internal_) {}; |
| |
| StringLiteral(StringLiteral &&other) { |
| internal_.Swap(&other.internal_); |
| } |
| |
| StringLiteral & operator=(proto::StringLiteral &&other);; |
| StringLiteral & operator=(const StringLiteral &other);; |
| StringLiteral & operator=(StringLiteral &&other);; |
| |
| const std::string &getContent() const { |
| return internal_.content(); |
| } |
| |
| void setContent(std::string &content) { |
| internal_.set_content(content); |
| } |
| |
| const std::string &getLanguage() const { |
| return internal_.language(); |
| } |
| |
| void setLanguage(std::string &language) { |
| internal_.set_language(language); |
| } |
| |
| const std::string &stringValue() const { |
| return internal_.content(); |
| } |
| |
| const proto::StringLiteral& getMessage() const { |
| return internal_; |
| } |
| |
| std::string as_turtle() const; |
| |
| private: |
| proto::StringLiteral internal_; |
| |
| friend class Value; |
| }; |
| |
| |
| class DatatypeLiteral { |
| public: |
| DatatypeLiteral() { } |
| |
| DatatypeLiteral(const std::string &content, URI const &datatype) { |
| internal_.set_content(content); |
| internal_.mutable_datatype()->MergeFrom(datatype.getMessage()); |
| } |
| |
| DatatypeLiteral(const proto::DatatypeLiteral &other) : internal_(other) { }; |
| |
| DatatypeLiteral(proto::DatatypeLiteral &&other) { |
| internal_.Swap(&other); |
| } |
| |
| DatatypeLiteral(const DatatypeLiteral &other) : internal_(other.internal_) { }; |
| |
| DatatypeLiteral(DatatypeLiteral &&other) { |
| internal_.Swap(&other.internal_); |
| } |
| |
| DatatypeLiteral & operator=(proto::DatatypeLiteral &&other);; |
| DatatypeLiteral & operator=(const DatatypeLiteral &other);; |
| DatatypeLiteral & operator=(DatatypeLiteral &&other);; |
| |
| const std::string &getContent() const { |
| return internal_.content(); |
| } |
| |
| void setContent(std::string &content) { |
| internal_.set_content(content); |
| } |
| |
| URI getDatatype() const { |
| return URI(internal_.datatype()); |
| } |
| |
| void setDatatype(const URI &datatype) { |
| internal_.mutable_datatype()->MergeFrom(datatype.getMessage()); |
| } |
| |
| const std::string &stringValue() const { |
| return internal_.content(); |
| } |
| |
| int intValue() const { |
| return std::stoi(getContent()); |
| } |
| |
| operator int() const { |
| return std::stoi(getContent()); |
| } |
| |
| long long longValue() const { |
| return std::stoll(getContent()); |
| } |
| |
| operator long long() const { |
| return std::stoll(getContent()); |
| } |
| |
| float floatValue() const { |
| return std::stof(getContent()); |
| } |
| |
| operator float() const { |
| return std::stof(getContent()); |
| } |
| |
| double doubleValue() const { |
| return std::stod(getContent()); |
| } |
| |
| operator double() const { |
| return std::stod(getContent()); |
| } |
| |
| const proto::DatatypeLiteral& getMessage() const { |
| return internal_; |
| } |
| |
| std::string as_turtle() const; |
| |
| private: |
| proto::DatatypeLiteral internal_; |
| |
| friend class Value; |
| }; |
| |
| /** |
| * Value is a polymorphic, but strictly typed generic implementation for URI, |
| * BNode and Literal. Copy/move constructors and assignment operators allow |
| * using URI, BNode and Literal wherever a Value is required. |
| */ |
| class Value { |
| public: |
| enum { |
| URI = 1, BNODE, STRING_LITERAL, DATATYPE_LITERAL, NONE |
| } type; |
| |
| Value() : type(NONE) { } |
| |
| Value(const proto::Value& v); |
| |
| Value(proto::Value&& v); |
| |
| Value(const marmotta::rdf::URI &uri) : type(URI) { |
| internal_.mutable_resource()->mutable_uri()->MergeFrom(uri.getMessage()); |
| } |
| |
| Value(marmotta::rdf::URI &&uri) : type(URI) { |
| internal_.mutable_resource()->mutable_uri()->Swap(&uri.internal_); |
| } |
| |
| Value(const BNode &bnode) : type(BNODE) { |
| internal_.mutable_resource()->mutable_bnode()->MergeFrom(bnode.getMessage()); |
| } |
| |
| Value(BNode &&bnode) : type(BNODE) { |
| internal_.mutable_resource()->mutable_bnode()->Swap(&bnode.internal_); |
| } |
| |
| Value(const StringLiteral &sliteral) : type(STRING_LITERAL) { |
| internal_.mutable_literal()->mutable_stringliteral()->MergeFrom(sliteral.getMessage()); |
| }; |
| |
| Value(StringLiteral &&sliteral) : type(STRING_LITERAL) { |
| internal_.mutable_literal()->mutable_stringliteral()->Swap(&sliteral.internal_); |
| }; |
| |
| Value(const DatatypeLiteral &dliteral) : type(DATATYPE_LITERAL) { |
| internal_.mutable_literal()->mutable_dataliteral()->MergeFrom(dliteral.getMessage()); |
| }; |
| |
| Value(DatatypeLiteral &&dliteral) : type(DATATYPE_LITERAL) { |
| internal_.mutable_literal()->mutable_dataliteral()->Swap(&dliteral.internal_); |
| }; |
| |
| Value(const std::string &literal) : type(STRING_LITERAL) { |
| internal_.mutable_literal()->mutable_stringliteral()->set_content(literal); |
| }; |
| |
| Value(const char* literal) : type(STRING_LITERAL) { |
| internal_.mutable_literal()->mutable_stringliteral()->set_content(literal); |
| }; |
| |
| |
| Value &operator=(const rdf::URI &uri); |
| |
| Value &operator=(const rdf::BNode &bnode); |
| |
| Value &operator=(const rdf::StringLiteral &literal); |
| |
| Value &operator=(const rdf::DatatypeLiteral &literal); |
| |
| Value &operator=(rdf::URI &&uri); |
| |
| Value &operator=(rdf::BNode &&bnode); |
| |
| Value &operator=(rdf::StringLiteral &&literal); |
| |
| Value &operator=(rdf::DatatypeLiteral &&literal); |
| |
| std::string stringValue() const; |
| |
| std::string as_turtle() const; |
| |
| const proto::Value& getMessage() const { |
| return internal_; |
| } |
| private: |
| proto::Value internal_; |
| |
| friend class Statement; |
| }; |
| |
| |
| class Resource { |
| public: |
| enum { |
| URI, BNODE, NONE |
| } type; |
| |
| Resource() : type(NONE) { }; |
| |
| Resource(const proto::Resource& v); |
| |
| Resource(proto::Resource&& v); |
| |
| Resource(const std::string &uri) : type(URI) { |
| internal_.mutable_uri()->set_uri(uri); |
| }; |
| |
| Resource(const char* uri) : type(URI) { |
| internal_.mutable_uri()->set_uri(uri); |
| }; |
| |
| Resource(const rdf::URI &uri) : type(URI) { |
| internal_.mutable_uri()->MergeFrom(uri.getMessage()); |
| } |
| |
| Resource(const rdf::BNode &bnode) : type(BNODE) { |
| internal_.mutable_bnode()->MergeFrom(bnode.getMessage()); |
| } |
| |
| Resource(rdf::URI &&uri) : type(URI) { |
| internal_.mutable_uri()->Swap(&uri.internal_); |
| } |
| |
| Resource(rdf::BNode &&bnode) : type(BNODE) { |
| internal_.mutable_bnode()->Swap(&bnode.internal_); |
| } |
| |
| Resource & operator=(const rdf::URI &uri); |
| |
| Resource & operator=(const rdf::BNode &bnode); |
| |
| Resource & operator=(rdf::URI &&uri); |
| |
| Resource & operator=(rdf::BNode &&bnode); |
| |
| std::string stringValue() const; |
| |
| std::string as_turtle() const; |
| |
| const proto::Resource& getMessage() const { |
| return internal_; |
| } |
| private: |
| proto::Resource internal_; |
| |
| friend class Statement; |
| }; |
| |
| |
| class Statement { |
| public: |
| Statement() {} |
| |
| Statement(const Statement& other) : internal_(other.internal_) {} |
| Statement(Statement&& other) { |
| internal_.Swap(&other.internal_); |
| } |
| |
| Statement(const proto::Statement& other) : internal_(other) {} |
| Statement(proto::Statement&& other) { |
| internal_.Swap(&other); |
| } |
| |
| Statement & operator=(const proto::Statement &other); |
| Statement & operator=(proto::Statement &&other); |
| Statement & operator=(const Statement &other); |
| Statement & operator=(Statement &&other); |
| |
| |
| Statement(Resource const &subject, URI const &predicate, Value const &object) { |
| internal_.mutable_subject()->MergeFrom(subject.getMessage()); |
| internal_.mutable_predicate()->MergeFrom(predicate.getMessage()); |
| internal_.mutable_object()->MergeFrom(object.getMessage()); |
| } |
| |
| |
| Statement(Resource const &subject, URI const &predicate, Value const &object, Resource const &context) { |
| internal_.mutable_subject()->MergeFrom(subject.getMessage()); |
| internal_.mutable_predicate()->MergeFrom(predicate.getMessage()); |
| internal_.mutable_object()->MergeFrom(object.getMessage()); |
| internal_.mutable_context()->MergeFrom(context.getMessage()); |
| } |
| |
| Statement(Resource &&subject, URI &&predicate, Value &&object) { |
| internal_.mutable_subject()->Swap(&subject.internal_); |
| internal_.mutable_predicate()->Swap(&predicate.internal_); |
| internal_.mutable_object()->Swap(&object.internal_); |
| } |
| |
| |
| Statement(Resource &&subject, URI &&predicate, Value &&object, Resource &&context) { |
| internal_.mutable_subject()->Swap(&subject.internal_); |
| internal_.mutable_predicate()->Swap(&predicate.internal_); |
| internal_.mutable_object()->Swap(&object.internal_); |
| internal_.mutable_context()->Swap(&context.internal_); |
| } |
| |
| |
| Resource getSubject() const { |
| return Resource(internal_.subject()); |
| } |
| |
| void setSubject(Resource const &subject) { |
| internal_.mutable_subject()->MergeFrom(subject.getMessage()); |
| } |
| |
| URI getPredicate() const { |
| return URI(internal_.predicate()); |
| } |
| |
| void setPredicate(URI const &predicate) { |
| internal_.mutable_predicate()->MergeFrom(predicate.getMessage()); |
| } |
| |
| Value getObject() const { |
| return Value(internal_.object()); |
| } |
| |
| void setObject(Value const &object) { |
| internal_.mutable_object()->MergeFrom(object.getMessage()); |
| } |
| |
| Resource getContext() const { |
| return Resource(internal_.context()); |
| } |
| |
| void setContext(Resource const &context) { |
| internal_.mutable_context()->MergeFrom(context.getMessage()); |
| } |
| |
| bool hasContext() const { |
| return internal_.has_context(); |
| } |
| |
| std::string as_turtle() const; |
| |
| const proto::Statement& getMessage() const { |
| return internal_; |
| } |
| private: |
| proto::Statement internal_; |
| }; |
| |
| |
| } // namespace rdf |
| } // namespace marmotta |
| |
| |
| #endif //MARMOTTA_RDF_MODEL_H |