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

com.atlan.generators.ModelCache Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
// Generated by delombok at Thu Oct 10 18:56:33 UTC 2024
/* SPDX-License-Identifier: Apache-2.0
   Copyright 2023 Atlan Pte. Ltd. */
package com.atlan.generators;

import com.atlan.Atlan;
import com.atlan.exception.AtlanException;
import com.atlan.model.enums.AtlanTypeCategory;
import com.atlan.model.typedefs.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class ModelCache {
    @java.lang.SuppressWarnings("all")
    @lombok.Generated
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ModelCache.class);
    private final Map enumDefCache;
    private final Map structDefCache;
    private final Map entityDefCache;
    private final Map relationshipDefCache;
    private final Map enumCache = new HashMap<>();
    private final Map structCache = new HashMap<>();
    private final Map assetCache = new HashMap<>();
    private final Map relationshipCache = new HashMap<>();
    private final Map> subTypeToSuperTypes = new ConcurrentHashMap<>();
    private static ModelCache INSTANCE = null;

    private ModelCache() throws AtlanException {
        enumDefCache = new ConcurrentHashMap<>();
        for (EnumDef enumDef : Atlan.getDefaultClient().typeDefs.list(AtlanTypeCategory.ENUM).getEnumDefs()) {
            enumDefCache.put(enumDef.getName(), enumDef);
        }
        structDefCache = new ConcurrentHashMap<>();
        for (StructDef structDef : Atlan.getDefaultClient().typeDefs.list(AtlanTypeCategory.STRUCT).getStructDefs()) {
            structDefCache.put(structDef.getName(), structDef);
        }
        entityDefCache = new ConcurrentHashMap<>();
        for (EntityDef entityDef : Atlan.getDefaultClient().typeDefs.list(AtlanTypeCategory.ENTITY).getEntityDefs()) {
            entityDefCache.put(entityDef.getName(), entityDef);
        }
        relationshipDefCache = new ConcurrentHashMap<>();
        for (RelationshipDef relationshipDef : Atlan.getDefaultClient().typeDefs.list(AtlanTypeCategory.RELATIONSHIP).getRelationshipDefs()) {
            relationshipDefCache.put(relationshipDef.getName(), relationshipDef);
        }
    }

    private static ModelCache createInstance() {
        try {
            ModelCache cache = new ModelCache();
            cache.cacheInheritance(cache.getEntityDefCache().values());
            return cache;
        } catch (AtlanException e) {
            log.error("Unable to refresh typedef caches.", e);
            return null;
        }
    }

    public static ModelCache getInstance() {
        if (INSTANCE == null) {
            INSTANCE = createInstance();
        }
        return INSTANCE;
    }

    public EnumGenerator addEnumGenerator(String name, EnumGenerator generator) {
        return enumCache.put(name, generator);
    }

    public StructGenerator addStructGenerator(String name, StructGenerator generator) {
        return structCache.put(name, generator);
    }

    public AssetGenerator addAssetGenerator(String name, AssetGenerator generator) {
        return assetCache.put(name, generator);
    }

    public RelationshipGenerator addRelationshipGenerator(String name, RelationshipGenerator generator) {
        return relationshipCache.put(name, generator);
    }

    public List getStructNames() {
        return structCache.keySet().stream().sorted().collect(Collectors.toList());
    }

    public Collection getAssetGenerators() {
        return assetCache.values();
    }

    public AssetGenerator getAssetGenerator(String entityDefName) {
        return assetCache.get(entityDefName);
    }

    public TypeGenerator.MappedType getCachedType(String typeName) {
        if (enumCache.containsKey(typeName)) {
            return TypeGenerator.MappedType.builder().type(TypeGenerator.MappedType.Type.ENUM).name(enumCache.get(typeName).getClassName()).build();
        } else if (structCache.containsKey(typeName)) {
            return TypeGenerator.MappedType.builder().type(TypeGenerator.MappedType.Type.STRUCT).name(structCache.get(typeName).getClassName()).build();
        } else if (assetCache.containsKey(typeName)) {
            return TypeGenerator.MappedType.builder().type(TypeGenerator.MappedType.Type.ASSET).name(assetCache.get(typeName).getClassName()).build();
        }
        return null;
    }

    public AssetGenerator getCachedAssetType(String typeName) {
        return assetCache.get(typeName);
    }

    public Set getUniqueAttributesForType(String originalName) {
        EntityDef entityDef = entityDefCache.get(originalName);
        return new TreeSet<>(entityDef.getAttributeDefs().stream().map(AttributeDef::getName).collect(Collectors.toSet()));
    }

    public Set getUniqueRelationshipsForType(String originalName) {
        EntityDef entityDef = entityDefCache.get(originalName);
        Set startingPoint = new TreeSet<>(entityDef.getRelationshipAttributeDefs().stream().map(AttributeDef::getName).collect(Collectors.toSet()));
        Set superTypes = getAllSuperTypesForType(originalName);
        for (String superType : superTypes) {
            // Skip Referenceable to avoid losing the overloaded 'meanings' relationship
            if (superType != null && !superType.equals("Referenceable")) {
                EntityDef superDef = entityDefCache.get(superType);
                Set toRemove = superDef.getRelationshipAttributeDefs().stream().map(AttributeDef::getName).collect(Collectors.toSet());
                startingPoint.removeAll(toRemove);
            }
        }
        return startingPoint;
    }

    public String getTypeDescription(String originalName) {
        String fromTypeDef = null;
        TypeDef def = enumDefCache.getOrDefault(originalName, null);
        if (def == null) {
            def = structDefCache.getOrDefault(originalName, null);
        }
        if (def == null) {
            def = entityDefCache.getOrDefault(originalName, null);
        }
        if (def == null) {
            def = relationshipDefCache.getOrDefault(originalName, null);
        }
        if (def != null) {
            fromTypeDef = def.getDescription();
        }
        return (fromTypeDef != null && !fromTypeDef.isEmpty()) ? fromTypeDef : "TBC";
    }

    public String getAttributeDescription(String objectName, String attrName) {
        String fromTypeDef = null;
        TypeDef def = enumDefCache.getOrDefault(objectName, null);
        if (def == null) {
            def = structDefCache.getOrDefault(objectName, null);
        }
        if (def == null) {
            def = relationshipDefCache.getOrDefault(objectName, null);
        }
        SortedSet allAttrs = new TreeSet<>();
        if (def == null && entityDefCache.containsKey(objectName)) {
            def = entityDefCache.getOrDefault(objectName, null);
            allAttrs = getAllAttributesForType(objectName);
        } else if (def != null) {
            allAttrs = new TreeSet<>(def.getAttributeDefs());
        }
        if (def != null) {
            for (AttributeDef attr : allAttrs) {
                if (attrName.equals(attr.getName())) {
                    fromTypeDef = attr.getDescription();
                    break;
                }
            }
            if (fromTypeDef == null && def instanceof EntityDef) {
                for (RelationshipAttributeDef attr : getAllRelationshipsForType(def.getName())) {
                    String relnDefName = attr.getRelationshipTypeName();
                    RelationshipDef relnDef = relationshipDefCache.get(relnDefName);
                    if (relnDef != null) {
                        if (attrName.equals(relnDef.getEndDef1().getName())) {
                            fromTypeDef = relnDef.getEndDef1().getDescription();
                            break;
                        } else if (attrName.equals(relnDef.getEndDef2().getName())) {
                            fromTypeDef = relnDef.getEndDef2().getDescription();
                            break;
                        }
                    }
                }
            }
        }
        return (fromTypeDef != null && !fromTypeDef.isEmpty()) ? fromTypeDef : "TBC";
    }

    private void cacheInheritance(Collection toCache) {
        // Populate inheritance maps
        if (!toCache.isEmpty()) {
            List leftOvers = new ArrayList<>();
            for (EntityDef entityDef : toCache) {
                String typeName = entityDef.getName();
                List superTypes = entityDef.getSuperTypes();
                if (superTypes == null || superTypes.isEmpty()) {
                    subTypeToSuperTypes.put(typeName, new ArrayList<>());
                } else {
                    subTypeToSuperTypes.put(typeName, superTypes);
                }
                if (superTypes != null && !superTypes.isEmpty() && !typeName.equals("Asset")) {
                    for (String superType : superTypes) {
                        if (!subTypeToSuperTypes.containsKey(superType)) {
                            leftOvers.add(entityDefCache.get(superType));
                        }
                    }
                }
            }
            cacheInheritance(leftOvers);
        }
    }

    public Set getAllSuperTypesForType(String typeName) {
        List next = subTypeToSuperTypes.get(typeName);
        if (next.isEmpty()) {
            LinkedHashSet root = new LinkedHashSet<>();
            root.add(typeName);
            return root;
        } else {
            LinkedHashSet now = new LinkedHashSet<>(next);
            for (String superType : next) {
                Set again = getAllSuperTypesForType(superType);
                now.addAll(again);
            }
            return now;
        }
    }

    public SortedSet getAllNonAssetAttributesForType(String originalName) {
        SortedSet all = getAllAttributesForType(originalName);
        all.removeAll(getAllAttributesForType("Asset"));
        return all;
    }

    public SortedSet getAllNonAssetRelationshipsForType(String originalName) {
        SortedSet all = getAllRelationshipsForType(originalName);
        all.removeAll(getAllRelationshipsForType("Asset"));
        return all;
    }

    SortedSet getAllAttributesForType(String originalName) {
        SortedSet full = new TreeSet<>();
        getAttributesForType(originalName, full, new HashSet<>());
        return full;
    }

    private void getAttributesForType(String originalName, SortedSet aggregated, Set processedTypes) {
        if (!processedTypes.contains(originalName)) {
            EntityDef entityDef = entityDefCache.get(originalName);
            if (originalName.equals("Referenceable")) {
                // Retain only the 'qualifiedName' attribute from Referenceable
                List attrs = entityDefCache.get(originalName).getAttributeDefs();
                for (AttributeDef attributeDef : attrs) {
                    if (attributeDef.getName().equals("qualifiedName")) {
                        aggregated.add(attributeDef);
                    }
                }
            } else {
                addAndLogAttributeConflicts(originalName, aggregated, entityDef.getAttributeDefs(), originalName);
                processedTypes.add(originalName);
                List superTypes = entityDef.getSuperTypes();
                if (superTypes != null && !superTypes.isEmpty()) {
                    for (String superType : superTypes) {
                        getAttributesForType(superType, aggregated, processedTypes);
                    }
                }
            }
        }
    }

    SortedSet getAllRelationshipsForType(String originalName) {
        SortedSet full = new TreeSet<>();
        getRelationshipsForType(originalName, full, new HashSet<>());
        return full;
    }

    private void getRelationshipsForType(String originalName, SortedSet aggregated, Set processedTypes) {
        if (!processedTypes.contains(originalName)) {
            EntityDef entityDef = entityDefCache.get(originalName);
            if (originalName.equals("Referenceable")) {
                // Retain only the 'meanings' relationship from Referenceable
                List attrs = entityDef.getRelationshipAttributeDefs();
                for (RelationshipAttributeDef attributeDef : attrs) {
                    if (attributeDef.getName().equals("meanings")) {
                        aggregated.add(attributeDef);
                    }
                }
            } else {
                Set uniqueRelationships = getUniqueRelationshipsForType(originalName);
                Set retained = new TreeSet<>();
                for (RelationshipAttributeDef attributeDef : entityDef.getRelationshipAttributeDefs()) {
                    if (uniqueRelationships.contains(attributeDef.getName())) {
                        boolean added = retained.add(attributeDef);
                        if (!added) {
                            log.warn("Conflicting relationship found for {}, within own typedef: {}", originalName, attributeDef.getName());
                        }
                    }
                }
                if (!retained.isEmpty()) {
                    addAndLogRelationshipConflicts(originalName, aggregated, retained, originalName);
                }
                processedTypes.add(originalName);
                List superTypes = entityDef.getSuperTypes();
                if (superTypes != null && !superTypes.isEmpty()) {
                    for (String superType : superTypes) {
                        getRelationshipsForType(superType, aggregated, processedTypes);
                    }
                }
            }
        }
    }

    // Set of attributes that are known to conflict with relationship attributes of the same name
    private static final Set attributesToIgnore = Set.of("inputs", "outputs");

    static String getAttrQualifiedName(String typeName, String attrName) {
        return typeName + "|" + attrName;
    }

    private void addAndLogAttributeConflicts(String typeName, SortedSet toAddTo, Collection toAdd, String fromSuperType) {
        for (AttributeDef one : toAdd) {
            if (!attributesToIgnore.contains(one.getName())) {
                boolean added = toAddTo.add(one);
                if (!added) {
                    log.warn("Conflicting attribute found for {}, from {}: {}", typeName, fromSuperType, one.getName());
                }
            }
        }
    }

    private void addAndLogRelationshipConflicts(String typeName, SortedSet toAddTo, Collection toAdd, String fromSuperType) {
        for (RelationshipAttributeDef one : toAdd) {
            boolean added = toAddTo.add(one);
            if (!added) {
                log.warn("Conflicting relationship found for {}, from {}: {}", typeName, fromSuperType, one.getName());
            }
        }
    }

    @java.lang.SuppressWarnings("all")
    @lombok.Generated
    public Map getEnumDefCache() {
        return this.enumDefCache;
    }

    @java.lang.SuppressWarnings("all")
    @lombok.Generated
    public Map getStructDefCache() {
        return this.structDefCache;
    }

    @java.lang.SuppressWarnings("all")
    @lombok.Generated
    public Map getEntityDefCache() {
        return this.entityDefCache;
    }

    @java.lang.SuppressWarnings("all")
    @lombok.Generated
    public Map getRelationshipDefCache() {
        return this.relationshipDefCache;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy