//....................... // Вспомогательные методы //....................... /// <summary> /// производит (насильственное) вставление элемента в модель, перед применением нужно делать проверки, /// используется в AddElement /// </summary> /// <param name="element"> /// The element. /// </param> private void IncludeItem(XElement element) { SNode item = this.CreateRecord(element); // Привязать прямые ссылки foreach (SObjectLink olink in item.DirectObjectLinks()) { XName target_id = olink.TargetId; SResource target_resource; if (resources.ContainsKey(target_id)) { target_resource = resources[target_id]; } else { target_resource = new SResource(target_id); resources.Add(target_id, target_resource); } olink._target_resource = target_resource; if (target_resource._inverseProperties == null) { target_resource._inverseProperties = new List <SObjectLink>(); } target_resource._inverseProperties.Add(olink); } var resource = PrepareResource(element); resource._content = item; item._resource = resource; //return item; }
// ........................ // Методы изменения модели // ........................ // Три метода пополнения модели /// <summary> /// Уничтожение айтема /// </summary> /// <param name="item_id"> /// The item_id. /// </param> public void DeleteItem(XName item_id) { SResource resource; if (!resources.ContainsKey(item_id)) { resource = new SResource(item_id); resources.Add(item_id, resource); } else { resource = resources[item_id]; //if (resource._content != null) // resource._content.Definition.RemoveInstance(item_id); //else OntologyModel.RemoveItemFromInstances(item_id); FreeContent(resource); // Не знаю как обработать обратные ссылки, наверное их надо открепить от соответствующих узлов if (resource._inverseProperties != null) { foreach (var ol in resource._inverseProperties) { //TODO: ??? Похоже, прямые ссылки, ведущие на ресурс то ли нужно, то ли можно оставлять без изменений Target у них будет null } } } resource.Deleted = true; return; // new XElement(SNames.TagDelete, new XAttribute(SNames.AttItem_id, item_id)); }
// Конструктор /// <summary> /// Initializes a new instance of the <see cref="SNode"/> class. /// </summary> /// <param name="x"> /// The x. /// </param> /// <param name="resource"> /// The resource. /// </param> /// <param name="rDataModel"> /// The r data model. /// </param> internal protected SNode(XElement x, SResource resource, SDataModel rDataModel) { _rDataModel = rDataModel; _resource = resource; _id = Coding(x.Attribute(SNames.rdfabout).Value); // RDFType = x.Name; //notFull = true; // _directProperties = new List<SProperty>(); if (_rDataModel == null) { return; } Definition = _rDataModel is SOntologyModel ? new ROntologyClassDefinition( new XElement("Class", new XAttribute(SNames.rdfabout, x.Name)), null, null) : _rDataModel.OntologyModel.GetOntologyNode <ROntologyClassDefinition>(x.Name.ToString()) ?? _rDataModel.OntologyModel.InsertNew <ROntologyClassDefinition>(x.Name, null, null, false); // if (!(_rDataModel is SOntologyModel)) Definition.AddInstance(this); foreach (var prop in x.Elements()) { if (prop.Attribute(SNames.rdfresource) == null) { _directProperties.Add(new SDataLink(prop, this)); } else { _directProperties.Add(new SObjectLink(prop, this)); } } }
/// <summary> /// Замена айтема /// </summary> /// <param name="oldId"> /// The old_id. /// </param> /// <param name="newId"> /// The new_id. /// </param> public void SubstituteItem(XName oldId, XName newId) { bool first_exists = this.resources.ContainsKey(oldId); bool second_exists = this.resources.ContainsKey(newId); if (!first_exists && !second_exists) { SResource resource = new SResource(oldId); resources.Add(oldId, resource); resources.Add(newId, resource); resource._mergedIds.Add(newId); resource._lastId = newId; return; } if (!first_exists) { SResource resource = resources[newId]; resources.Add(oldId, resource); resource._mergedIds.Add(oldId); // последний идентификатор остается из ресурса return; } if (!second_exists) { SResource resource = resources[oldId]; resources.Add(newId, resource); resource._mergedIds.Add(newId); resource._lastId = newId; // В ресурсе меняется последний идентификатор на новый return; } SResource first_resource = this.resources[oldId]; SResource second_resource = this.resources[newId]; if (first_resource == second_resource) { return; } // перенос внешних ссылок с первого ресурса на второй if (first_resource._inverseProperties != null) { foreach (SObjectLink olink in first_resource._inverseProperties) { olink._target_resource = second_resource; if (second_resource._inverseProperties == null) { second_resource._inverseProperties = new List <SObjectLink>(); } second_resource._inverseProperties.Add(olink); } } // перенос списка слияния с первого ресурса на второй second_resource._mergedIds.AddRange(first_resource._mergedIds); // перенос ссылки из входа на второй foreach (XName mergedId in first_resource._mergedIds) { resources[mergedId] = second_resource; } // Последний идентификатор остается из второго ресурса //first_resource._inverseProperties = null; // Это необязательно, поскольку первый ресурс будет откреплен // освобождение контента ресурса, т.е. убирание (уничтожение) прикрепленного узла и его исходящих стрелок this.FreeContent(first_resource); // this.resources[oldId] = second_resource; // это уже выполнено в цикле }
/// <summary> /// Освобождение ресурса. Предполагается, что контент ресурса - нормальный /// </summary> /// <param name="resource"> /// The resource. /// </param> protected void FreeContent(SResource resource) { SNode node = resource._content; // Если нет контента if (node == null) { return; } foreach (SObjectLink olink in node.DirectObjectLinks().Where(p => p._target_resource != null)) //TODO: возможно, проверка Where излишняя { SResource target_resource = olink._target_resource; target_resource._inverseProperties.Remove(olink); //olink.Target = null; } resource._content = null; }
/// <summary> /// </summary> /// <param name="x"> /// The x. /// </param> /// <returns> /// </returns> public override SNode CreateRecord(XElement x) { SResource resource = PrepareResource(x); if (x.Name == SNames.TagClass) { return(new ROntologyClassDefinition(x, resource, this)); } if (x.Name == SNames.TagObjectproperty) { return(new ROntologyObjectPropertyDefinition(x, resource, this)); } if (x.Name == SNames.TagDatatypeproperty) { return(new ROntologyDatatypePropertyDefinition(x, resource, this)); } return(new ROntologyDef(x, resource, this)); }
/// <summary> /// Подготовка ресурса для того, чтобы образовать запись. Если ресурс занят, то он освобождается /// </summary> /// <param name="x"> /// The x. /// </param> /// <returns> /// </returns> protected SResource PrepareResource(XElement x) { XName item_id = SNode.Coding(x.Attribute(SNames.rdfabout).Value); SResource resource; if (this.resources.ContainsKey(item_id)) { resource = this.resources[item_id]; // Если уничтоженный, то возвращается null //if (resource.Deleted) return null; // Если есть контент, то он освобождается if (resource._content != null) { FreeContent(resource); } } else { resource = new SResource(item_id); resources.Add(item_id, resource); } return(resource); }
/// <summary> /// Добавление записи формата rdf или оператора удаления или замены в модель. /// </summary> /// <param name="xOperator"> /// xml представление записи. /// </param> public void Include(XElement xOperator) { XName rname = xOperator.Name; XAttribute userDocumentId = xOperator.Attribute(SNames.AttUsersWorkRDFDocumentId); if (userDocumentId != null) { // var docUri = GetItemById(userDocumentId.Value).Uri(); userDocumentId.Remove(); AddToUserWorkDoc(xOperator, userDocumentId.Value); // LOG.WriteLine("\n\n" + DateTime.Now.ToString() + " " + userDocumentId.Value + "\n" + xOperator.ToString()); } if (rname == SNames.TagDelete) { if (!string.IsNullOrEmpty(xOperator.Attribute(SNames.AttItem_id).Value)) { XName id = SNode.Coding(xOperator.Attribute(SNames.AttItem_id).Value); this.DeleteItem(id); } } else if (rname == SNames.TagSubstitute) { if (!string.IsNullOrEmpty(xOperator.Attribute(SNames.AttOld_id).Value) && !string.IsNullOrEmpty(xOperator.Attribute(SNames.AttNew_id).Value)) { XName old_id = SNode.Coding(xOperator.Attribute(SNames.AttOld_id).Value); XName new_id = SNode.Coding(xOperator.Attribute(SNames.AttNew_id).Value); this.SubstituteItem(old_id, new_id); } } else { if (string.IsNullOrEmpty(xOperator.Attribute(SNames.rdfabout.ToString()).Value)) { return; } XName element_id = SNode.Coding(xOperator.Attribute(SNames.rdfabout.ToString()).Value); // Если этот идентификатор неопределен, то ничего не делаем // если нет ресурса, то вставляем айтем if (!this.resources.ContainsKey(element_id)) { this.IncludeItem(xOperator); return; } SResource resource = this.resources[element_id]; // если ресурс уничтожен, то элемент не вставляем if (resource.Deleted) { return; } // смотрим контент ресурса SNode node = resource._content; // если контента нет, то вставляем элемент if (node == null) { this.IncludeItem(xOperator); return; } // если (контент есть)& // определяемый ид не совпадает с идентификатором узла, // НО определяемый совпадает с последним, ТО меняем контент на новый if (element_id != node.Id) { // Здесь должно осуществиться и другое условие if (element_id == resource._lastId) { this.IncludeItem(xOperator); } // иначе данные устаревшие и не фиксируются } else { // Здесь замена осуществится только если временная отметка нового определения позже старой // выявляем временную отметку у элемента DateTime modificationTime = DateTime.MinValue; XAttribute mt = xOperator.Attribute(SNames.AttModificationTime); if (mt != null && DateTime.TryParse(mt.Value, out modificationTime) && modificationTime > node.modificationTime) { this.IncludeItem(xOperator); } } } }
internal ROntologyDatatypePropertyDefinition(XElement x, SResource resource, SDataModel rDataModel) : base(x, resource, rDataModel) { }
/// <summary> /// Initializes a new instance of the <see cref="ROntologyClassDefinition"/> class. /// </summary> /// <param name="x"> /// The x. /// </param> /// <param name="resource"> /// The resource. /// </param> /// <param name="rDataModel"> /// The r data model. /// </param> internal ROntologyClassDefinition(XElement x, SResource resource, SDataModel rDataModel) : base(x, resource, rDataModel) { }
internal ROntologyDef(XElement x, SResource resource, SDataModel rDataModel) : base(x, resource, rDataModel) { XSource = x; RDFType = x.Name; }