blob: 6793f8563a7392d7287fc49809024d54c1ec3276 [file] [log] [blame]
/*
* 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