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

io.sundr.dsl.internal.utils.GraphUtils Maven / Gradle / Ivy

There is a newer version: 1.14.0
Show newest version
/*
 * Copyright 2015 The original authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package io.sundr.dsl.internal.utils;

import io.sundr.codegen.model.JavaClazz;
import io.sundr.codegen.model.JavaType;
import io.sundr.dsl.internal.processor.Node;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

import static io.sundr.dsl.internal.Constants.CARDINALITY_MULTIPLE;
import static io.sundr.dsl.internal.Constants.EXCLUSIVE;
import static io.sundr.dsl.internal.Constants.KEYWORDS;
import static io.sundr.dsl.internal.Constants.REQUIRES_ALL;
import static io.sundr.dsl.internal.Constants.REQUIRES_ANY;
import static io.sundr.dsl.internal.utils.JavaTypeUtils.isEntryPoint;
import static io.sundr.dsl.internal.utils.JavaTypeUtils.isTerminal;
import static io.sundr.dsl.internal.utils.JavaTypeUtils.isCardinalityMultiple;

public final class GraphUtils {

    private GraphUtils() {
        //Utility Class
    }

    public static Set> createGraph(Set clazzes) {
        Set> nodes = new LinkedHashSet>();
        for (JavaClazz clazz : clazzes) {
            if (isEntryPoint(clazz)) {
                nodes.add(createGraph(clazz, clazzes, new LinkedHashSet(), new LinkedHashSet()));

            }
        }
        return nodes;
    }

    public static Node createGraph(JavaClazz root, Set all, Set path, Set visited) {
        Set next = new LinkedHashSet();
        Set currentPath = new LinkedHashSet(path);

        if (!isTerminal(root)) {
            currentPath.add(root.getType());
            for (JavaClazz candidate : exclusion(all, visited)) {
                if (!isEntryPoint(candidate) && isSatisfied(candidate, currentPath)) {
                    next.add(candidate);
                }
            }
            next.remove(root);
        }

        Set> nextVertices = new LinkedHashSet>();
        Set levelInterfaces = new LinkedHashSet();
        levelInterfaces.addAll(visited);

        for (JavaClazz c : next) {
            Node subGraph = createGraph(c, all, currentPath, levelInterfaces);
            levelInterfaces.add(subGraph.getItem().getType());
            levelInterfaces.addAll(subGraph.getItem().getType().getInterfaces());
            if (subGraph.getTransitions().size() > 0 || isTerminal(subGraph.getItem())) {
                nextVertices.add(subGraph);
            }
        }
        return new Node(root, nextVertices);
    }

    private static Set exclusion(Set one, Set excluded) {
        Set result = new LinkedHashSet();
        for (JavaClazz item : one) {
            if (!excluded.contains(item.getType()) || isTerminal(item) || isCardinalityMultiple(item)) {
                result.add(item);
            }
        }
        return result;
    }


    private static boolean isSatisfied(JavaClazz candidate, Set visited) {
        Set visitedKeywords = getKeywords(visited);

        Boolean multiple = (Boolean) candidate.getType().getAttributes().get(CARDINALITY_MULTIPLE);
        Set requiresAll = (Set) candidate.getType().getAttributes().get(REQUIRES_ALL);
        Set requiresAny = (Set) candidate.getType().getAttributes().get(REQUIRES_ANY);
        Set exclusive = (Set) candidate.getType().getAttributes().get(EXCLUSIVE);

        //Eliminate circles if not supported
        if (!multiple && visited.contains(candidate.getType())) {
            return false;
        }

        //Check if path contains exclusive keywords
        for (String e : exclusive) {
            if (visitedKeywords.contains(e)) {
                return false;
            }
        }

        //Check if "All" requirements are meet
        for (String a : requiresAll) {
            if (!visitedKeywords.contains(a)) {
                return false;
            }
        }

        for (String a : requiresAny) {
            if (visitedKeywords.contains(a)) {
                return true;
            }
        }

        return requiresAny.isEmpty();
    }

    private static Set getKeywords(Set types) {
        Set result = new LinkedHashSet();
        for (JavaType type : types) {
            Set keywords = (Set) type.getAttributes().get(KEYWORDS);
            result.addAll(keywords != null ? keywords : Collections.emptySet());
        }
        return result;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy