com.reprezen.kaizen.oasparser.jsonoverlay.Resolver.java Source code

Java tutorial

Introduction

Here is the source code for com.reprezen.kaizen.oasparser.jsonoverlay.Resolver.java

Source

/*******************************************************************************
 *  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.reprezen.kaizen.oasparser.jsonoverlay;

import java.net.URL;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.Set;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Queues;
import com.google.common.collect.Sets;

public class Resolver {

    private static Set<ResolutionBase> resolvedBases = Sets.newHashSet();

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

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

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

    private static Collection<ResolutionBase> preresolveBase(ResolutionBase base) {
        List<ResolutionBase> discoveredBases = Lists.newArrayList();
        if (!resolvedBases.contains(base)) {
            resolvedBases.add(base);
            if (base.isValid()) {
                for (JsonNode refNode : findReferenceNodes(base.getJson())) {
                    JsonNode refString = refNode.get("$ref");
                    String key = Reference.register(refString, base, true);
                    ((ObjectNode) refNode).put("key", key);
                    Reference ref = Reference.get(key);
                    if (ref.isValid() && !resolvedBases.contains(ref.getBase())) {
                        discoveredBases.add(ref.getBase());
                    }
                }
            }
        }
        return discoveredBases;
    }

    private final static Predicate<JsonNode> refNodeFilter = new Predicate<JsonNode>() {
        @Override
        public boolean apply(JsonNode node) {
            // accepting nodes with non-text $ref properties will mean we'll get Reference objects marked as invalid, as
            // desired
            return node.isObject() && node.has("$ref");
        }
    };

    private static Iterable<JsonNode> findReferenceNodes(JsonNode tree) {
        return Iterables.filter(treeWalk(tree), refNodeFilter);
    }

    private static Iterable<JsonNode> treeWalk(JsonNode tree) {
        final ArrayDeque<JsonNode> toVisit = Queues.newArrayDeque();
        toVisit.add(tree);
        return new Iterable<JsonNode>() {
            @Override
            public Iterator<JsonNode> iterator() {
                return new Iterator<JsonNode>() {
                    @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<JsonNode> iter = node.elements(); iter.hasNext();) {
                                toVisit.addFirst(iter.next());
                            }
                        } else if (node.isObject()) {
                            for (Iterator<Entry<String, JsonNode>> iter = node.fields(); iter.hasNext();) {
                                toVisit.addFirst(iter.next().getValue());
                            }
                        }
                    }
                };
            }
        };
    }
}