1 /* 2 * Copyright (c) 2023 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.networknt.schema; 18 19 import com.networknt.schema.annotation.JsonNodeAnnotations; 20 import com.networknt.schema.result.JsonNodeResults; 21 22 import java.util.Stack; 23 24 /** 25 * Stores the execution context for the validation run. 26 */ 27 public class ExecutionContext { 28 private ExecutionConfig executionConfig; 29 private CollectorContext collectorContext = null; 30 private ValidatorState validatorState = null; 31 private Stack<DiscriminatorContext> discriminatorContexts = null; 32 private JsonNodeAnnotations annotations = null; 33 private JsonNodeResults results = null; 34 35 /** 36 * This is used during the execution to determine if the validator should fail fast. 37 * <p> 38 * This valid is determined by the previous validator. 39 */ 40 private Boolean failFast = null; 41 42 /** 43 * Creates an execution context. 44 */ ExecutionContext()45 public ExecutionContext() { 46 this(new ExecutionConfig(), null); 47 } 48 49 /** 50 * Creates an execution context. 51 * 52 * @param collectorContext the collector context 53 */ ExecutionContext(CollectorContext collectorContext)54 public ExecutionContext(CollectorContext collectorContext) { 55 this(new ExecutionConfig(), collectorContext); 56 } 57 58 /** 59 * Creates an execution context. 60 * 61 * @param executionConfig the execution configuration 62 */ ExecutionContext(ExecutionConfig executionConfig)63 public ExecutionContext(ExecutionConfig executionConfig) { 64 this(executionConfig, null); 65 } 66 67 /** 68 * Creates an execution context. 69 * 70 * @param executionConfig the execution configuration 71 * @param collectorContext the collector context 72 */ ExecutionContext(ExecutionConfig executionConfig, CollectorContext collectorContext)73 public ExecutionContext(ExecutionConfig executionConfig, CollectorContext collectorContext) { 74 this.collectorContext = collectorContext; 75 this.executionConfig = executionConfig; 76 } 77 78 /** 79 * Gets the collector context. 80 * 81 * @return the collector context 82 */ getCollectorContext()83 public CollectorContext getCollectorContext() { 84 if (this.collectorContext == null) { 85 this.collectorContext = new CollectorContext(); 86 } 87 return this.collectorContext; 88 } 89 90 /** 91 * Sets the collector context. 92 * 93 * @param collectorContext the collector context 94 */ setCollectorContext(CollectorContext collectorContext)95 public void setCollectorContext(CollectorContext collectorContext) { 96 this.collectorContext = collectorContext; 97 } 98 99 /** 100 * Gets the execution configuration. 101 * 102 * @return the execution configuration 103 */ getExecutionConfig()104 public ExecutionConfig getExecutionConfig() { 105 return executionConfig; 106 } 107 108 /** 109 * Sets the execution configuration. 110 * 111 * @param executionConfig the execution configuration 112 */ setExecutionConfig(ExecutionConfig executionConfig)113 public void setExecutionConfig(ExecutionConfig executionConfig) { 114 this.executionConfig = executionConfig; 115 } 116 getAnnotations()117 public JsonNodeAnnotations getAnnotations() { 118 if (this.annotations == null) { 119 this.annotations = new JsonNodeAnnotations(); 120 } 121 return annotations; 122 } 123 getResults()124 public JsonNodeResults getResults() { 125 if (this.results == null) { 126 this.results = new JsonNodeResults(); 127 } 128 return results; 129 } 130 131 /** 132 * Determines if the validator should immediately throw a fail fast exception if 133 * an error has occurred. 134 * <p> 135 * This defaults to the execution config fail fast at the start of the execution. 136 * 137 * @return true if fail fast 138 */ isFailFast()139 public boolean isFailFast() { 140 if (this.failFast == null) { 141 this.failFast = getExecutionConfig().isFailFast(); 142 } 143 return failFast; 144 } 145 146 /** 147 * Sets if the validator should immediately throw a fail fast exception if an 148 * error has occurred. 149 * 150 * @param failFast true to fail fast 151 */ setFailFast(boolean failFast)152 public void setFailFast(boolean failFast) { 153 this.failFast = failFast; 154 } 155 156 /** 157 * Gets the validator state. 158 * 159 * @return the validator state 160 */ getValidatorState()161 public ValidatorState getValidatorState() { 162 return validatorState; 163 } 164 165 /** 166 * Sets the validator state. 167 * 168 * @param validatorState the validator state 169 */ setValidatorState(ValidatorState validatorState)170 public void setValidatorState(ValidatorState validatorState) { 171 this.validatorState = validatorState; 172 } 173 getCurrentDiscriminatorContext()174 public DiscriminatorContext getCurrentDiscriminatorContext() { 175 if (this.discriminatorContexts == null) { 176 return null; 177 } 178 179 if (!this.discriminatorContexts.empty()) { 180 return this.discriminatorContexts.peek(); 181 } 182 return null; // this is the case when we get on a schema that has a discriminator, but it's not used in anyOf 183 } 184 enterDiscriminatorContext(final DiscriminatorContext ctx, @SuppressWarnings("unused") JsonNodePath instanceLocation)185 public void enterDiscriminatorContext(final DiscriminatorContext ctx, @SuppressWarnings("unused") JsonNodePath instanceLocation) { 186 if (this.discriminatorContexts == null) { 187 this.discriminatorContexts = new Stack<>(); 188 } 189 this.discriminatorContexts.push(ctx); 190 } 191 leaveDiscriminatorContextImmediately(@uppressWarnings"unused") JsonNodePath instanceLocation)192 public void leaveDiscriminatorContextImmediately(@SuppressWarnings("unused") JsonNodePath instanceLocation) { 193 this.discriminatorContexts.pop(); 194 } 195 } 196