protected override void UpdateProfileItem(ProfileTypeDefinitionModel profileItem, IDALContext dalContext) { profileItem.TypeId = (int)ProfileItemTypeEnum.Object; base.UpdateProfileItem(profileItem, dalContext); if (profileItem.TypeId != (int)ProfileItemTypeEnum.Object) { throw new Exception(); } }
protected override void UpdateProfileItem(ProfileTypeDefinitionModel profileItem, IDALContext dalContext) { if (_model.SuperType != null) { var superTypeProfile = _model.SuperType.ImportProfileItem(dalContext); profileItem.Parent = dalContext.MapToModelProfileSimple(superTypeProfile); } profileItem.IsAbstract = _model.IsAbstract; base.UpdateProfileItem(profileItem, dalContext); }
private ProfileTypeDefinitionModel ExtendTypeDefinitionInternal(ProfileTypeDefinitionModel parent, int?profileId, bool isExtend, UserToken userToken) { //used to populate author info var user = _dalUser.GetById(userToken.UserId, userToken); //update the new profile to clean out and update some key parts of the item //make clean copy of parent and then remove some lingering parent data items var result = JsonConvert.DeserializeObject <ProfileTypeDefinitionModel>(JsonConvert.SerializeObject(parent)); result.ID = null; result.OpcNodeId = null; result.BrowseName = null; result.SymbolicName = null; result.DocumentUrl = null; result.Name = isExtend ? "[Extend]" : "[New]"; //name useful in ancestory tree. After that is built, we clear name. result.Parent = _profileUtils.MapToModelProfileSimple(parent); result.AuthorId = User.GetUserID(); result.Author = new UserSimpleModel() { ID = user.ID, FirstName = user.FirstName, LastName = user.LastName, Organization = user.Organization }; result.CreatedBy = result.Author; result.Created = DateTime.UtcNow; result.UpdatedBy = result.Author; result.Updated = DateTime.UtcNow; //return dependencies, ancestory for this profile as part of this response to reduce volume of calls for a profile. result.Dependencies = new List <ProfileTypeDefinitionSimpleModel>(); result.Ancestory = _profileUtils.GenerateAncestoryLineage(result, userToken); result.ProfileAttributes = new List <ProfileAttributeModel>(); result.Interfaces = new List <ProfileTypeDefinitionModel>(); result.Compositions = new List <ProfileTypeDefinitionRelatedModel>(); result.ExtendedProfileAttributes = _profileUtils.GetExtendedAttributes(result, userToken); //clear name, profile fk before returning... result.Name = ""; result.Description = ""; result.IsFavorite = false; //for normal extend, new, profileId is null. For wizard, profile Id will be selected by user in upstream step if (profileId.HasValue) { result.Profile = _dalProfile.GetById(profileId.Value, userToken); result.ProfileId = profileId; } else { result.Profile = null; result.ProfileId = 0; } return(result); }
protected override void UpdateProfileItem(ProfileTypeDefinitionModel profileItem, IDALContext dalContext) { base.UpdateProfileItem(profileItem, dalContext); if (_model.TypeDefinition != null) { var objectType = _model.TypeDefinition?.ImportProfileItem(dalContext); if (objectType == null) { throw new Exception($"Undefined object type {_model.TypeDefinition.DisplayName?.FirstOrDefault()?.Text} {_model.TypeDefinition.NodeId}"); } profileItem.Parent = dalContext.MapToModelProfileSimple(objectType); } }
public static void AddVariableToProfileModel(this VariableModel model, ProfileTypeDefinitionModel profileItem, IDALContext dalContext) { if (model is PropertyModel property) { property.AddVariableToProfileModel(profileItem, dalContext); } else if (model is DataVariableModel variable) { variable.AddVariableToProfileModel(profileItem, dalContext); } else { throw new Exception($"Unexpected variable type {model.GetType()}"); } }
/// <summary> /// /// </summary> /// <remarks> /// TBD - handle scenario where user implemented same interface in ancestor profile. /// Prevent this from happening by not allowing this as an interface selection. ///</remarks> /// <param name="profile"></param> /// <returns></returns> public List <ProfileTypeDefinitionModel> BuildInterfaceLookup(ProfileTypeDefinitionModel profile, UserToken userToken) { //remove items of a different type, remove self //remove interfaces already used by profile. //Note: interfaces also must only derive from BaseInterfaceType - by selecting only interface profile types, we satisfy this. var items = profile == null? _dal.Where(p => p.ProfileType.Name.ToLower().Equals("interface"), userToken, null, null, false) : _dal.Where(p => p.ProfileType.Name.ToLower().Equals("interface") && !p.ID.Equals(profile.ID) && !profile.Interfaces.Select(x => x.ID).ToList().Contains(p.ID), userToken, null, null, false); var result = new List <ProfileTypeDefinitionModel>(); int counter = 0; foreach (var p in items.Data) { //pull extended attributes from ancestory AND interface attributes p.ExtendedProfileAttributes = this.GetExtendedAttributes(p, userToken); //merge profile attributes, compositions, variable types p.ProfileAttributes = this.MergeProfileAttributes(p); //add some special indicators these attrs are interface attr foreach (var a in p.ProfileAttributes) { a.Interface = new ProfileTypeDefinitionRelatedModel() { ID = p.ID, Name = p.Name, BrowseName = p.BrowseName, OpcNodeId = p.OpcNodeId };; a.InterfaceGroupId = counter; } //add some special indicators the ancestor attrs are interface attr associated with this interface foreach (var a in p.ExtendedProfileAttributes) { a.Interface = new ProfileTypeDefinitionRelatedModel() { ID = p.ID, Name = p.Name, BrowseName = p.BrowseName, OpcNodeId = p.OpcNodeId };; a.InterfaceGroupId = counter; } result.Add(p); counter++; } return(result); }
/// <summary> /// An ordered representation of the profile's lineage. This is a flat collection /// </summary> /// <param name="profile"></param> /// <returns></returns> public List <ProfileTypeDefinitionSimpleModel> GenerateAncestoryLineage(ProfileTypeDefinitionModel profile, UserToken userToken) { //navigate up the inheritance tree until the root. List <ProfileTypeDefinitionSimpleModel> result = new List <ProfileTypeDefinitionSimpleModel>(); int counter = 0; var ancestor = profile; while (ancestor != null) { result.Add(MapToModelProfileSimple(ancestor, counter)); ancestor = ancestor.Parent?.ID == null ? null : _dal.GetById(ancestor.Parent.ID.Value, userToken); counter--; } //sort the result grandaprent / parent / profile return(result.OrderBy(p => p.Level).ThenBy(p => p.Name).ToList()); }
/// <summary> /// Get the list of profiles that depend on this profile /// </summary> /// <param name="profile"></param> /// <returns></returns> public List <ProfileTypeDefinitionSimpleModel> GenerateDependencies(ProfileTypeDefinitionModel profile, UserToken userToken) { //find all descendants that may be related...go n levels deep var result = new List <ProfileTypeDefinitionSimpleModel>(); BuildDescendantsTree(ref result, profile.ID, 1, userToken); var count = result.Count(); //find compositions, variable types which depend on this profile var dependencies = _dal.Where(p => !ProfileMapperUtil.ExcludedProfileTypes.Contains(p.ProfileTypeId) /*p.ProfileTypeId != (int)ProfileItemTypeEnum.Object*/ && (p.ParentId.Equals(profile.ID) || p.Compositions.Any(p => p.CompositionId.Equals(profile.ID)) || p.Attributes.Any(a => a.DataType.CustomTypeId.HasValue && a.DataType.CustomTypeId.Equals(profile.ID))) , userToken, null, null).Data .Select(s => MapToModelProfileAncestory(s, count + 1)); return(result.Concat(dependencies).OrderBy(p => p.Level).ThenBy(p => p.Name).ToList()); }
/// <summary> /// A nested representation of the profile's place relative to its ancestors and siblings /// This is a recursive represenation for ancestors and siblings. /// </summary> /// <param name="profile"></param> /// <param name="includeSiblings"></param> /// <returns></returns> public List <ProfileTypeDefinitionAncestoryModel> GenerateAncestoryTree(ProfileTypeDefinitionModel profile, UserToken userToken, bool includeSiblings = false) { //navigate up the inheritance tree until the root. this is sorted properly. Should be at least one. var lineage = this.GenerateAncestoryLineage(profile, userToken); //build a nested loop from root to profile item ProfileTypeDefinitionAncestoryModel root = null; ProfileTypeDefinitionAncestoryModel curItem = null; ProfileTypeDefinitionAncestoryModel finalParent = null; foreach (var p in lineage) { var pConverted = new ProfileTypeDefinitionAncestoryModel() { ID = p.ID, Author = p.Author, Description = p.Description, Level = p.Level, Name = p.Name, Type = p.Type , /*Namespace = p.Namespace,*/ IsAbstract = p.IsAbstract, OpcNodeId = p.OpcNodeId , Profile = new ProfileModel() { ID = p.Profile.ID, Namespace = p.Profile.Namespace, Version = p.Profile.Version } }; //1st iteration if (root == null) { root = pConverted; root.Children = new List <ProfileTypeDefinitionAncestoryModel>(); finalParent = root; } else //all other iterations { curItem.Children.Add(pConverted); finalParent = curItem; } curItem = pConverted; curItem.Children = new List <ProfileTypeDefinitionAncestoryModel>(); } var result = new List <ProfileTypeDefinitionAncestoryModel>(); result.Add(root); //build out a list and siblings will go on same level as the profile //find siblings - profiles with same parent. //Append to cur item if there is a multi-gen scenario. append as sibling if profile is the root if (includeSiblings) { var siblings = _dal.Where(p => !ProfileMapperUtil.ExcludedProfileTypes.Contains(p.ProfileTypeId) /*p.ProfileTypeId != (int)ProfileItemTypeEnum.Object*/ && profile.Parent != null && p.ParentId.Equals(profile.Parent.ID) && p.ID != profile.ID, userToken, null, null, false).Data .Select(s => MapToModelProfileAncestory(s, 1)); if (lineage.Count == 1) { result = result.Concat(siblings).ToList(); } else { //append siblings to final parent finalParent.Children = finalParent.Children.Concat(siblings).ToList(); } } return(result); }
public static LookupDataTypeModel GetAttributeDataType(this BaseTypeModel model, ProfileTypeDefinitionModel profileItem, IDALContext dalContext) { if (model is ObjectTypeModel objectType) { return(new ObjectTypeModelImportProfile { _model = objectType }.GetAttributeDataType(profileItem, dalContext)); } else if (model is VariableTypeModel variableType) { return(new VariableTypeModelImportProfile { _model = variableType }.GetAttributeDataType(profileItem, dalContext)); } else if (model is DataTypeModel dataType) { return(new DataTypeModelImportProfile { _model = dataType }.GetAttributeDataType(profileItem, dalContext)); } throw new Exception($"Unexpected variable type {model.GetType()}"); //var nodeModelFactory = new BaseTypeModelImportProfile<BaseTypeModel> { _model = model }; //return nodeModelFactory.GetAttributeDataType(profileItem, dalContext); }
protected override void UpdateProfileItem(ProfileTypeDefinitionModel profileItem, IDALContext dalContext) { profileItem.TypeId = (int)ProfileItemTypeEnum.CustomDataType; base.UpdateProfileItem(profileItem, dalContext); if (profileItem.TypeId != (int)ProfileItemTypeEnum.CustomDataType) { throw new Exception(); } var attributeNamespace = NodeModelUtils.GetNamespaceFromNodeId(_model.NodeId); if (_model.StructureFields?.Any() == true || _model.HasBaseType("nsu=http://opcfoundation.org/UA/;i=22")) { profileItem.TypeId = (int)ProfileItemTypeEnum.Structure; if (profileItem.Attributes == null) { profileItem.Attributes = new List <ProfileAttributeModel>(); } foreach (var field in _model.StructureFields ?? new List <DataTypeModel.StructureField>()) { var fieldDataType = field.DataType; if (fieldDataType == null) { throw new Exception($"Unable to resolve data type {field.DataType?.DisplayName}"); } var attributeDataType = fieldDataType.GetAttributeDataType(profileItem, dalContext); if (attributeDataType == null) { throw new Exception($"{fieldDataType} not resolved"); } var attribute = new ProfileAttributeModel { IsActive = true, Name = field.Name, BrowseName = $"{attributeNamespace};{field.Name}", //No SymbolicName for structure fields Namespace = attributeNamespace, IsRequired = !field.IsOptional, Description = field.Description?.FirstOrDefault()?.Text, AttributeType = new LookupItemModel { ID = (int)AttributeTypeIdEnum.StructureField }, DataType = attributeDataType, OpcNodeId = NodeModelUtils.GetNodeIdIdentifier(_model.NodeId), }; profileItem.Attributes.Add(attribute); } } if (_model.EnumFields?.Any() == true) { profileItem.TypeId = (int)ProfileItemTypeEnum.Enumeration; if (profileItem.Attributes == null) { profileItem.Attributes = new List <ProfileAttributeModel>(); } foreach (var field in _model.EnumFields) { var int64DataType = dalContext.GetDataType("Int64"); if (int64DataType == null /* || int64DataType.ID == 0*/) { throw new Exception($"Unable to resolve Int64 data type."); } var attribute = new ProfileAttributeModel { IsActive = true, Name = field.Name, BrowseName = $"{attributeNamespace};{field.Name}", // No SymbolicName for enum fields DisplayName = field.DisplayName?.FirstOrDefault()?.Text, Description = field.Description?.FirstOrDefault()?.Text, AttributeType = new LookupItemModel { ID = (int)AttributeTypeIdEnum.EnumField }, DataType = int64DataType, EnumValue = field.Value, Namespace = attributeNamespace, }; profileItem.Attributes.Add(attribute); } } }
public void AddVariableToProfileModel(ProfileTypeDefinitionModel profileItem, IDALContext dalContext) { string description = _model.Description?.FirstOrDefault()?.Text; var typeDefinitionModel = _model.TypeDefinition?.ImportProfileItem(dalContext); // TODO Capture the DataVariable TypeDefinition somewhere in the ProfileItem var attributeDataType = _model.DataType.GetAttributeDataType(profileItem, dalContext); if (attributeDataType != null) { int attributeTypeId = 0; if (this._model is PropertyModel) { attributeTypeId = (int)AttributeTypeIdEnum.Property; } else if (this._model is DataVariableModel) { attributeTypeId = (int)AttributeTypeIdEnum.DataVariable; } else { throw new Exception($"Unexpected child item {_model?.DisplayName} of type {this.GetType().Name} on item {profileItem.Name} ({profileItem.ID})"); } string dataVariableNodeIds = null; if (_model.DataVariables?.Any() == true && _model?.TypeDefinition?.DataVariables?.Any() == true) { var map = GetDataVariableNodeIds(_model.DataVariables, _model.TypeDefinition.DataVariables); dataVariableNodeIds = DataVariableNodeIdMap.GetMapAsString(map); } var attribute = new ProfileAttributeModel { IsActive = true, Name = _model.DisplayName?.FirstOrDefault()?.Text, SymbolicName = _model.SymbolicName, BrowseName = _model.BrowseName, Namespace = NodeModelUtils.GetNamespaceFromNodeId(_model.NodeId), IsRequired = ObjectModelImportProfile.GetModelingRuleForProfile(_model.ModelingRule), ModelingRule = _model.ModelingRule, IsArray = (_model.ValueRank ?? -1) != -1, ValueRank = _model.ValueRank, ArrayDimensions = _model.ArrayDimensions, Description = description, AttributeType = new LookupItemModel { ID = attributeTypeId }, DataType = attributeDataType, DataVariableNodeIds = dataVariableNodeIds, TypeDefinitionId = profileItem.ID, TypeDefinition = profileItem, VariableTypeDefinitionId = typeDefinitionModel?.ID, VariableTypeDefinition = typeDefinitionModel, OpcNodeId = NodeModelUtils.GetNodeIdIdentifier(_model.NodeId), AdditionalData = _model.Value, AccessLevel = _model.AccessLevel, UserAccessLevel = _model.UserAccessLevel, AccessRestrictions = _model.AccessRestrictions, WriteMask = _model.WriteMask, UserWriteMask = _model.UserWriteMask, }; var euInfo = NodeModelOpcExtensions.GetEUInformation(_model.EngineeringUnit); if (euInfo != null) { var engUnit = new EngineeringUnitModel { DisplayName = euInfo.DisplayName.Text, Description = euInfo.Description.Text, UnitId = euInfo.UnitId, NamespaceUri = euInfo.NamespaceUri, }; engUnit = dalContext.GetOrCreateEngineeringUnitAsync(engUnit); attribute.EngUnit = engUnit; } attribute.EngUnitOpcNodeId = _model.EngUnitNodeId; attribute.MinValue = (decimal?)_model.MinValue; attribute.MaxValue = (decimal?)_model.MaxValue; attribute.InstrumentMinValue = (decimal?)_model.InstrumentMinValue; attribute.InstrumentMaxValue = (decimal?)_model.InstrumentMaxValue; if (profileItem.Attributes == null) { profileItem.Attributes = new List <ProfileAttributeModel>(); } profileItem.Attributes.Add(attribute); } else { throw new Exception($"Data type {_model.DataType} not resolved."); } }
public bool ExportInternal(CESMII.ProfileDesigner.DAL.Models.ProfileModel profileModel, ProfileTypeDefinitionModel profileItem, Stream xmlNodeSet, UserToken userToken, UserToken authorId) { if (profileItem?.ProfileId != null) { profileModel = _nsDal.GetById(profileItem.ProfileId.Value, userToken); //if (!(profileModel.AuthorId == null || profileModel.AuthorId == userId)) //{ // throw new Exception($"User does not have access to profile on profileItem {profileItem}"); //} } //var uriToExport = nodeSetModel?.Namespace ?? profileItem.Namespace; var dalContext = new DALContext(this, userToken, authorId, false); _lastDalContext = dalContext; if (!NodesetModels.ContainsKey(strOpcNamespaceUri)) { try { // TODO find the right OPC version references in the nodeSet? var opcNodeSetModel = _nsDal.Where(ns => ns.Namespace == strOpcNamespaceUri /*&& (ns.AuthorId == null || ns.AuthorId == userId)*/, userToken, null, null, false, true).Data.OrderByDescending(m => m.PublishDate).FirstOrDefault(); // workaround for bug https://github.com/dotnet/runtime/issues/67622 var fileCachePatched = opcNodeSetModel.NodeSetFiles[0].FileCache.Replace("<Value/>", "<Value xsi:nil='true' />"); using (MemoryStream nodeSetStream = new MemoryStream(Encoding.UTF8.GetBytes(fileCachePatched))) //var nodeSetFilePath = Path.Combine(Path.GetDirectoryName(this.GetType().Assembly.Location), "Nodesets", "Opc.Ua.NodeSet2.xml"); //using (Stream nodeSetStream = new FileStream(nodeSetFilePath, FileMode.Open)) { UANodeSet nodeSet = UANodeSet.Read(nodeSetStream); _importedNodesByNodeId = null; // Get aliases from base UA model // TODO remove unused aliases later //foreach (var alias in nodeSet.Aliases) //{ // this.Aliases[alias.Value] = alias.Alias; //} // TODO find a more elegant way to load OPC base data types (needed by DataTypeModel.GetBuiltinDataType) var opcModel = nodeSet.Models[0]; var opcProfile = _nsDal.Where(ns => ns.Namespace == opcModel.ModelUri /*&& ns.PublicationDate == opcModel.PublicationDate*/ /*&& (ns.AuthorId == null || ns.AuthorId == userId)*/, userToken, null, null).Data?.FirstOrDefault(); //TBD - this next line is time consuming. this.LoadNodeSetAsync(nodeSet, opcProfile // new OPCUANodeSetHelpers.ModelNameAndVersion //{ // ModelUri = opcModel.ModelUri, // ModelVersion = opcModel.Version, // PublicationDate = opcModel.PublicationDate, // CacheId = opcNodeSetModel.ID, //} , true).Wait(); } } catch { } } if (profileItem == null) { var profileItemsResult = _dal.Where(pi => pi.ProfileId == profileModel.ID /*&& (pi.AuthorId == null || pi.AuthorId == userId)*/, userToken, null, null, false, true); if (profileItemsResult.Data != null) { foreach (var profile in profileItemsResult.Data) { var nodeModel = NodeModelFromProfileFactory.Create(profile, this, dalContext); } } } else { var nodeModel = NodeModelFromProfileFactory.Create(profileItem, this, dalContext); } // Export the nodesets var exportedNodeSet = new UANodeSet(); foreach (var model in this.NodesetModels.Values.Where(model => ((ProfileModel)model.CustomState).Namespace == profileModel.Namespace && ((ProfileModel)model.CustomState).PublishDate == profileModel.PublishDate)) { model.UpdateIndices(); ExportNodeSet(exportedNodeSet, model, this.NodesetModels, this.Aliases); } // .Net6 changed the default to no-identation: https://github.com/dotnet/runtime/issues/64885 using (StreamWriter writer = new StreamWriter(xmlNodeSet, Encoding.UTF8)) { try { var xmlWriter = XmlWriter.Create(writer, new XmlWriterSettings { Indent = true, }); XmlSerializer serializer = new XmlSerializer(typeof(UANodeSet)); serializer.Serialize(xmlWriter, exportedNodeSet); } finally { writer.Flush(); } } //exportedNodeSet.Write(xmlNodeSet); return(true); }
public async Task <IActionResult> Update([FromBody] ProfileTypeDefinitionModel model) { return(await UpdateInternal(model, false)); }
/// <summary> /// For a given profile, map the custom data type attributes to a unified model /// structure (ProfileAttributeModel) that can be used downstream when merging /// all sttributes into a single collection. This will add some data to distinguish /// these as custom data type attributes. /// </summary> /// <param name="item"></param> /// <returns></returns> //[System.Obsolete("This is going away. TBD - Remove once we cut over custom data types.")] //protected List<ProfileAttributeModel> MapCustomDataTypesToProfileAttributeModels(ProfileItemModel item) //{ // var result = new List<ProfileAttributeModel>(); // if (item == null || item.CustomDataTypes == null) return result; // //get lookup data type for custom data type // var dataTypeCustom = _dalDataType.Where(x => x.Code.ToLower().Equals("customdatatype"), null, null).Data.FirstOrDefault(); // foreach (var cdt in item.CustomDataTypes) // { // result.Add(new ProfileAttributeModel // { // CustomDataType = cdt, // CustomDataTypeId = cdt.RelatedId, // ID = cdt.ID, // Name = cdt.Name, // Description = cdt.Description, // ProfileId = item.ID, // TypeId = dataTypeCustom.ID, // DataType = dataTypeCustom // }); // } // return result; //} /// <summary> /// For each interface associated with the profile, append the interface attribute into the /// profile attributes list. These would be read only and show how the profile is virtually implementing /// the attributes for each interface. /// </summary> /// <remarks> /// TBD - need to get the ancestor attributes of each interface as well. /// </remarks> /// <param name="item"></param> /// <returns></returns> protected List <ProfileAttributeModel> MapInterfaceAttributesToProfileAttributeModels(ProfileTypeDefinitionModel item, UserToken userToken) { var result = new List <ProfileAttributeModel>(); if (item == null || item.Interfaces == null) { return(result); } var counter = 0; foreach (var p in item.Interfaces) { var attrs = this.MergeProfileAttributes(p); //get the ancestor attribs which are also now a part of this interface implementation attrs = attrs.Concat(this.GetExtendedAttributes(p, userToken)).ToList(); //add some special indicators these attrs are interface attr all associated with this interface //even acncestor attribs should be associated with this interface. foreach (var a in attrs) { a.Interface = new ProfileTypeDefinitionRelatedModel() { ID = p.ID, Name = p.Name, BrowseName = p.BrowseName, OpcNodeId = p.OpcNodeId };; a.InterfaceGroupId = counter; } result = result.Concat(attrs).ToList(); counter++; } return(result); }
/// <summary> /// For a given profile, map the composition attributes to a unified model /// structure (ProfileAttributeModel) that can be used downstream when merging /// all sttributes into a single collection. This will add some data to distinguish /// these as composition type attributes. /// </summary> /// <param name="item"></param> /// <returns></returns> protected List <ProfileAttributeModel> MapCompositionsToProfileAttributeModels(ProfileTypeDefinitionModel item) { var result = new List <ProfileAttributeModel>(); if (item == null || item.Compositions == null) { return(result); } //get lookup data type for composition var dataTypeComp = _dalDataType.Where(x => x.Code.ToLower().Equals("composition"), new UserToken(), null, null).Data.FirstOrDefault(); //get lookup data type for attr type composition var attrTypeComp = _dalLookup.Where(x => x.Code.ToLower().Equals("composition"), new UserToken(), null, null).Data.FirstOrDefault(); foreach (var comp in item.Compositions) { result.Add(new ProfileAttributeModel { Composition = comp, CompositionId = comp.RelatedProfileTypeDefinitionId, ID = comp.ID, Name = comp.Name, BrowseName = comp.BrowseName, SymbolicName = comp.SymbolicName, Description = comp.Description, TypeDefinitionId = item.ID, //TypeDefinition = item, // Results in cycle during serialization // No VariableTypeDefinition for compositions DataTypeId = dataTypeComp.ID, DataType = dataTypeComp, AttributeType = attrTypeComp }); } return(result); }
public ProfileTypeDefinitionSimpleWithAttrsModel MapToModelProfileSimpleWithAttrs(ProfileTypeDefinitionModel item, int level = 0) { if (item != null) { return(new ProfileTypeDefinitionSimpleWithAttrsModel { ID = item.ID, Name = item.Name, BrowseName = item.BrowseName, /*Namespace = item.Profile.Namespace,*/ Profile = new ProfileModel() { ID = item.Profile.ID, Namespace = item.Profile.Namespace, Version = item.Profile.Version }, Description = item.Description, Type = item.Type, Author = item.Author, OpcNodeId = item.OpcNodeId, IsAbstract = item.IsAbstract, Level = level, ProfileAttributes = item.Attributes }); } else { return(null); } }
/// <summary> /// Add or update a profile type def from the front end. This is different than importing a nodeset XML file. /// </summary> /// <param name="model"></param> /// <returns></returns> private async Task <IActionResult> UpdateInternal(ProfileTypeDefinitionModel model, bool isAdd) { var userToken = UserExtension.DalUserToken(User); //For front end, set Profile to null to ensure that the DAL does not see this as a changed object that must be updated. //Setting ProfileId will suffice. if (model.ProfileId.HasValue && model.ProfileId.Value > 0) { model.Profile = null; } if (isAdd) { model.ID = 0; //satisfy required field and set to 0 will indicate new item } //clean up stuff - set new ids to 0 rather than -1 for server side handling if (model.ProfileAttributes != null) { foreach (var attrib in model.ProfileAttributes) { if (attrib.TypeDefinitionId <= 0) { attrib.TypeDefinitionId = model.ID; } if (attrib.ID < 0) { attrib.ID = null; } if (attrib.CompositionId < 0) { attrib.CompositionId = null; } //if (attrib.CustomDataTypeId < 0) attrib.CustomDataTypeId = null; } //on front end, all attributes stored in single collection. // split out compositions, primitive attributes // into individual lists for DAL, DB. model.Attributes = model.ProfileAttributes.Where(a => (!a.CompositionId.HasValue || a.CompositionId < 0)).ToList(); // (!a.CustomDataTypeId.HasValue || a.CustomDataTypeId < 0)).ToList(); var comps = model.ProfileAttributes.Where(a => a.CompositionId.HasValue && a.CompositionId >= 0).ToList(); model.Compositions = _profileUtils.MapProfileAttributeToCompositionModels(comps); //var varTypes = model.ProfileAttributes.Where(a => a.CustomDataTypeId.HasValue && a.CustomDataTypeId >= 0).ToList(); //model.CustomDataTypes = _profileUtils.MapProfileAttributeToCustomDataTypeModels(varTypes); } //clear out stuff unrelated to the save of the item. There is lots of related stuff that we use in the display //that will trip up validation but is not central to the profile save operation. model.Ancestory = null; model.TypeId = model.Type.ID; //moved to DAL...set this to null to ensure that the DAL does not see this as a changed object that must be updated. Setting ProfileId will suffice. //model.Profile = null; //re-validate ModelState.Clear(); TryValidateModel(model); //required if (!model.ProfileId.HasValue) { ModelState.AddModelError("Profile", "Profile type definition must be assigned to a profile"); } if (!ModelState.IsValid) { var errors = ExtractModelStateErrors(); return(BadRequest("The item is invalid. Please correct the following: " + errors.ToString())); } int?id = 0; if (isAdd) { id = await _dal.Add(model, userToken); //increment extend count for this item's parent var analytic = _dalAnalytics.Where(x => x.ProfileTypeDefinitionId == model.Parent.ID, userToken, null, null, false).Data.FirstOrDefault(); if (analytic == null) { await _dalAnalytics.Add(new ProfileTypeDefinitionAnalyticModel() { ProfileTypeDefinitionId = model.Parent.ID.Value, ExtendCount = 1 }, userToken); } else { analytic.ExtendCount += 1; await _dalAnalytics.Update(analytic, null); } } else { id = await _dal.Update(model, userToken); } if (id < 0) { _logger.LogWarning($"ProfileTypeDefinitionController|UpdateInternal|Could not {(isAdd ? "add" : "update")} profile type definition."); return(BadRequest($"Could not {(isAdd ? "add" : "update")} profile type definition.")); } _logger.LogInformation($"ProfileTypeDefinitionController|UpdateInternal|{(isAdd ? "Added" : "Updated")} profile type definition. Id:{id}."); //return result object plus id. return(Ok(new ResultMessageWithDataModel() { IsSuccess = true, Message = $"Item was {(isAdd ? "added" : "updated")}.", //Data = new JRaw(JsonConvert.SerializeObject(this.GetItem(model.ID)) //Data = new JRaw(JsonConvert.SerializeObject(new IdIntModel() { ID = id })) Data = id })); }
public bool ExportProfileItem(ProfileTypeDefinitionModel profileItem, Stream xmlNodeSet, UserToken userToken, UserToken authorId) { return(ExportInternal(null, profileItem, xmlNodeSet, userToken, authorId)); }