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

com.heliorm.mojo.Modeller Maven / Gradle / Ivy

There is a newer version: 0.99.107
Show newest version
package com.heliorm.mojo;

import com.heliorm.Table;

import java.util.*;
import java.util.stream.Collectors;

import static java.lang.String.format;

/**
 * @author gideon
 */
class Modeller> {

    private final Generator gen;
    private Map classPackageMap;
    private Map packageDatabases;

    Modeller(Generator gen, Set topLevelPackages) throws GeneratorException {
        this.gen = gen;
        generate(topLevelPackages);
    }

    Map getPackageDatabases() {
        return packageDatabases;
    }

    PackageDatabase getPackageDatabase(String className) {
        return packageDatabases.get(classPackageMap.get(className));
    }

    private void generate(Set topLevelPackages) throws GeneratorException {
        Set> allPojoClasses = gen.getAllPojoClasses();
        classPackageMap = makeDatabaseMap(topLevelPackages, allPojoClasses);
        Set uniquePackages = new HashSet<>(classPackageMap.values());
        packageDatabases = makeDatabases(uniquePackages);
        List roots = buildTree(allPojoClasses);
        for (Entry entry : roots) {
            generate(entry);
        }
    }

    private T generate(Entry entry) {
        Set subTables = entry.kids.stream()
                .map(this::generate).collect(Collectors.toSet());
        Class pojoClass = entry.clazz;
        PackageDatabase db = packageDatabases.get(classPackageMap.get(pojoClass.getCanonicalName()));
        T table = gen.getPojoModel(pojoClass, db, subTables);
        db.addTable(table);
        return table;
    }

    private List buildTree(Set> classes) {
        Map classMap = classes.stream()
                .collect(Collectors.toMap(Class::getName, Entry::new));
        return buildTree(classMap);
    }

    private List buildTree(Map entryMap) {
        List root = new ArrayList<>();
        for (String name : entryMap.keySet()) {
            Entry entry = entryMap.get(name);
            Class superClass = entry.clazz.getSuperclass();
            String parentName = superClass.getName();
            if (entryMap.containsKey(parentName)) {
                Entry parentEntry = entryMap.get(parentName);
                parentEntry.add(entry);
            } else {
                root.add(entry);
            }
        }
        return root;
    }

    private Map makeDatabaseMap(Set topLevelPackages, Set> allPojoClasses) throws GeneratorException {
        Map map = new HashMap<>();
        for (Class clazz : allPojoClasses) {
            for (String tlp : topLevelPackages) {
                String name = clazz.getCanonicalName();
                if (name.startsWith(tlp)) {
                    if (map.containsKey(name)) {
                        throw new GeneratorException(format("Class '%s' matches more than one top level package (%s and %s)",
                                name,
                                tlp,
                                map.get(name)));
                    }
                    map.put(name, tlp);
                    break;
                }
            }
        }
        return map;
    }

    private Map makeDatabases(Set packages) {
        return packages.stream()
                .collect(Collectors.toMap(pkg -> pkg, PackageDatabase::new));
    }

    private static class Entry {

        private final Class clazz;
        private final List kids = new ArrayList<>();

        Entry(Class clazz) {
            this.clazz = clazz;
        }


        void add(Entry child) {
            kids.add(child);
        }

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy