public Map prepare()

in query/src/main/java/jetbrains/exodus/query/metadata/ModelMetaDataImpl.java [80:163]


    public Map<String, EntityMetaData> prepare() {
        Map<String, EntityMetaData> result = typeToEntityMetaDatas;
        if (result != null) {
            return result;
        }

        synchronized (entityMetaDatas) {
            result = typeToEntityMetaDatas;
            if (result != null) {
                return result;
            }
            result = new HashMap<>();

            for (final EntityMetaData emd : entityMetaDatas) {
                ((EntityMetaDataImpl) emd).reset();

                final String type = emd.getType();
                if (result.get(type) != null) {
                    throw new IllegalArgumentException("Duplicate entity [" + type + ']');
                }
                result.put(type, emd);
            }

            this.typeToEntityMetaDatas = result;

            for (EntityMetaData emd : entityMetaDatas) {
                final EntityMetaDataImpl impl = (EntityMetaDataImpl) emd;
                final Set<AssociationEndMetaData> ends = impl.getExternalAssociationEnds();
                if (ends != null) {
                    for (AssociationEndMetaData aemd : ends) {
                        final AssociationEndMetaDataImpl endImpl = (AssociationEndMetaDataImpl) aemd;
                        endImpl.resolve(this, associationMetaDatas.get(endImpl.getAssociationMetaDataName()));
                    }
                }
            }

            for (final EntityMetaData emd : entityMetaDatas) {
                Set<AssociationEndMetaData> ends = ((EntityMetaDataImpl) emd).getExternalAssociationEnds();
                final boolean wasNull = ends == null;
                String superType = emd.getSuperType();
                while (superType != null) {
                    EntityMetaData parent = result.get(superType);
                    Set<AssociationEndMetaData> parentEnds = ((EntityMetaDataImpl) parent).getExternalAssociationEnds();
                    if (parentEnds != null) {
                        if (ends == null) {
                            ends = new HashSet<>(parentEnds);
                        } else {
                            ends.addAll(parentEnds);
                        }
                    }
                    superType = parent.getSuperType();
                }
                if (wasNull && ends != null) {
                    // non-null ends are mutated in-place
                    ((EntityMetaDataImpl) emd).setAssociationEnds(ends);
                }
            }

            for (final EntityMetaData emd : entityMetaDatas) {
                // add subtype
                final String superType = emd.getSuperType();
                if (superType != null) {
                    addSubTypeToMetaData(result, emd, superType);
                }
                // add interface types
                for (String iFaceType : emd.getInterfaceTypes()) {
                    addSubTypeToMetaData(result, emd, iFaceType);
                }

                // set supertypes
                List<String> thisAndSuperTypes = new ArrayList<>();
                EntityMetaData data = emd;
                String t = data.getType();
                do {
                    thisAndSuperTypes.add(t);
                    thisAndSuperTypes.addAll(data.getInterfaceTypes());
                    data = result.get(t);
                    t = data.getSuperType();
                } while (t != null);
                ((EntityMetaDataImpl) emd).setThisAndSuperTypes(thisAndSuperTypes);
            }
            return result;
        }
    }