public void Initialize(ContextBase context, SchemaScope parent, int initialDepth, ScopeType type) { base.Initialize(context, parent, initialDepth, type); ParentSchemaScope = parent; ConditionalContext = ConditionalContext.Create(context); }
public override void Initialize(ContextBase context, SchemaScope parent, int initialDepth, ScopeType type) { base.Initialize(context, parent, initialDepth, type); ChildScopes.Clear(); ParentSchemaScope = parent; ConditionalContext = ConditionalContext.Create(context, parent.ShouldValidateUnevaluated()); }
public void InitializeScopes(JsonToken token) { if (!Schema._dependencies.IsNullOrEmpty()) { foreach (KeyValuePair <string, object> dependency in Schema._dependencies.GetInnerDictionary()) { JSchema dependencySchema = dependency.Value as JSchema; if (dependencySchema != null) { SchemaScope scope = CreateTokenScope(token, dependencySchema, ConditionalContext.Create(Context), null, InitialDepth); _dependencyScopes.Add(dependency.Key, scope); } } } }
public static SchemaScope CreateTokenScope(JsonToken token, JSchema schema, ContextBase context, SchemaScope parent, int depth) { SchemaScope scope; switch (token) { case JsonToken.StartObject: ObjectScope objectScope = context.Validator.GetCachedScope <ObjectScope>(ScopeType.Object); if (objectScope == null) { objectScope = new ObjectScope(); } objectScope.Initialize(context, parent, depth, schema); context.Scopes.Add(objectScope); objectScope.InitializeScopes(token); scope = objectScope; break; case JsonToken.StartArray: case JsonToken.StartConstructor: ArrayScope arrayScope = context.Validator.GetCachedScope <ArrayScope>(ScopeType.Array); if (arrayScope == null) { arrayScope = new ArrayScope(); } arrayScope.Initialize(context, parent, depth, schema); context.Scopes.Add(arrayScope); scope = arrayScope; break; default: PrimativeScope primativeScope = context.Validator.GetCachedScope <PrimativeScope>(ScopeType.Primitive); if (primativeScope == null) { primativeScope = new PrimativeScope(); } primativeScope.Initialize(context, parent, depth, schema); scope = primativeScope; context.Scopes.Add(scope); break; } if (!schema._allOf.IsNullOrEmpty()) { AllOfScope allOfScope = context.Validator.GetCachedScope <AllOfScope>(ScopeType.AllOf); if (allOfScope == null) { allOfScope = new AllOfScope(); } allOfScope.Initialize(context, scope, depth, ScopeType.AllOf); scope.AddChildScope(allOfScope); allOfScope.InitializeScopes(token, schema._allOf.GetInnerList(), context.Scopes.Count - 1); } if (!schema._anyOf.IsNullOrEmpty()) { AnyOfScope anyOfScope = context.Validator.GetCachedScope <AnyOfScope>(ScopeType.AnyOf); if (anyOfScope == null) { anyOfScope = new AnyOfScope(); } anyOfScope.Initialize(context, scope, depth, ScopeType.AnyOf); scope.AddChildScope(anyOfScope); anyOfScope.InitializeScopes(token, schema._anyOf.GetInnerList(), context.Scopes.Count - 1); } if (!schema._oneOf.IsNullOrEmpty()) { OneOfScope oneOfScope = context.Validator.GetCachedScope <OneOfScope>(ScopeType.OneOf); if (oneOfScope == null) { oneOfScope = new OneOfScope(); } oneOfScope.Initialize(context, scope, depth, ScopeType.OneOf); scope.AddChildScope(oneOfScope); oneOfScope.InitializeScopes(token, schema._oneOf.GetInnerList(), context.Scopes.Count - 1); } if (schema.Not != null) { NotScope notScope = context.Validator.GetCachedScope <NotScope>(ScopeType.Not); if (notScope == null) { notScope = new NotScope(); } notScope.Initialize(context, scope, depth, ScopeType.Not); scope.AddChildScope(notScope); notScope.InitializeScopes(token, new List <JSchema> { schema.Not }, context.Scopes.Count - 1); } // only makes sense to eval if/then/else when there is an if and either a then or a else if (schema.If != null && (schema.Then != null || schema.Else != null)) { IfThenElseScope ifThenElseScope = context.Validator.GetCachedScope <IfThenElseScope>(ScopeType.IfThenElse); if (ifThenElseScope == null) { ifThenElseScope = new IfThenElseScope(); } ifThenElseScope.Initialize(context, scope, depth, ScopeType.IfThenElse); scope.AddChildScope(ifThenElseScope); ifThenElseScope.If = schema.If; if (schema.Then != null) { ifThenElseScope.Then = schema.Then; ifThenElseScope.ThenContext = ConditionalContext.Create(context); } if (schema.Else != null) { ifThenElseScope.Else = schema.Else; ifThenElseScope.ElseContext = ConditionalContext.Create(context); } ifThenElseScope.InitializeScopes(token, context.Scopes.Count - 1); } return(scope); }
public ConditionalContext CreateConditionalContext() { return(ConditionalContext.Create(Context, ShouldValidateUnevaluated())); }
protected override bool EvaluateTokenCore(JsonToken token, object value, int depth) { int relativeDepth = depth - InitialDepth; if (relativeDepth == 0) { EnsureEnum(token, value); switch (token) { case JsonToken.StartArray: EnsureValid(value); TestType(Schema, JSchemaType.Array); return(false); case JsonToken.StartConstructor: JSchemaType schemaType = Schema.Type.GetValueOrDefault(JSchemaType.None); if (schemaType != JSchemaType.None) { RaiseError($"Invalid type. Expected {schemaType.GetDisplayText()} but got Constructor.", ErrorType.Type, Schema, value, null); } return(false); case JsonToken.EndArray: case JsonToken.EndConstructor: ValidateConditionalChildren(token, value, depth); int itemCount = _index + 1; if (Schema.MaximumItems != null && itemCount > Schema.MaximumItems) { RaiseError($"Array item count {itemCount} exceeds maximum count of {Schema.MaximumItems}.", ErrorType.MaximumItems, Schema, itemCount, null); } if (Schema.MinimumItems != null && itemCount < Schema.MinimumItems) { RaiseError($"Array item count {itemCount} is less than minimum count of {Schema.MinimumItems}.", ErrorType.MinimumItems, Schema, itemCount, null); } if (Schema.Contains != null && !_matchContains) { List <ValidationError> containsErrors = new List <ValidationError>(); foreach (ConditionalContext containsContext in _containsContexts) { containsErrors.AddRange(containsContext.Errors); } RaiseError($"No items match contains.", ErrorType.Contains, Schema, null, containsErrors); } return(true); default: throw new InvalidOperationException("Unexpected token when evaluating array: " + token); } } if (relativeDepth == 1) { if (JsonTokenHelpers.IsPrimitiveOrStartToken(token)) { _index++; if (Schema.UniqueItems || !Schema._validators.IsNullOrEmpty()) { if (Context.TokenWriter == null) { Context.TokenWriter = new JTokenWriter(); Context.TokenWriter.WriteToken(token, value); } } if (Schema.ItemsPositionValidation) { JSchema itemSchema = Schema._items?.ElementAtOrDefault(_index); if (itemSchema != null) { CreateScopesAndEvaluateToken(token, value, depth, itemSchema); } else { if (!Schema.AllowAdditionalItems) { RaiseError($"Index {_index + 1} has not been defined and the schema does not allow additional items.", ErrorType.AdditionalItems, Schema, value, null); } else if (Schema.AdditionalItems != null) { CreateScopesAndEvaluateToken(token, value, depth, Schema.AdditionalItems); } } } else { if (!Schema._items.IsNullOrEmpty()) { CreateScopesAndEvaluateToken(token, value, depth, Schema._items[0]); } } // no longer need to check contains schema after match if (Schema.Contains != null && !_matchContains) { ConditionalContext containsContext = ConditionalContext.Create(Context); _containsContexts.Add(containsContext); // contains scope should not have the current scope the parent // do not want contain failures setting the current scope's IsValid CreateScopesAndEvaluateToken(token, value, depth, Schema.Contains, null, containsContext); } } if (JsonTokenHelpers.IsPrimitiveOrEndToken(token)) { if (Schema.UniqueItems) { JToken currentToken = Context.TokenWriter.CurrentToken; bool isDuplicate = JsonTokenHelpers.Contains(_uniqueArrayItems, currentToken); if (isDuplicate) { object v = (currentToken is JValue valueToken) ? valueToken.Value : currentToken; RaiseError($"Non-unique array item at index {_index}.", ErrorType.UniqueItems, Schema, v, null); } else { _uniqueArrayItems.Add(Context.TokenWriter.CurrentToken); } } if (Schema.Contains != null && !_matchContains) { ConditionalContext currentContainsContext = _containsContexts[_containsContexts.Count - 1]; if (!currentContainsContext.HasErrors) { _matchContains = true; // no longer need previous errors after match _containsContexts.Clear(); } } } } return(false); }
protected ConditionalScope(ContextBase context, SchemaScope parent, int initialDepth) : base(context, parent, initialDepth) { ParentSchemaScope = parent; ConditionalContext = ConditionalContext.Create(context); }