• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 package com.networknt.schema;
17 
18 import java.net.URI;
19 import java.net.URISyntaxException;
20 
21 /**
22  * Validator for validating the correctness of $id.
23  */
24 public interface JsonSchemaIdValidator {
25     /**
26      * Validates if the $id value is valid.
27      *
28      * @param id                     the $id or id
29      * @param rootSchema             true if this is a root schema
30      * @param schemaLocation         the schema location
31      * @param resolvedSchemaLocation the schema location after resolving with the id
32      * @param validationContext      the validation context for instance to get the
33      *                               meta schema
34      * @return true if valid
35      */
validate(String id, boolean rootSchema, SchemaLocation schemaLocation, SchemaLocation resolvedSchemaLocation, ValidationContext validationContext)36     boolean validate(String id, boolean rootSchema, SchemaLocation schemaLocation,
37             SchemaLocation resolvedSchemaLocation, ValidationContext validationContext);
38 
39     public static final JsonSchemaIdValidator DEFAULT = new DefaultJsonSchemaIdValidator();
40 
41     /**
42      * Implementation of {@link JsonSchemaIdValidator}.
43      * <p>
44      * Note that this does not strictly follow the specification.
45      * <p>
46      * This allows an $id that isn't an absolute-IRI on the root schema but it must
47      * resolve to an absolute-IRI given a base-IRI.
48      * <p>
49      * This also allows non-empty fragments.
50      */
51     public static class DefaultJsonSchemaIdValidator implements JsonSchemaIdValidator {
52         @Override
validate(String id, boolean rootSchema, SchemaLocation schemaLocation, SchemaLocation resolvedSchemaLocation, ValidationContext validationContext)53         public boolean validate(String id, boolean rootSchema, SchemaLocation schemaLocation,
54                 SchemaLocation resolvedSchemaLocation, ValidationContext validationContext) {
55             if (hasNoContext(schemaLocation)) {
56                 // The following are non-standard
57                 if (isFragment(id) || startsWithSlash(id)) {
58                     return true;
59                 }
60             }
61             return resolvedSchemaLocation.getAbsoluteIri() != null
62                     && isAbsoluteIri(resolvedSchemaLocation.getAbsoluteIri().toString());
63         }
64 
startsWithSlash(String id)65         protected boolean startsWithSlash(String id) {
66             return id.startsWith("/");
67         }
68 
isFragment(String id)69         protected boolean isFragment(String id) {
70             return id.startsWith("#");
71         }
72 
hasNoContext(SchemaLocation schemaLocation)73         protected boolean hasNoContext(SchemaLocation schemaLocation) {
74             return schemaLocation.getAbsoluteIri() == null || schemaLocation.toString().startsWith("#");
75         }
76 
isAbsoluteIri(String iri)77         protected boolean isAbsoluteIri(String iri) {
78             if (!iri.contains(":")) {
79                 return false; // quick check
80             }
81             try {
82                 new URI(iri);
83             } catch (URISyntaxException e) {
84                 return false;
85             }
86             return true;
87         }
88     }
89 }
90