All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.fge.jsonschema.tree.BaseSchemaTree Maven / Gradle / Ivy

There is a newer version: 2.2.6
Show newest version
/*
 * Copyright (c) 2013, Francis Galiegue 
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the Lesser GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Lesser GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */

package com.github.fge.jsonschema.tree;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.fge.jsonschema.processing.ProcessingException;
import com.github.fge.jsonschema.processing.ref.Dereferencing;
import com.github.fge.jsonschema.ref.JsonPointer;
import com.github.fge.jsonschema.ref.JsonRef;
import com.github.fge.jsonschema.util.JacksonUtils;

/**
 * A {@link JsonTree2} carrying URI resolution context information
 *
 * 

In addition to what {@link JsonTree2} does, this tree also modifies URI * resolution context information when changing paths, and adds methods in order * to query this resolution context.

* *

All context information is carried as JSON References, since this is what * is used for addressing in JSON Schema.

* * @see JsonRef * @see CanonicalSchemaTree2 * @see InlineSchemaTree2 */ public abstract class BaseSchemaTree implements SchemaTree { protected static final JsonNodeFactory FACTORY = JacksonUtils.nodeFactory(); /** * Whether this schema is valid */ protected final boolean valid; /** * The initial node */ protected final JsonNode baseNode; /** * The current JSON Pointer into the node. Starts empty. */ protected final JsonPointer pointer; /** * The current node. */ protected final JsonNode node; /** * Whether inline dereferencing is used */ private final Dereferencing dereferencing; /** * The JSON Reference from which this node has been loaded * *

If loaded without a URI, this will be the empty reference.

*/ protected final JsonRef loadingRef; /** * The JSON Reference representing the context at the root of the schema * *

It will defer from {@link #loadingRef} if there is an {@code id} at * the top level.

*/ protected final JsonRef startingRef; /** * The current resolution context */ protected JsonRef currentRef; /** * The main constructor * * @param loadingRef the loading reference * @param baseNode the base node */ protected BaseSchemaTree(final JsonRef loadingRef, final JsonNode baseNode, final Dereferencing dereferencing) { this(loadingRef, baseNode, JsonPointer.empty(), dereferencing); } /** * The main constructor * * @param loadingRef the loading reference * @param baseNode the base node */ protected BaseSchemaTree(final JsonRef loadingRef, final JsonNode baseNode, final JsonPointer pointer, final Dereferencing dereferencing) { this(loadingRef, baseNode, pointer, dereferencing, false); } protected BaseSchemaTree(final JsonRef loadingRef, final JsonNode baseNode, final JsonPointer pointer, final Dereferencing dereferencing, final boolean valid) { this.baseNode = baseNode; this.pointer = pointer; node = pointer.resolve(baseNode); this.dereferencing = dereferencing; this.loadingRef = loadingRef; final JsonRef ref = idFromNode(baseNode); startingRef = ref == null ? loadingRef : loadingRef.resolve(ref); currentRef = nextRef(startingRef, pointer.asElements(), baseNode); this.valid = valid; } @Override public final JsonNode getBaseNode() { return baseNode; } @Override public final JsonPointer getPointer() { return pointer; } @Override public final JsonNode getNode() { return node; } /** * Resolve a JSON Reference against the current resolution context * * @param other the JSON Reference to resolve * @return the resolved reference * @see JsonRef#resolve(JsonRef) */ @Override public final JsonRef resolve(final JsonRef other) { return currentRef.resolve(other); } /** * Get the loading URI for that schema * * @return the loading URI as a {@link JsonRef} */ @Override public final JsonRef getLoadingRef() { return loadingRef; } /** * Get the current resolution context * * @return the context as a {@link JsonRef} */ @Override public final JsonRef getContext() { return currentRef; } @Override public final boolean isValid() { return valid; } /** * Build a JSON Reference from a node * *

This will return {@code null} if the reference could not be built. The * conditions for a successful build are as follows:

* *
    *
  • the node is an object;
  • *
  • it has a member named {@code id};
  • *
  • the value of this member is a string;
  • *
  • this string is a valid URI.
  • *
* * @param node the node * @return a JSON Reference, or {@code null} */ protected static JsonRef idFromNode(final JsonNode node) { if (!node.path("id").isTextual()) return null; try { return JsonRef.fromString(node.get("id").textValue()); } catch (ProcessingException ignored) { return null; } } /** * Calculate the next URI context from a starting reference and node * * @param startingRef the starting reference * @param pointers the list of JSON Pointers * @param startingNode the starting node * @return the calculated reference */ protected static JsonRef nextRef(final JsonRef startingRef, final Iterable pointers, final JsonNode startingNode) { JsonRef ret = startingRef; JsonRef idRef; JsonNode node = startingNode; for (final JsonPointer pointer: pointers) { node = pointer.resolve(node); idRef = idFromNode(node); if (idRef != null) ret = ret.resolve(idRef); } return ret; } @Override public final JsonNode asJson() { final ObjectNode ret = FACTORY.objectNode(); ret.put("loadingURI", FACTORY.textNode(loadingRef.toString())); ret.put("pointer", FACTORY.textNode(pointer.toString())); ret.put("currentContext", FACTORY.textNode(currentRef.toString())); ret.put("dereferencing", FACTORY.textNode(dereferencing.toString())); return ret; } @Override public final String toString() { return asJson().toString(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy