Browse Source

Started with nested schemas.

pull/297/head
Sebastian 8 years ago
parent
commit
7f5b43da0b
  1. 35
      src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayFieldProperties.cs
  2. 16
      src/Squidex.Domain.Apps.Core.Model/Schemas/IArrayField.cs
  3. 2
      src/Squidex.Domain.Apps.Core.Model/Schemas/IFieldPropertiesVisitor.cs
  4. 2
      src/Squidex.Domain.Apps.Core.Model/Schemas/IFieldVisitor.cs
  5. 39
      src/Squidex.Domain.Apps.Core.Operations/EnrichContent/DefaultValueFactory.cs
  6. 5
      src/Squidex.Domain.Apps.Core.Operations/GenerateEdmSchema/EdmTypeVisitor.cs
  7. 24
      src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/JsonTypeVisitor.cs
  8. 10
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/JsonValueConverter.cs
  9. 50
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/FieldValidator.cs
  10. 84
      src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ValidatorsFactory.cs
  11. 10
      src/Squidex.Domain.Apps.Entities/Schemas/Guards/FieldPropertiesValidator.cs

35
src/Squidex.Domain.Apps.Core.Model/Schemas/ArrayFieldProperties.cs

@ -0,0 +1,35 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Core.Schemas
{
[TypeName("ArrayField")]
public sealed class ArrayFieldProperties : FieldProperties
{
public int? MinItems { get; set; }
public int? MaxItems { get; set; }
public override T Accept<T>(IFieldPropertiesVisitor<T> visitor)
{
throw new NotImplementedException();
}
public override T Accept<T>(IFieldVisitor<T> visitor, IField field)
{
throw new NotImplementedException();
}
public override Field CreateField(long id, string name, Partitioning partitioning)
{
throw new NotImplementedException();
}
}
}

16
src/Squidex.Domain.Apps.Core.Model/Schemas/IArrayField.cs

@ -0,0 +1,16 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Collections.Generic;
namespace Squidex.Domain.Apps.Core.Schemas
{
public interface IArrayField : IField<ArrayFieldProperties>
{
IReadOnlyCollection<IField> Fields { get; }
}
}

2
src/Squidex.Domain.Apps.Core.Model/Schemas/IFieldPropertiesVisitor.cs

