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

com.networknt.oas.jsonoverlay.Resolver 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.ObjectNode;

import java.net.URL;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

public class Resolver {

	private Set resolvedBases = new HashSet<>();
	private final ReferenceRegistry referenceRegistry;
	private final ResolutionBaseRegistry resolutionBaseRegistry;

	public Resolver(ReferenceRegistry referenceRegistry, ResolutionBaseRegistry resolutionBaseRegistry) {
		this.referenceRegistry = referenceRegistry;
		this.resolutionBaseRegistry = resolutionBaseRegistry;
	}

	public void preresolve(String... baseUrls) {
		for (String url : baseUrls) {
			preresolve(resolutionBaseRegistry.of(url, true));
		}
	}

	public void preresolve(URL... baseUrls) {
		for (URL url : baseUrls) {
			preresolve(resolutionBaseRegistry.of(url, true));
		}
	}

	public void preresolve(ResolutionBase base) {
		Queue toResolve = new ArrayDeque<>();
		toResolve.add(base);
		while (!toResolve.isEmpty()) {
			toResolve.addAll(preresolveBase(toResolve.remove()));
		}
	}

	private Collection preresolveBase(ResolutionBase base) {
		List discoveredBases = new ArrayList<>();
		if (!resolvedBases.contains(base)) {
			resolvedBases.add(base);
			if (base.isValid()) {
				List nodes =
						StreamSupport.stream(treeWalk(base.getJson()).spliterator(), false)
						.filter(n -> (n.isObject() && n.has("$ref")))
						.collect(Collectors.toList());
				for (JsonNode refNode : nodes) {
					JsonNode refString = refNode.get("$ref");
					String key = referenceRegistry.registerRef(refString, base, true);
					((ObjectNode) refNode).put("key", key);
					Reference ref = referenceRegistry.getRef(key);
					if (ref.isValid() && !resolvedBases.contains(ref.getBase())) {
						discoveredBases.add(ref.getBase());
					}
				}
			}
		}
		return discoveredBases;
	}

	private Iterable treeWalk(JsonNode tree) {
		final ArrayDeque toVisit = new ArrayDeque<>();
		toVisit.add(tree);
		return new Iterable() {
			@Override
			public Iterator iterator() {
				return new Iterator() {
					@Override
					public boolean hasNext() {
						return !toVisit.isEmpty();
					}

					@Override
					public JsonNode next() {
						if (hasNext()) {
							JsonNode next = toVisit.remove();
							queueChildren(next);
							return next;
						} else {
							throw new NoSuchElementException();
						}
					}

					@Override
					public void remove() {
						throw new UnsupportedOperationException();
					}

					private void queueChildren(JsonNode node) {
						if (node.isArray()) {
							for (Iterator iter = node.elements(); iter.hasNext();) {
								toVisit.addFirst(iter.next());
							}
						} else if (node.isObject()) {
							for (Iterator> iter = node.fields(); iter.hasNext();) {
								toVisit.addFirst(iter.next().getValue());
							}
						}
					}
				};
			}
		};
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy