private void FillVirtualFieldsInfo( Content content, VirtualFieldContext context, HashSet <Content> visitedContents) { if (visitedContents.Contains(content)) { return; } visitedContents.Add(content); foreach (Field field in content.Fields) { if (field is BaseVirtualField baseField) { ProcessVirtualField(baseField, content, context); } else if (field is EntityField entityField) { FillVirtualFieldsInfo(entityField.Content, context, visitedContents); } else if (field is ExtensionField extensionField) { foreach (Content extContent in extensionField.ContentMapping.Values) { FillVirtualFieldsInfo(extContent, context, visitedContents); } } } }
/// <summary> /// Рекурсивно обходит <see cref="Content"/> и заполняет /// <see cref="VirtualFieldContext.IgnoredFields"/> - список полей которые надо игнорировать при создании схемы /// и <see cref="VirtualFieldContext.VirtualFields"/> - значения вирутальных полей /// </summary> /// <exception cref="InvalidOperationException" /> public VirtualFieldContext GetVirtualFieldContext(Content content) { var context = new VirtualFieldContext(); FillVirtualFieldsInfo(content, context, new HashSet <Content>()); return(context); }
/// <exception cref="NotSupportedException" /> /// <exception cref="InvalidOperationException" /> private JSchema GetSchema(Content definition, bool forList, bool includeRegionTags, bool excludeVirtualFields) { _contentService.LoadStructureCache(); _fieldService.LoadStructureCache(); VirtualFieldContext virtualFieldContext = _virtualFieldContextService.GetVirtualFieldContext(definition); var context = new SchemaContext { VirtualFields = virtualFieldContext.VirtualFields, IgnoredFields = virtualFieldContext.IgnoredFields, ExcludeVirtualFields = excludeVirtualFields }; JSchema rootSchema = GetSchemaRecursive(definition, context, forList); if (includeRegionTags) { JSchema schemaWithRegionTags = new JSchema { Type = JSchemaType.Object }; schemaWithRegionTags.Properties.Add(ProductProp, rootSchema); JSchema regionTagsSchema = new JSchema { Type = JSchemaType.Array }; JSchema regionTagSchema = new JSchema { Type = JSchemaType.Object }; regionTagSchema.Properties.Add("title", new JSchema { Type = JSchemaType.String }); JSchema valuesSchema = new JSchema { Type = JSchemaType.Array }; JSchema valueSchema = new JSchema { Type = JSchemaType.Object }; valueSchema.Properties.Add("value", new JSchema { Type = JSchemaType.String }); JSchema regionIdsSchema = new JSchema { Type = JSchemaType.Array }; regionIdsSchema.Items.Add(new JSchema { Type = JSchemaType.Integer }); valueSchema.Properties.Add("regionsId", regionIdsSchema); valueSchema.Required.Add("regionsId"); valueSchema.Required.Add("value"); valuesSchema.Items.Add(valueSchema); regionTagSchema.Properties.Add("values", valuesSchema); regionTagSchema.Required.Add("title"); regionTagSchema.Required.Add("values"); regionTagsSchema.Items.Add(regionTagSchema); schemaWithRegionTags.Properties.Add(RegionTagsProp, regionTagsSchema); FillSchemaDefinitions(schemaWithRegionTags, context); DeduplicateJsonSchema(schemaWithRegionTags, context); return schemaWithRegionTags; } FillSchemaDefinitions(rootSchema, context); DeduplicateJsonSchema(rootSchema, context); return rootSchema; }
private void ProcessVirtualField( BaseVirtualField baseVirtualField, Content definition, VirtualFieldContext context) { if (baseVirtualField is VirtualMultiEntityField virtualMultiEntityField) { string path = virtualMultiEntityField.Path; var virtualFieldKey = Tuple.Create(definition, path); if (context.VirtualFields.ContainsKey(virtualFieldKey)) { return; } Field foundField = _virtualFieldPathEvaluator .GetFieldByPath(path, definition, out bool hasFilter, out Content parent); if (!hasFilter) { context.IgnoredFields.Add(Tuple.Create(parent, foundField)); } context.VirtualFields[virtualFieldKey] = foundField; if (foundField is EntityField foundEntityField) { foreach (BaseVirtualField childField in virtualMultiEntityField.Fields) { ProcessVirtualField(childField, foundEntityField.Content, context); } } else { throw new InvalidOperationException( "В Path VirtualMultiEntityField должны быть только поля EntityField или наследники"); } } else if (baseVirtualField is VirtualEntityField virtualEntityField) { foreach (BaseVirtualField childField in virtualEntityField.Fields) { ProcessVirtualField(childField, definition, context); } } else if (baseVirtualField is VirtualField virtualField) { string path = virtualField.Path; var virtualFieldKey = Tuple.Create(definition, path); if (context.VirtualFields.ContainsKey(virtualFieldKey)) { return; } Field fieldToMove = _virtualFieldPathEvaluator .GetFieldByPath(path, definition, out bool hasFilter, out Content parent); if (!hasFilter) { context.IgnoredFields.Add(Tuple.Create(parent, fieldToMove)); } context.VirtualFields[virtualFieldKey] = fieldToMove; } }