
com.heliorm.mojo.Modeller Maven / Gradle / Ivy
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