@ -9,6 +9,8 @@ namespace Squidex.Domain.Apps.Core.Schemas
{
public interface IFieldPropertiesVisitor<out T>
{
T Visit(ArrayFieldProperties properties);
T Visit(AssetsFieldProperties properties);
T Visit(BooleanFieldProperties properties);

2
src/Squidex.Domain.Apps.Core.Model/Schemas/IFieldVisitor.cs

@ -9,6 +9,8 @@ namespace Squidex.Domain.Apps.Core.Schemas
{
public interface IFieldVisitor<out T>
{
T Visit(IArrayField field);
T Visit(IField<AssetsFieldProperties> field);
T Visit(IField<BooleanFieldProperties> field);

39
src/Squidex.Domain.Apps.Core.Operations/EnrichContent/DefaultValueFactory.cs

@ -13,7 +13,7 @@ using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Core.EnrichContent
{
public sealed class DefaultValueFactory : IFieldPropertiesVisitor<JToken>
public sealed class DefaultValueFactory : IFieldVisitor<JToken>
{
private readonly Instant now;
@ -26,62 +26,67 @@ namespace Squidex.Domain.Apps.Core.EnrichContent
{
Guard.NotNull(field, nameof(field));
return field.RawProperties.Accept(new DefaultValueFactory(now));
return field.Accept(new DefaultValueFactory(now));
}
public JToken Visit(AssetsFieldProperties properties)
public JToken Visit(IArrayField field)
{
return new JArray();
}
public JToken Visit(BooleanFieldProperties properties)
public JToken Visit(IField<AssetsFieldProperties> field)
{
return properties.DefaultValue;
return new JArray();
}
public JToken Visit(IField<BooleanFieldProperties> field)
{
return field.Properties.DefaultValue;
}
public JToken Visit(GeolocationFieldProperties properties)
public JToken Visit(IField<GeolocationFieldProperties> field)
{
return JValue.CreateNull();
}
public JToken Visit(JsonFieldProperties properties)
public JToken Visit(IField<JsonFieldProperties> field)
{
return JValue.CreateNull();
}
public JToken Visit(NumberFieldProperties properties)
public JToken Visit(IField<NumberFieldProperties> field)
{
return properties.DefaultValue;
return field.Properties.DefaultValue;
}
public JToken Visit(ReferencesFieldProperties properties)
public JToken Visit(IField<ReferencesFieldProperties> field)
{
return new JArray();
}
public JToken Visit(StringFieldProperties properties)
public JToken Visit(IField<StringFieldProperties> field)
{
return properties.DefaultValue;
return field.Properties.DefaultValue;
}
public JToken Visit(TagsFieldProperties properties)
public JToken Visit(IField<TagsFieldProperties> field)
{
return new JArray();
}
public JToken Visit(DateTimeFieldProperties properties)
public JToken Visit(IField<DateTimeFieldProperties> field)
{
if (properties.CalculatedDefaultValue == DateTimeCalculatedDefaultValue.Now)
if (field.Properties.CalculatedDefaultValue == DateTimeCalculatedDefaultValue.Now)
{
return now.ToString();
}
if (properties.CalculatedDefaultValue == DateTimeCalculatedDefaultValue.Today)
if (field.Properties.CalculatedDefaultValue == DateTimeCalculatedDefaultValue.Today)
{
return now.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
}
return properties.DefaultValue?.ToString();
return field.Properties.DefaultValue?.ToString();
}
}
}

5
src/Squidex.Domain.Apps.Core.Operations/GenerateEdmSchema/EdmTypeVisitor.cs

@ -23,6 +23,11 @@ namespace Squidex.Domain.Apps.Core.GenerateEdmSchema
return field.Accept(Instance);
}
public IEdmTypeReference Visit(IArrayField field)
{
return null;
}
public IEdmTypeReference Visit(IField<AssetsFieldProperties> field)
{
return CreatePrimitive(EdmPrimitiveTypeKind.String, field);

24
src/Squidex.Domain.Apps.Core.Operations/GenerateJsonSchema/JsonTypeVisitor.cs

@ -21,6 +21,30 @@ namespace Squidex.Domain.Apps.Core.GenerateJsonSchema
this.schemaResolver = schemaResolver;
}
public JsonProperty Visit(IArrayField field)
{
return CreateProperty(field, jsonProperty =>
{
var itemSchema = new JsonSchema4
{
Type = JsonObjectType.Object
};
foreach (var child in field.Fields)
{
var childProperty = field.Accept(this);
childProperty.Description = child.RawProperties.Hints;
childProperty.IsRequired = child.RawProperties.IsRequired;
itemSchema.Properties.Add(child.Name, childProperty);
}
jsonProperty.Type = JsonObjectType.Object;
jsonProperty.Item = itemSchema;
});
}
public JsonProperty Visit(IField<AssetsFieldProperties> field)
{
return CreateProperty(field, jsonProperty =>

10
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/JsonValueConverter.cs

@ -28,11 +28,21 @@ namespace Squidex.Domain.Apps.Core.ValidateContent
return field.Accept(new JsonValueConverter(json));
}
public object Visit(IArrayField field)
{
return Value.ToObject<List<JObject>>();
}
public object Visit(IField<AssetsFieldProperties> field)
{
return Value.ToObject<List<Guid>>();
}
internal static object ConvertValue(IField field, object value)
{
throw new NotImplementedException();
}
public object Visit(IField<BooleanFieldProperties> field)
{
return (bool?)Value;

50
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/Validators/FieldValidator.cs

@ -0,0 +1,50 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Squidex.Domain.Apps.Core.Schemas;
using Squidex.Infrastructure.Json;
namespace Squidex.Domain.Apps.Core.ValidateContent.Validators
{
public sealed class FieldValidator : IValidator
{
private readonly IEnumerable<IValidator> validators;
private readonly IField field;
public FieldValidator(IEnumerable<IValidator> validators, IField field)
{
this.validators = validators;
this.field = field;
}
public async Task ValidateAsync(object value, ValidationContext context, Action<string> addError)
{
try
{
object typedValue = null;
if (value is JToken jToken)
{
typedValue = jToken.IsNull() ? null : JsonValueConverter.ConvertValue(field, jToken);
}
foreach (var validator in ValidatorsFactory.CreateValidators(field))
{
await validator.ValidateAsync(typedValue, context, addError);
}
}
catch
{
addError("<FIELD> is not a valid value.");
}
}
}
}

84
src/Squidex.Domain.Apps.Core.Operations/ValidateContent/ValidatorsFactory.cs

@ -15,7 +15,7 @@ using Squidex.Infrastructure;
namespace Squidex.Domain.Apps.Core.ValidateContent
{
public sealed class ValidatorsFactory : IFieldPropertiesVisitor<IEnumerable<IValidator>>
public sealed class ValidatorsFactory : IFieldVisitor<IEnumerable<IValidator>>
{
private static readonly ValidatorsFactory Instance = new ValidatorsFactory();
@ -27,115 +27,123 @@ namespace Squidex.Domain.Apps.Core.ValidateContent
{
Guard.NotNull(field, nameof(field));
return field.RawProperties.Accept(Instance);
return field.Accept(Instance);
}
public IEnumerable<IValidator> Visit(AssetsFieldProperties properties)
public IEnumerable<IValidator> Visit(IArrayField field)
{
if (properties.IsRequired || properties.MinItems.HasValue || properties.MaxItems.HasValue)
if (field.Properties.IsRequired || field.Properties.MinItems.HasValue || field.Properties.MaxItems.HasValue)
{
yield return new CollectionValidator<Guid>(properties.IsRequired, properties.MinItems, properties.MaxItems);
yield return new CollectionValidator<Guid>(field.Properties.IsRequired, field.Properties.MinItems, field.Properties.MaxItems);
}
}
public IEnumerable<IValidator> Visit(IField<AssetsFieldProperties> field)
{
if (field.Properties.IsRequired || field.Properties.MinItems.HasValue || field.Properties.MaxItems.HasValue)
{
yield return new CollectionValidator<Guid>(field.Properties.IsRequired, field.Properties.MinItems, field.Properties.MaxItems);
}
yield return new AssetsValidator(properties);
yield return new AssetsValidator(field.Properties);
}
public IEnumerable<IValidator> Visit(BooleanFieldProperties properties)
public IEnumerable<IValidator> Visit(IField<BooleanFieldProperties> field)
{
if (properties.IsRequired)
if (field.Properties.IsRequired)
{
yield return new RequiredValidator();
}
}
public IEnumerable<IValidator> Visit(DateTimeFieldProperties properties)
public IEnumerable<IValidator> Visit(IField<DateTimeFieldProperties> field)
{
if (properties.IsRequired)
if (field.Properties.IsRequired)
{
yield return new RequiredValidator();
}
if (properties.MinValue.HasValue || properties.MaxValue.HasValue)
if (field.Properties.MinValue.HasValue || field.Properties.MaxValue.HasValue)
{
yield return new RangeValidator<Instant>(properties.MinValue, properties.MaxValue);
yield return new RangeValidator<Instant>(field.Properties.MinValue, field.Properties.MaxValue);
}
}
public IEnumerable<IValidator> Visit(GeolocationFieldProperties properties)
public IEnumerable<IValidator> Visit(IField<GeolocationFieldProperties> field)
{
if (properties.IsRequired)
if (field.Properties.IsRequired)
{
yield return new RequiredValidator();
}
}
public IEnumerable<IValidator> Visit(JsonFieldProperties properties)
public IEnumerable<IValidator> Visit(IField<JsonFieldProperties> field)
{
if (properties.IsRequired)
if (field.Properties.IsRequired)
{
yield return new RequiredValidator();
}
}
public IEnumerable<IValidator> Visit(NumberFieldProperties properties)
public IEnumerable<IValidator> Visit(IField<NumberFieldProperties> field)
{
if (properties.IsRequired)
if (field.Properties.IsRequired)
{
yield return new RequiredValidator();
}
if (properties.MinValue.HasValue || properties.MaxValue.HasValue)
if (field.Properties.MinValue.HasValue || field.Properties.MaxValue.HasValue)
{
yield return new RangeValidator<double>(properties.MinValue, properties.MaxValue);
yield return new RangeValidator<double>(field.Properties.MinValue, field.Properties.MaxValue);
}
if (properties.AllowedValues != null)
if (field.Properties.AllowedValues != null)
{
yield return new AllowedValuesValidator<double>(properties.AllowedValues.ToArray());
yield return new AllowedValuesValidator<double>(field.Properties.AllowedValues.ToArray());
}
}
public IEnumerable<IValidator> Visit(ReferencesFieldProperties properties)
public IEnumerable<IValidator> Visit(IField<ReferencesFieldProperties> field)
{
if (properties.IsRequired || properties.MinItems.HasValue || properties.MaxItems.HasValue)
if (field.Properties.IsRequired || field.Properties.MinItems.HasValue || field.Properties.MaxItems.HasValue)
{
yield return new CollectionValidator<Guid>(properties.IsRequired, properties.MinItems, properties.MaxItems);
yield return new CollectionValidator<Guid>(field.Properties.IsRequired, field.Properties.MinItems, field.Properties.MaxItems);
}
if (properties.SchemaId != Guid.Empty)
if (field.Properties.SchemaId != Guid.Empty)
{
yield return new ReferencesValidator(properties.SchemaId);
yield return new ReferencesValidator(field.Properties.SchemaId);
}
}
public IEnumerable<IValidator> Visit(StringFieldProperties properties)
public IEnumerable<IValidator> Visit(IField<StringFieldProperties> field)
{
if (properties.IsRequired)
if (field.Properties.IsRequired)
{
yield return new RequiredStringValidator();
}
if (properties.MinLength.HasValue || properties.MaxLength.HasValue)
if (field.Properties.MinLength.HasValue || field.Properties.MaxLength.HasValue)
{
yield return new StringLengthValidator(properties.MinLength, properties.MaxLength);
yield return new StringLengthValidator(field.Properties.MinLength, field.Properties.MaxLength);
}
if (!string.IsNullOrWhiteSpace(properties.Pattern))
if (!string.IsNullOrWhiteSpace(field.Properties.Pattern))
{
yield return new PatternValidator(properties.Pattern, properties.PatternMessage);
yield return new PatternValidator(field.Properties.Pattern, field.Properties.PatternMessage);
}
if (properties.AllowedValues != null)
if (field.Properties.AllowedValues != null)
{
yield return new AllowedValuesValidator<string>(properties.AllowedValues.ToArray());
yield return new AllowedValuesValidator<string>(field.Properties.AllowedValues.ToArray());
}
}
public IEnumerable<IValidator> Visit(TagsFieldProperties properties)
public IEnumerable<IValidator> Visit(IField<TagsFieldProperties> field)
{
if (properties.IsRequired || properties.MinItems.HasValue || properties.MaxItems.HasValue)
if (field.Properties.IsRequired || field.Properties.MinItems.HasValue || field.Properties.MaxItems.HasValue)
{
yield return new CollectionValidator<string>(properties.IsRequired, properties.MinItems, properties.MaxItems);
yield return new CollectionValidator<string>(field.Properties.IsRequired, field.Properties.MinItems, field.Properties.MaxItems);
}
yield return new CollectionItemValidator<string>(new RequiredStringValidator());

10
src/Squidex.Domain.Apps.Entities/Schemas/Guards/FieldPropertiesValidator.cs

@ -25,6 +25,16 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
return properties?.Accept(Instance) ?? Enumerable.Empty<ValidationError>();
}
public IEnumerable<ValidationError> Visit(ArrayFieldProperties properties)
{
if (properties.MaxItems.HasValue && properties.MinItems.HasValue && properties.MinItems.Value >= properties.MaxItems.Value)
{
yield return new ValidationError("Max items must be greater than min items.",
nameof(properties.MinItems),
nameof(properties.MaxItems));
}
}
public IEnumerable<ValidationError> Visit(AssetsFieldProperties properties)
{
if (properties.MaxItems.HasValue && properties.MinItems.HasValue && properties.MinItems.Value >= properties.MaxItems.Value)

Loading…
Cancel
Save