/* Ousía Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "Document.hpp" #include #include namespace ousia { namespace model { int DocumentEntity::getFieldDescriptorIndex(const std::string &fieldName) { const NodeVector &fds = descriptor->getFieldDescriptors(); unsigned int f = 0; // look if we have an empty name. if (fieldName == "") { // in that case we look for a default field. // First: Do we only have one field? if (fds.size() == 1) { // if so we return that one. return f; } // Second: Do we have a TREE field? for (auto &fd : fds) { if (fd->getFieldType() == FieldDescriptor::FieldType::TREE) { return f; } f++; } } else { // otherwise we return the FieldDescriptor with the correct name (if // such a descriptor exists). for (auto &fd : fds) { if (fd->getName() == fieldName) { return f; } f++; } } return -1; } void DocumentEntity::getField(NodeVector &res, const std::string &fieldName) { int f = getFieldDescriptorIndex(fieldName); if (f < 0) { NodeVector empty{this}; res = NodeVector(this); } res = fields[f]; } NodeVector &DocumentEntity::getField( Rooted fieldDescriptor) { const NodeVector &fds = descriptor->getFieldDescriptors(); int f = 0; for (auto &fd : fds) { if (fd->getName() == fieldDescriptor->getName() && fd->getFieldType() == fieldDescriptor->getFieldType()) { return fields[f]; } f++; } throw OusiaException( "The given FieldDescriptor is not specified in the Descriptor of this " "node."); } static Rooted resolveDescriptor( std::vector> domains, const std::string &className) { // iterate over all domains. for (auto &d : domains) { // use the actual resolve method. std::vector> resolved = d->resolve(className); // if we don't find anything, continue. if (resolved.size() == 0) { continue; } // Otherwise take the first valid result. for (auto &r : resolved) { Managed *m = &(*r); StructuredClass *c = dynamic_cast(m); if (c != nullptr) { return Rooted(c); } } } return {nullptr}; } Rooted StructuredEntity::buildRootEntity( Handle document, std::vector> domains, const std::string &className, Variant attributes, std::string name) { // If the parent is not set, we can not build the entity. if (document == nullptr) { return {nullptr}; } // If we can not find the correct descriptor, we can not build the entity // either. Rooted descriptor = resolveDescriptor(domains, className); if (descriptor == nullptr) { return {nullptr}; } // Then construct the StructuredEntity itself. Rooted root{ new StructuredEntity(document->getManager(), document, descriptor, attributes, std::move(name))}; // append it to the document. document->setRoot(root); // and return it. return root; } Rooted StructuredEntity::buildEntity( Handle parent, std::vector> domains, const std::string &className, const std::string &fieldName, Variant attributes, std::string name) { // If the parent is not set, we can not build the entity. if (parent == nullptr) { return {nullptr}; } // If we can not find the correct descriptor, we can not build the entity // either. Rooted descriptor = resolveDescriptor(domains, className); if (descriptor == nullptr) { return {nullptr}; } // Then construct the StructuredEntity itself. Rooted entity{new StructuredEntity( parent->getManager(), parent, descriptor, attributes, std::move(name))}; // if the field does not exist, return null handle as well. if (!parent->hasField(fieldName)) { return {nullptr}; } // append the new entity to the right field. NodeVector field(parent); parent->getField(field, fieldName); field.push_back(entity); // and return it. return entity; } Rooted DocumentPrimitive::buildEntity( Handle parent, Variant content, const std::string &fieldName) { // If the parent is not set, we can not build the entity. if (parent == nullptr) { return {nullptr}; } // Then construct the StructuredEntity itself. Rooted entity{ new DocumentPrimitive(parent->getManager(), parent, content)}; // if the field does not exist, return null handle as well. if (!parent->hasField(fieldName)) { return {nullptr}; } // append the new entity to the right field. NodeVector field(parent); parent->getField(field, fieldName); field.push_back(entity); // and return it. return entity; } /* Type registrations */ const Rtti Document_Rtti{"Document"}; const Rtti DocumentEntity_Rtti{"DocumentEntity"}; const Rtti AnnotationEntity_Rtti{"AnnotationEntity", {&DocumentEntity_Rtti}}; const Rtti StructuredEntity_Rtti{"StructuredEntity", {&DocumentEntity_Rtti}}; const Rtti DocumentPrimitive_Rtti{"DocumentPrimitive", {&StructuredEntity_Rtti}}; const Rtti Anchor_Rtti{"Anchor", {&StructuredEntity_Rtti}}; } }