public virtual bool HasValue <T>() { return(entityBase.HasValue <T>()); }
public string Resolve(string stringToResolve, IEntityBase dataSource) { StringBuilder resolved = new StringBuilder(); int index = 0; while (index != stringToResolve.Length - 1) { Match sequenceFound = controlSequenceFinder.Match(stringToResolve, index); if (!sequenceFound.Success) { break; } resolved.Append(ResolveTemplateContent(stringToResolve.Substring(index, sequenceFound.Index - index))); string controlSequence = sequenceFound.Groups["expression"].Value; string startTag = $"$([{controlSequence}]"; string endTag = $"$([end-{controlSequence}])"; int length = sequenceFound.Length; index = sequenceFound.Index; int nestedSequences = Count(stringToResolve.Substring(index + startTag.Length, length - startTag.Length), startTag); int endIndex = index + length; while (nestedSequences > 0) { int newEnd = stringToResolve.Substring(endIndex) .IndexOf(endTag, StringComparison.OrdinalIgnoreCase); if (newEnd < 0) { throw new ControlSequenceEndTagNotFoundException(controlSequence); } newEnd = endIndex + newEnd; //Find nested tags between last end tag and this end tag nestedSequences += Count(stringToResolve.Substring(endIndex, newEnd - endIndex), startTag); nestedSequences--; endIndex = newEnd + endTag.Length; } Match controlSequenceDataMatch = greedyContentFinder.Match(stringToResolve, index, endIndex - index); if (!controlSequenceDataMatch.Success) { throw new InvalidOperationException("Should not happen"); } resolved.Append(ResolveControlSequence(controlSequenceDataMatch.Groups["expression"].Value, controlSequenceDataMatch.Groups["parameter"].Value, controlSequenceDataMatch.Groups["content"].Value)); if (controlSequenceDataMatch.Value.Contains('\n')) { Match newlineMatch = newlineSearcher.Match(stringToResolve, endIndex); if (newlineMatch.Success && newlineMatch.Index == endIndex) { endIndex += newlineMatch.Length; } } index = endIndex; } resolved.Append(ResolveTemplateContent(stringToResolve.Substring(index))); return(resolved.ToString()); string ResolveControlSequence(string sequence, string parameter, string content) { switch (sequence.ToUpperInvariant()) { case "IF-EXIST": return(IfSequence(IfExistCondition)); case "IF-SPECIFIED": return(IfSequence(IfSpecifiedCondition)); case "FOREACH": return(ForeachSequence()); case "NO-DUPLICATE-LINES": return(RemoveDuplicateLinesSequence()); default: throw new UnrecognizedControlSequenceException(sequence); } string RemoveDuplicateLinesSequence() { if (!string.IsNullOrEmpty(parameter)) { throw new NoDuplicateLinesParameterMismatchException(); } string[] lines = (Resolve(content, dataSource)).Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); return(string.Join(Environment.NewLine, lines.Distinct()) + Environment.NewLine); } string IfSequence(Func <bool> conditionCheck) { if (string.IsNullOrEmpty(parameter)) { throw new IfSequenceParameterMismatchException(); } bool condition = conditionCheck(); return(IfResult(condition)); } bool IfExistCondition() { CommandDefinition definition = dataSource.Value <CommandDefinition>(); Argument argument = definition?.Argument <Argument>(parameter); return(argument != null || dataSource.HasContent(parameter)); } bool IfSpecifiedCondition() { CommandDefinition definition = dataSource.Value <CommandDefinition>(); Argument argument = definition?.Argument <Argument>(parameter); bool specified; if (argument != null) { specified = argument.IsDefined; } else { specified = dataSource.HasContent(parameter) && !string.IsNullOrEmpty(dataSource[parameter].Value <string>()); } return(specified); } string IfResult(bool condition) { string result = string.Empty; string[] elseSplit = content.Split(new[] { "$([else])" }, StringSplitOptions.RemoveEmptyEntries); if (condition) { result = Resolve(elseSplit[0], dataSource); } else if (elseSplit.Length == 2) { result = Resolve(elseSplit[1], dataSource); } return(result); } string ForeachSequence() { StringBuilder foreachResult = new StringBuilder(); if ((content.StartsWith("\n", StringComparison.Ordinal) || content.StartsWith("\r\n", StringComparison.Ordinal)) && (content.EndsWith("\n", StringComparison.Ordinal) || content.EndsWith("\r\n", StringComparison.Ordinal))) { //This would leads to unwanted empty lines content = content.TrimStart('\r').TrimStart('\n'); } string[] nameSplit = parameter.Split(new[] { "[in]" }, StringSplitOptions.RemoveEmptyEntries); if (nameSplit.Length != 2) { throw new ForeachSequenceParameterMismatchException(parameter); } string elementName = nameSplit[0].Trim(); string[] ofTypeSplit = nameSplit[1].Split(new[] { "[of-type]" }, StringSplitOptions.RemoveEmptyEntries); string splitPart = ofTypeSplit.Length == 2 ? ofTypeSplit[1] : ofTypeSplit[0]; string[] split = splitPart.Split(new[] { "[split]" }, StringSplitOptions.RemoveEmptyEntries); string collection = ofTypeSplit.Length == 2 ? ofTypeSplit[0].Trim() : split[0].Trim(); string filter = string.Empty; string splitSize = split.Length == 2 ? split[1].Trim() : string.Empty; if (!int.TryParse(splitSize, out int chunksize)) { chunksize = -1; } if (ofTypeSplit.Length == 2) { filter = split.Length == 2 ? split[0].Trim() : ofTypeSplit[1].Trim(); } string[] path = collection.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); IEnumerable <Entity> data = ResolveRecursively(path); if (!string.IsNullOrEmpty(filter)) { data = data.Where(TemplateEqualsFilter); } ForeachItemContainer container = new ForeachItemContainer(elementName); if (chunksize > 0) { var query = data.Select((entity, idx) => new { idx, entity }); IEnumerable <IEnumerable <Entity> > dataChunks = query.GroupBy(x => x.idx / chunksize, a => a.entity); using (dataSource.AddTemporaryDataSource(container)) using (dataSource.SkipCaching(elementName)) { foreach (IEnumerable <Entity> chunk in dataChunks) { using (dataSource.SkipCaching(EntityKeys.ChunkStartKey)) using (dataSource.SkipCaching(EntityKeys.ChunkEndKey)) { string start = data.TakeWhile(x => !x.Equals(chunk.FirstOrDefault())).Count().ToString(CultureInfo.InvariantCulture); string end = data.TakeWhile(x => !x.Equals(chunk.LastOrDefault())).Count().ToString(CultureInfo.InvariantCulture); if (dataSource is Entity) { Entity dataSourceEntity = dataSource as Entity; container.Current = dataSourceEntity.Create(Guid.NewGuid().ToByteString(), chunk); using (container.Current.AddTemporaryDataSource(new DataChunk(start, end))) foreachResult.Append(Resolve(content, dataSource)); } else { throw new FormattableException($"The datasource should be an entity but is of type {dataSource.GetType()}"); } } } } } else { using (dataSource.AddTemporaryDataSource(container)) using (dataSource.SkipCaching(elementName)) { foreach (Entity entity in data) { container.Current = entity; foreachResult.Append(Resolve(content, dataSource)); } } } return(foreachResult.ToString()); bool TemplateEqualsFilter(Entity entity) { return(entity.Template().TemplateNames(repository) .Any(n => n.Equals(filter, StringComparison.OrdinalIgnoreCase))); } } } string ResolveTemplateContent(string resolvable) { string result = resolvable; Match controlSequenceMatch = templateAccessRegex.Match(resolvable); while (controlSequenceMatch.Success) { string content = controlSequenceMatch.Groups["content"].Value; if (content.StartsWith("[", StringComparison.Ordinal) && content.EndsWith("]", StringComparison.Ordinal)) { throw new WildControlSequenceException(content); } string[] path = content.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); string value = (ResolveRecursively(path)).Value <string>(); if (controlSequenceMatch.Groups["text_control"].Success) { string textControlSequence = controlSequenceMatch.Groups["text_control"].Value; textControlSequence = textControlSequence.Substring(0, textControlSequence.Length - 1); value = ResolveTextControlSequences(value, textControlSequence); } result = result.Replace(controlSequenceMatch.Value, value); controlSequenceMatch = controlSequenceMatch.NextMatch(); } return(result); } IEntityBase ResolveRecursively(string[] path) { IEntityBase current = dataSource; foreach (string part in path) { current = current[part]; if (current.HasValue <string>()) { string value = Resolve(current.Value <string>(), current); current.SetValue(value); } } return(current); } int Count(string data, string substring) { return((data.Length - data.Replace(substring, string.Empty).Length) / substring.Length); } }
public override Entity Resolve(Entity owner, string key, bool fallback = false) { TemplateEntity ownerTemplateEntity = TemplateEntity.Decorate(owner); if (key == EntityKeys.FieldArpDataTypeKey && owner.Type == EntityKeys.FormatKey) { return(ResolveArpDataType()); } if (key == EntityKeys.TypeMetaDataFormatKey && owner.Type == EntityKeys.FormatKey) { return(ResolveTypeMetaDataFormat()); } if (key == EntityKeys.ExpandHiddenTypesFormatKey) { return(ExpandHiddenTypes()); } if (key == EntityKeys.FilterHiddenTypesFormatKey) { return(FilterHiddenTypes()); } if (key == EntityKeys.IsFieldKey) { return(owner.Create(key, CodeEntity.Decorate(owner).AsField != null)); } if (key == EntityKeys.IsTypeKey) { return(owner.Create(key, CodeEntity.Decorate(owner).AsType != null)); } if (key == EntityKeys.BigDataProjectKey) { return(GetBigDataProjectEntity()); } if (key == EntityKeys.NormalProjectKey) { return(GetNormalProjectEntity()); } ISymbol symbol = owner.Value <ISymbol>(); if (symbol != null) { Entity result = owner.PropertyValueEntity(key, symbol); if (result != null) { return(result); } throw new ContentProviderException(key, owner); } if (key == EntityKeys.BaseDirectoryKey && HasBaseDirectory(owner, out string baseDirectory)) { return(owner.Create(key, baseDirectory)); } IType type = owner.Value <IType>(); if (type != null) { return(ResolveType()); } IField field = owner.Value <IField>(); if (field != null) { return(ResolveField()); } IDataType dataType = owner.Value <IDataType>(); if (dataType != null) { return(ResolveDataType()); } ICodeModel codeModel = owner.Value <ICodeModel>(); if (codeModel != null) { return(ResolveCodeModel()); } throw new ContentProviderException(key, owner); IEnumerable <CodeEntity> GetPortEnums() { return(GetAllPorts().Concat(GetPortStructures().SelectMany(p => p.Fields)) .Select(f => f.ResolvedType) .Where(t => t.AsEnum != null) .Distinct()); } IEnumerable <CodeEntity> GetAllPorts() { bool IsPort(CodeEntity fieldEntity) { return(fieldEntity.AsField != null && fieldEntity.AsField.HasAttributeWithoutValue(EntityKeys.PortAttributeKey)); } return(TemplateEntity.Decorate(owner).EntityHierarchy .Select(CodeEntity.Decorate) .SelectMany(c => c.Fields) .Where(IsPort)); } IEnumerable <CodeEntity> GetPortStructures() { HashSet <CodeEntity> structures = new HashSet <CodeEntity>(GetAllPorts() .Select(f => f.ResolvedType) .Where(t => t.AsType != null && t.AsEnum == null), new FullNameCodeEntityComparer()); HashSet <CodeEntity> visited = new HashSet <CodeEntity>(new FullNameCodeEntityComparer()); while (structures.Except(visited).Any()) { foreach (CodeEntity structure in structures.Except(visited).ToArray()) { foreach (CodeEntity structureField in structure.Fields) { CodeEntity structureDataType = structureField.ResolvedType; if (structureDataType.AsType != null && structureDataType.AsEnum == null) { structures.Add(structureDataType); } } visited.Add(structure); } } return(structures); } Entity FilterHiddenTypes() { IEnumerable <IType> types = owner.Select(CodeEntity.Decorate) .Where(c => !c.IsHidden()) .Select(c => c.AsType) .ToArray(); string name = owner.FirstOrDefault()?.Name ?? string.Empty; return(owner.Create(key, types.Select(t => owner.Create(name, t.FullName, t)))); } Entity ExpandHiddenTypes() { IEnumerable <CodeEntity> dataSourceFields = owner.Select(CodeEntity.Decorate); dataSourceFields = ExpandHiddenStructureFields(dataSourceFields); string name = owner.FirstOrDefault()?.Name ?? string.Empty; return(owner.Create(key, dataSourceFields.Select(e => e.AsField) .Select(f => owner.Create(name, f.Name, f)))); IEnumerable <CodeEntity> ExpandHiddenStructureFields(IEnumerable <CodeEntity> fields) { foreach (CodeEntity hiddenField in fields) { CodeEntity hiddenType = hiddenField.ResolvedType; if (hiddenType == null || !hiddenType.IsHidden()) { yield return(hiddenField); continue; } foreach (CodeEntity hiddenTypeField in ExpandHiddenStructureFields(hiddenType.Fields)) { yield return(hiddenTypeField); } } } } T ChooseMetaDataTemplate <T>(IEnumerable <(T template, string name, string context)> templates) { return(templates.OrderByDescending(t => ContextComplexity(t.context ?? string.Empty)) .FirstOrDefault(Matches) .template); bool Matches((T template, string name, string context) template) { if (!key.Equals(template.name, StringComparison.OrdinalIgnoreCase)) { return(false); } if (string.IsNullOrEmpty(template.context)) { return(true); } string[] contextPath = template.context.Split(new [] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries) .Reverse().ToArray(); Entity current = owner; foreach (string part in contextPath) { current = current?.Owner; if (current?[$"is{part}"].Value <bool>() != true) { return(false); } } return(true); } int ContextComplexity(string context) { return(context.Count(c => c == '/' || c == '\\')); } } Entity ResolveType() { switch (key) { case EntityKeys.PathKey: { return(owner.Create(key, type.GetFile(owner).Parent.FullName)); } case EntityKeys.FieldsKey: { return(owner.Create(key, type.Fields.Select(f => owner.Create(key.Singular(), f.Name, f)))); } case EntityKeys.FileKey: { VirtualFile file = owner.Root.Value <ICodeModel>() .Types[type]; return(owner.Create(key, file.Name, file)); } case EntityKeys.BaseTypeKey: { IDataType baseType = type.BaseTypes.FirstOrDefault(); return(owner.Create(key, baseType)); } default: { if (TryResolveTypeTemplate(out Entity result)) { return(result); } if (TryResolveProperty(out result)) { return(result); } if (TryResolveFields(out result)) { return(result); } if (TryResolveRelationship(out result)) { return(result); } throw new ContentProviderException(key, owner); } } bool TryResolveTypeTemplate(out Entity result) { Templates.Type.metaDataTemplate typeMetaDataTemplate = ChooseMetaDataTemplate(templateRepository.TypeTemplates .Select(t => (t, t.name, t.context))); if (typeMetaDataTemplate != null) { result = GetTypeTemplateEntity(typeMetaDataTemplate); return(true); } result = null; return(false); Entity GetTypeTemplateEntity(Templates.Type.metaDataTemplate metaDataTemplate) { if (!metaDataTemplate.hasvalue) { bool hasAttribute = type.HasAttributeWithoutValue(metaDataTemplate.name); return(owner.Create(key, new Func <string>(hasAttribute.ToString), hasAttribute)); } (string[] values, CodePosition position) = GetTypeTemplateValue(); IEnumerable <string> formattedValues = VerifyValues().ToArray(); return(metaDataTemplate.multiplicity == Templates.Type.multiplicity.OneOrMore ? owner.Create(key, formattedValues.Select(v => owner.Create(key.Singular(), v))) : owner.Create(key, formattedValues.First())); IEnumerable <string> VerifyValues() { return(values.Select(VerifyValue)); string VerifyValue(string arg) { (bool success, string message, string newValue) = metaDataTemplate.ValueRestriction.Verify(arg); if (!success) { owner.AddCodeException(new FieldAttributeRestrictionException(metaDataTemplate.name, arg, message, position, type.GetFile(owner))); } return(newValue); } } (string[], CodePosition) GetTypeTemplateValue() { IAttribute attribute = type.Attributes.LastOrDefault(a => a.Name.Equals(metaDataTemplate.name, StringComparison.OrdinalIgnoreCase)); string value = attribute?.Values.FirstOrDefault() ?? resolver.Resolve(metaDataTemplate.defaultvalue, owner); return(metaDataTemplate.multiplicity == Templates.Type.multiplicity.OneOrMore ? value.Split(new[] { metaDataTemplate.split }, StringSplitOptions.RemoveEmptyEntries) : new[] { value }, attribute?.Position ?? new CodePosition(0, 0)); } } } bool TryResolveProperty(out Entity result) { result = owner.PropertyValueEntity(key, type); return(result != null); } bool TryResolveFields(out Entity result) { metaDataTemplate metaDataTemplate = templateRepository.FieldTemplates .FirstOrDefault(t => t.name.Plural().Equals(key, StringComparison .OrdinalIgnoreCase)); if (metaDataTemplate != null) { IEnumerable <IField> fields = type.Fields .Where(f => f.Attributes .Any(a => a.Name .Equals(metaDataTemplate.name, StringComparison.OrdinalIgnoreCase))); result = owner.Create(key, fields.Select(f => owner.Create(metaDataTemplate.name, f.Name, f))); return(true); } result = null; return(false); } bool TryResolveRelationship(out Entity result) { templateRelationship[] relationships = owner.Template().Relationship; templateRelationship relationship = relationships?.FirstOrDefault(r => r.name.Equals(key, StringComparison.OrdinalIgnoreCase)) ?? relationships?.FirstOrDefault(r => r.name.Equals(key.Singular(), StringComparison.OrdinalIgnoreCase)); TemplateDescription relationshipDescription = relationship != null?templateRepository.Template(relationship.type) : null; if (relationshipDescription != null) { IEnumerable <string> names = type.Attributes .Where(a => a.Name.Equals(relationship.name, StringComparison.OrdinalIgnoreCase)) .SelectMany(a => a.Values); result = relationship.GetRelationship(relationshipDescription, owner, names.ToArray()); return(true); } result = null; return(false); } } Entity ResolveField() { switch (key) { case EntityKeys.FieldNameKey: { return(owner.Create(key, field.Name)); } case EntityKeys.DataTypeKey: { IDataType fieldDataType = GetRealFieldDataType(); return(owner.Create(key, fieldDataType.Name, fieldDataType)); } case EntityKeys.ResolvedTypeKey: { ICodeModel model = owner.Root.Value <ICodeModel>(); IDataType fieldDataType = field.DataType; IType realType = fieldDataType.PotentialFullNames .Select(model.Type) .FirstOrDefault(t => t != null); return(owner.Create(key, realType?.Name, realType)); } case EntityKeys.MultiplicityKey: { return(owner.Create(key, field.Multiplicity.Select(m => owner.Create(key, new Func <string>(m.ToString), m)))); } default: { metaDataTemplate metaDataTemplate = templateRepository.FieldTemplates .FirstOrDefault(t => t.name.Equals(key, StringComparison.OrdinalIgnoreCase)); if (metaDataTemplate != null) { return(GetFieldTemplateEntity(metaDataTemplate)); } throw new ContentProviderException(key, owner); } } IDataType GetRealFieldDataType() { ICodeModel rootCodeModel = owner.Root.Value <ICodeModel>(); IEnum @enum = field.DataType.PotentialFullNames.Select(n => rootCodeModel.GetEnum(n)).FirstOrDefault(e => e != null); if (@enum != null) { (IDataType enumBaseType, _) = GetEnumBaseType(@enum); return(enumBaseType); } return(field.DataType); } Entity GetFieldTemplateEntity(metaDataTemplate metaDataTemplate) { if (!metaDataTemplate.hasvalue) { bool hasAttribute = field.HasAttributeWithoutValue(metaDataTemplate.name); return(owner.Create(key, new Func <string>(hasAttribute.ToString), hasAttribute)); } (string[] values, CodePosition position) = GetFieldTemplateValue(); IEnumerable <string> formattedValues = VerifyValues().ToArray(); return(metaDataTemplate.multiplicity == multiplicity.OneOrMore ? owner.Create(key, formattedValues.Select(v => owner.Create(key.Singular(), v))) : owner.Create(key, formattedValues.First())); IEnumerable <string> VerifyValues() { return(values.Select(VerifyValue)); string VerifyValue(string arg) { (bool success, string message, string newValue) = metaDataTemplate.ValueRestriction.Verify(arg); if (!success) { owner.AddCodeException(new FieldAttributeRestrictionException(metaDataTemplate.name, arg, message, position, field.GetFile(owner))); } return(newValue); } } (string[], CodePosition) GetFieldTemplateValue() { IAttribute attribute = field.Attributes.LastOrDefault(a => a.Name.Equals(metaDataTemplate.name, StringComparison.OrdinalIgnoreCase)); string value = string.IsNullOrEmpty(attribute?.Values.FirstOrDefault()) ? resolver.Resolve(metaDataTemplate.defaultvalue, owner) : attribute.Values.First(); return(metaDataTemplate.multiplicity == multiplicity.OneOrMore ? value.Split(new[] { metaDataTemplate.split }, StringSplitOptions.RemoveEmptyEntries) : new[] { value }, attribute?.Position ?? new CodePosition(0, 0)); } } } Entity ResolveCodeModel() { switch (key) { case EntityKeys.PortStructsKey: { return(owner.Create(key, GetPortStructures().Select(c => c.Base))); } case EntityKeys.PortEnumsKey: { return(owner.Create(key, GetPortEnums().Select(c => c.Base))); } case EntityKeys.NamespaceKey: { bool prior206Target = CheckProjectTargets(); IEnumerable <string> relevantTypes = TemplateEntity.Decorate(owner).EntityHierarchy .Select(CodeEntity.Decorate) .Where(c => !c.IsRoot()) .Select(c => c.FullName); string ns = prior206Target ? codeModel.RootNamespaceForOldTarget( relevantTypes.ToArray(), GetPortStructures().Concat(GetPortEnums()) .Select(c => c.FullName) .ToArray()) : codeModel.RootNamespace(relevantTypes.ToArray()); if (string.IsNullOrEmpty(ns)) { ns = owner.Name; } return(owner.Create(key, ns)); } default: throw new ContentProviderException(key, owner); } bool CheckProjectTargets() { IEnumerable <TargetEntity> targets = ProjectEntity.Decorate(owner).Targets.Select(t => TargetEntity.Decorate(t)); return(targets.Any(t => t.Version < new Version(20, 6))); } } Entity ResolveDataType() { switch (key) { case EntityKeys.NameKey: return(owner.Create(key, dataType.Name)); case EntityKeys.FullNameKey: string fullName = GetDataTypeFullName(); return(owner.Create(key, fullName)); default: throw new ContentProviderException(key, owner); } string GetDataTypeFullName() { ICodeModel rootCodeModel = owner.Root.Value <ICodeModel>(); return(dataType.PotentialFullNames.FirstOrDefault(fn => rootCodeModel.Type(fn) != null) ?? dataType.Name); } } Entity ResolveTypeMetaDataFormat() { IEntityBase dataSource = ownerTemplateEntity.FormatOrigin; IDataType dataSourceDataType = dataSource.HasValue <IDataType>() ? dataSource.Value <IDataType>() : dataSource.Value <IField>().DataType; ICodeModel rootCodeModel = dataSource.Root.Value <ICodeModel>(); string dataTypeName = string.Empty; if (dataSourceDataType != null) { dataTypeName = dataSourceDataType.PotentialFullNames .Select(n => rootCodeModel.Type(n)) .FirstOrDefault(t => t != null) ?.Name ?? datatypeConversion.Convert(dataSourceDataType); } return(owner.Create(key, dataTypeName)); } Entity ResolveArpDataType() { IEntityBase dataSource = ownerTemplateEntity.FormatOrigin; IField dataSourceField = dataSource.Value <IField>(); if (dataSourceField == null) { throw new FormatTargetMismatchException("arpDataType", "field|port", dataSource.Type); } ICodeModel rootCodeModel = dataSource.Root.Value <ICodeModel>(); bool isStruct = dataSourceField.DataType.PotentialFullNames.Any(n => rootCodeModel.GetClass(n) != null || rootCodeModel.GetStructure(n) != null); IEnum @enum = dataSourceField.DataType.PotentialFullNames.Select(n => rootCodeModel.GetEnum(n)).FirstOrDefault(e => e != null); bool isArray = dataSourceField.Multiplicity.Any(); string arpName = "DataType::" + GetArpDataType(dataSourceField.DataType.Name); return(owner.Create(key, arpName)); string GetArpDataType(string dataTypeName) { string postfix = isArray ? " | DataType::Array" : string.Empty; if (isStruct) { return("Struct" + postfix); } if (@enum != null) { (IDataType enumBaseType, string formattedBaseType) = GetEnumBaseType(@enum); return($"Enum | DataType::{formattedBaseType}" + postfix); } (bool success, string value) = FormatDataType(dataTypeName); if (!success) { throw new UnknownDataTypeException(value); } return(value + postfix); } } (bool success, string value) FormatDataType(string unformattedValue) { if (unformattedValue.Contains('<')) { unformattedValue = unformattedValue.Substring(0, unformattedValue.IndexOf('<')); } string result = owner.Create("temporaryCtnFormatContainer", unformattedValue).Format()["knownDataTypes"].Value <string>(); Match unkownMatch = UnkownDataTypeRegex.Match(result); if (unkownMatch.Success) { return(false, unkownMatch.Groups["dataType"].Value); } return(true, result); } (IDataType, string) GetEnumBaseType(IEnum @enum) { IDataType enumDataType = @enum.BaseTypes.FirstOrDefault(); string enumBaseType = enumDataType?.Name; if (string.IsNullOrEmpty(enumBaseType)) { throw new MissingEnumDataTypeException(@enum); } (bool formatted, string formattedBaseType) = FormatDataType(enumBaseType); if (!formatted) { throw new UnkownEnumDataTypeException(formattedBaseType, @enum); } return(enumDataType, formattedBaseType); } Entity GetBigDataProjectEntity() { if (HasMoreThan1000Fields()) { return(owner.Create(key, "true", true)); } return(owner.Create(key, "false", false)); } Entity GetNormalProjectEntity() { if (HasMoreThan1000Fields()) { return(owner.Create(key, "false", false)); } return(owner.Create(key, "true", true)); } bool HasMoreThan1000Fields() { ICodeModel model = owner.Value <ICodeModel>(); if (model == null || GetAllPorts().Concat(GetPortStructures().SelectMany(s => s.Fields)).Count() <= 1000) { return(false); } return(true); } }