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

com.networknt.oas.jsonoverlay.Reference Maven / Gradle / Ivy

There is a newer version: 2.1.38
Show newest version
/*******************************************************************************
 *  Copyright (c) 2017 ModelSolv, Inc. and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 *
 *  Contributors:
 *     ModelSolv, Inc. - initial API and implementation and/or initial documentation
 *******************************************************************************/
package com.networknt.oas.jsonoverlay;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.MissingNode;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.UUID;

public class Reference {

	private String refString;
	private String canonRefString;
	private ResolutionBase base;
	private String fragment;
	private Boolean isValid = null;
	private JsonNode json = null;
	private ResolutionException error;
	private String key;

	private final ResolutionBaseRegistry resolutionBaseRegistry;

	/* package */ Reference(String refString, String canonicalRefString, ResolutionBase base) {
		this.refString = refString;
		this.canonRefString = canonicalRefString;
		resolutionBaseRegistry = base.getResolutionBaseRegistry();
		int pos = refString.indexOf('#');
		String relUrl = pos < 0 ? refString : refString.substring(0, pos);
		if (relUrl.isEmpty()) {
			this.base = base;
		} else {
			// note re false: if creating a ref with resolution requested, the base will be
			// resolved as a side-effect during ref resolution, so no need to do it now.
			this.base = resolutionBaseRegistry.of(base.comprehend(relUrl), false);
		}
		if (pos >= 0) {
			this.fragment = refString.substring(pos);
		}
		if (fragment != null) {
			try {
				// certain chars *should* be URL encoded in fragments, and if they are we'll
				// decode them before applying
				// as a pointer. But if not, we don't complain (all our URL/URI parsing is done
				// with fragments removed).
				this.fragment = URLDecoder.decode(fragment, "UTF-8");
			} catch (UnsupportedEncodingException e) {
			}
		}
		this.key = canonRefString;
	}

	/* package */ Reference(String refString, ResolutionBase base, ResolutionException e) {
		this.refString = refString;
		this.canonRefString = null;
		resolutionBaseRegistry = base.getResolutionBaseRegistry();
		this.fragment = null;
		this.base = base;
		this.isValid = false;
		this.error = e;
		this.key = UUID.randomUUID().toString();
	}

	public String getRefString() {
		return refString;
	}

	public String getCanonicalRefString() {
		return canonRefString;
	}

	public ResolutionBase getBase() {
		return base;
	}

	public String getFragment() {
		return fragment;
	}

	public JsonNode getJson() {
		if (isValid()) {
			return json;
		} else {
			return MissingNode.getInstance();
		}
	}

	public boolean isValid() {
		return isValid != null && isValid;
	}

	public boolean isInvalid() {
		return isValid != null && !isValid;
	}

	public boolean isResolved() {
		return isValid != null;
	}

	public ResolutionException getError() {
		return error;
	}

	public String getErrorReason() {
		return error != null ? error.getLocalizedMessage() : null;
	}

	public String getKey() {
		return key;
	}

	public JsonNode resolve() {
		if (!isResolved()) {
			try {
				JsonNode root = base.resolve();
				if (fragment == null) {
					this.json = root;
				} else {
					try {
						this.json = root.at(fragment.substring(1));
						if (json.isMissingNode()) {
							throw new ResolutionException(
									"JSON pointer does not address a value in the containing structure");
						}
					} catch (IllegalArgumentException e) {
						throw new ResolutionException("Failed to resolve JSON pointer", e);
					}
				}
				isValid = true;
			} catch (ResolutionException e) {
				this.error = e;
				this.isValid = false;
				this.json = MissingNode.getInstance();
			}
		}
		return json;
	}

	@Override
	public String toString() {
		return String.format("Reference[$ref=%s; canonical=%s; valid=%s, badReason=%s]", getRefString(),
				getCanonicalRefString(), isValid(), getErrorReason());
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy