diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/model/Document.cpp | 104 | ||||
| -rw-r--r-- | src/core/model/Document.hpp | 100 | 
2 files changed, 200 insertions, 4 deletions
diff --git a/src/core/model/Document.cpp b/src/core/model/Document.cpp index 31b22e3..709981b 100644 --- a/src/core/model/Document.cpp +++ b/src/core/model/Document.cpp @@ -58,7 +58,7 @@ int DocumentEntity::getFieldDescriptorIndex(const std::string &fieldName)  }  void DocumentEntity::getField(ManagedVector<StructuredEntity> &res, -              const std::string &fieldName) +                              const std::string &fieldName)  {  	int f = getFieldDescriptorIndex(fieldName);  	if (f < 0) { @@ -85,6 +85,108 @@ ManagedVector<StructuredEntity> &DocumentEntity::getField(  	    "The given FieldDescriptor is not specified in the Descriptor of this "  	    "node.");  } + +static Rooted<StructuredClass> resolveDescriptor( +    std::vector<Handle<Domain>> domains, const std::string &className) +{ +	// iterate over all domains. +	for (auto &d : domains) { +		// use the actual resolve method. +		std::vector<Rooted<Managed>> 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<StructuredClass *>(m); +			if (c != nullptr) { +				return Rooted<StructuredClass>(c); +			} +		} +	} +	return {nullptr}; +} + +Rooted<StructuredEntity> StructuredEntity::buildRootEntity( +    Handle<Document> document, std::vector<Handle<Domain>> 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<StructuredClass> descriptor = resolveDescriptor(domains, className); +	if (descriptor == nullptr) { +		return {nullptr}; +	} +	// Then construct the StructuredEntity itself. +	Rooted<StructuredEntity> 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> StructuredEntity::buildEntity( +    Handle<DocumentEntity> parent, std::vector<Handle<Domain>> 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<StructuredClass> descriptor = resolveDescriptor(domains, className); +	if (descriptor == nullptr) { +		return {nullptr}; +	} +	// Then construct the StructuredEntity itself. +	Rooted<StructuredEntity> 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. +	ManagedVector<StructuredEntity> field{parent}; +	parent->getField(field, fieldName); +	field.push_back(entity); + +	// and return it. +	return entity; +} + +Rooted<DocumentPrimitive> DocumentPrimitive::buildEntity( +    Handle<DocumentEntity> 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<DocumentPrimitive> 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. +	ManagedVector<StructuredEntity> field{parent}; +	parent->getField(field, fieldName); +	field.push_back(entity); + +	// and return it. +	return entity; +}  }  } diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index a31e52f..15a4599 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -80,6 +80,7 @@ namespace model {  class StructuredEntity;  class AnnotationEntity; +class Document;  /**   * A DocumentEntity is the common superclass for StructuredEntities and @@ -110,8 +111,11 @@ public:  	{  		// TODO: Validation at construction time?  		// insert empty vectors for each field. -		for (size_t f = 0; f < descriptor->getFieldDescriptors().size(); f++) { -			fields.push_back(ManagedVector<StructuredEntity>(this)); +		if (!descriptor.isNull()) { +			for (size_t f = 0; f < descriptor->getFieldDescriptors().size(); +			     f++) { +				fields.push_back(ManagedVector<StructuredEntity>(this)); +			}  		}  	} @@ -202,6 +206,57 @@ public:  	}  	ManagedVector<AnnotationEntity> &getAnnotations() { return annotations; } + +	/** +	 * This builds the root StructuredEntity for the given document. It +	 * automatically appends the newly build entity to the given document. +	 * +	 * @param document   is the document this entity shall be build for. The +	 *                   resulting entity will automatically be appended to that +	 *                   document. Also the manager of that document will be +	 *                   used to register the new node. +	 * @param domains    are the domains that are used to find the +	 *                   StructuredClass for the new node. The domains will be +	 *                   searched in the given order. +	 * @param className  is the name of the StructuredClass. +	 * @param attributes are the attributes of the new node in terms of a Struct +	 *                   variant (empty per default). +	 * @param name       is the name of this StructuredEntity (empty per +	 *                   default). +	 * @return           the newly created StructuredEntity or a nullptr if some +	 *                   input handle was empty or the given domains did not +	 *                   contain a StructuredClass with the given name. +	 */ +	static Rooted<StructuredEntity> buildRootEntity( +	    Handle<Document> document, std::vector<Handle<Domain>> domains, +	    const std::string &className, Variant attributes = Variant(), +	    std::string name = ""); + +	/** +	 * This builds a StructuredEntity as child of the given DocumentEntity. It +	 * automatically appends the newly build entity to its parent. +	 * +	 * @param parent     is the parent DocumentEntity. The newly constructed +	 *                   StructuredEntity will automatically be appended to it. +	 * @param domains    are the domains that are used to find the +	 *                   StructuredClass for the new node. The domains will be +	 *                   searched in the given order. +	 * @param className  is the name of the StructuredClass. +	 * @param fieldName  is the name of the field where the newly constructed +	 *                   StructuredEntity shall be appended. +	 * @param attributes are the attributes of the new node in terms of a Struct +	 *                   variant (empty per default). +	 * @param name       is the name of this StructuredEntity (empty per +	 *                   default). +	 * +	 * @return           the newly created StructuredEntity or a nullptr if some +	 *                   input handle was empty or the given domains did not +	 *                   contain a StructuredClass with the given name. +	 */ +	static Rooted<StructuredEntity> buildEntity( +	    Handle<DocumentEntity> parent, std::vector<Handle<Domain>> domains, +	    const std::string &className, const std::string &fieldName = "", +	    Variant attributes = Variant(), std::string name = "");  };  /** @@ -211,7 +266,7 @@ public:   */  class DocumentPrimitive : public StructuredEntity {  public: -	DocumentPrimitive(Manager &mgr, Handle<StructuredEntity> parent, +	DocumentPrimitive(Manager &mgr, Handle<DocumentEntity> parent,  	                  Variant content)  	    : StructuredEntity(mgr, parent, nullptr, std::move(content))  	{ @@ -220,6 +275,25 @@ public:  	Variant getContent() const { return getAttributes(); }  	// TODO: Override such methods like "getField" to disable them? + +	/** +	 * This builds a DocumentPrimitive as child of the given DocumentEntity. It +	 * automatically appends the newly build entity to its parent. +	 * +	 * @param parent     is the parent DocumentEntity. The newly constructed +	 *                   DocumentPrimitive will automatically be appended to it. +	 * @param content    is the primitive content of the new node in terms of a +	 *                   Struct variant. +	 * @param fieldName  is the name of the field where the newly constructed +	 *                   StructuredEntity shall be appended. +	 * +	 * @return           the newly created StructuredEntity or a nullptr if some +	 *                   input handle was empty or the given domains did not +	 *                   contain a StructuredClass with the given name. +	 */ +	static Rooted<DocumentPrimitive> buildEntity( +	    Handle<DocumentEntity> parent,  +	    Variant content, const std::string &fieldName = "");  };  /** @@ -284,6 +358,26 @@ public:  	Rooted<Anchor> getEnd() { return end; }  }; + +/** + * A Document is mainly a wrapper for the Root structure node of the Document + * Graph. + */ +class Document : public Node { +private: +	Owned<StructuredEntity> root; + +public: +	Document(Manager &mgr, std::string name) +	    // TODO: Can a document have a parent? +	    : Node(mgr, std::move(name), nullptr) +	{ +	} + +	void setRoot(Handle<StructuredEntity> root) { root = acquire(root); }; + +	Rooted<StructuredEntity> getRoot() const { return root; } +};  }  }  | 
