Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.heliorm.mojo.Output Maven / Gradle / Ivy
package com.heliorm.mojo;
import com.heliorm.Database;
import com.heliorm.Field;
import com.heliorm.Index;
import com.heliorm.Table;
import com.heliorm.def.*;
import com.heliorm.impl.FieldBuilder;
import com.heliorm.impl.IndexPart;
import com.heliorm.impl.TableBuilder;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import static java.lang.String.format;
/**
* @author gideon
*/
class Output {
private final GenerateModel gen;
private final Database database;
private final String packageName;
private final Map, Set>> tables = new HashMap<>();
private final StringBuilder buf = new StringBuilder();
private final Set imports = new HashSet<>();
private int depth;
private PrintWriter out;
Output(GenerateModel gen, Database database, String packageName) {
this.packageName = packageName;
this.database = database;
this.gen = gen;
}
void addTable(Table> table) {
tables.put(table, table.getSubTables());
}
void output(String directory) throws GeneratorException, OrmMetaDataException {
String databaseClass = gen.getDatabaseClassFor(database);
String packageName = databaseClass.substring(0, databaseClass.lastIndexOf('.'));
String path = directory + "/" + packageName.replace(".", "/");
File pathFile = new File(path);
if (!pathFile.exists()) {
pathFile.mkdirs();
}
String fileName = path + "/Tables.java";
try {
for (Table> table : tables.keySet()) {
push();
emit(table);
pop();
emit("");
}
out = new PrintWriter(new FileWriter(fileName));
impt(Database.class.getCanonicalName());
impt(Table.class.getCanonicalName());
out.printf("package %s;\n", packageName);
out.println("");
for (String imp : imports.stream().sorted().toList()) {
out.printf("import %s;\n", imp);
}
out.println("");
out.println("public final class Tables implements Database {");
out.println("");
out.println("");
out.print(buf);
out.println("");
StringJoiner sj = new StringJoiner(", ");
for (Table> table : tables.keySet()) {
sj.add(shortFieldName(table));
}
out.println("\t@Override");
out.println("\tpublic final List> getTables() {");
out.printf("\t\treturn Arrays.asList(%s);", sj);
out.println("\n\t}");
out.println("");
out.println("\t@Override");
out.println("\tpublic final String getSqlDatabase() {");
out.printf("\t\treturn \"%s\";", database.getSqlDatabase());
out.println("\n\t}");
out.println("");
out.printf("\tpublic final static Tables %s = new Tables();\n", shortDatabaseName());
for (Table> table : tables.keySet()) {
out.printf("\tpublic final static %s %s = new %s();\n", tableName(table), shortFieldName(table), tableName(table));
}
out.println("\n}");
} catch (IOException ex) {
throw new GeneratorException(format("Error opening output file '%s' (%s)", fileName, ex.getMessage()), ex);
} finally {
if (out != null) {
out.close();
}
}
}
private void push() {
depth++;
}
private void pop() {
depth--;
}
private void emit(String fmt, Object... args) {
buf.append(String.join("",Collections.nCopies(depth*4," ")));
buf.append(format(fmt, args));
if (!fmt.endsWith("\n")) {
buf.append("\n");
}
}
private void impts(String name) {
if (!name.startsWith(packageName)) {
imports.add("static " + name);
}
}
private void impt(String name) {
imports.add(name);
}
private void impt(Class> clazz) {
if (!clazz.getPackage().getName().equals(packageName) && (!clazz.isEnum() || (clazz.getEnclosingClass() == null))) {
imports.add(clazz.getCanonicalName());
}
}
private void emit(Table cm) {
impt(cm.getObjectClass());
emit("public static class %s implements Table<%s> {",
tableName(cm), getJavaName(cm));
emit("");
push();
emit("private %s() {", tableName(cm));
emit("}");
emit("");
StringJoiner fieldNames = new StringJoiner(",");
impt(TableBuilder.class);
impt(FieldBuilder.class);
emit("private transient TableBuilder<%s,%s> builder = TableBuilder.create(this);", tableName(cm), getJavaName(cm));
emit("");
for (Field, ?> fm : cm.getFields()) {
addFieldModel(cm, fm);
fieldNames.add(fm.getJavaName());
}
// getFields();
impt(List.class);
impt(Field.class);
impt(Arrays.class);
emit("");
emit("@Override");
emit("public List> getFields() {", getJavaName(cm));
push();
emit(format("return Arrays.asList(%s);", fieldNames));
pop();
emit("}");
// getPrimaryKey();
impt(Optional.class);
emit("");
emit("@Override");
emit("public Optional> getPrimaryKey() {", getJavaName(cm));
push();
Optional> opt = cm.getPrimaryKey();
if (opt.isPresent()) {
emit("return Optional.of(%s);", opt.get().getJavaName());
} else {
emit("return Optional.empty();");
}
pop();
emit("}");
// getSqlTable();
emit("");
emit("@Override");
emit("public String getSqlTable() {");
push();
emit("return \"%s\";", cm.getSqlTable());
pop();
emit("}");
// getObjectClass();
emit("");
emit("@Override");
emit("public Class<%s> getObjectClass() {", getJavaName(cm));
push();
emit("return %s.class;", getJavaName(cm));
pop();
emit("}");
// getSubTables();
emit("");
emit("@Override");
emit("public Set> getSubTables() {", getJavaName(cm));
push();
Set> subs = tables.get(cm);
impt(List.class);
impt(Set.class);
if (subs.isEmpty()) {
impt(Collections.class);
emit("return Collections.EMPTY_SET;");
} else {
impt(Arrays.class);
impt(HashSet.class);
StringJoiner sj = new StringJoiner(",");
Set> all = explodeSubs(subs);
for (Table> sub : all) {
impts(fullFieldName(sub));
sj.add(shortFieldName(sub));
}
emit("return new HashSet(Arrays.asList(%s));", sj.toString());
}
pop();
emit("}");
pop();
// getDatabase()
push();
emit("");
emit("@Override");
emit("public Database getDatabase() {");
push();
emit("return %s;", shortDatabaseName());
pop();
emit("}");
pop();
// isAbstract()
push();
emit("");
emit("@Override");
emit("public boolean isAbstract() {");
push();
emit("return %b;", cm.isAbstract());
pop();
emit("}");
// isRecord()
push();
emit("");
emit("@Override");
emit("public boolean isRecord() {");
push();
emit("return %b;", cm.isRecord());
pop();
emit("}");
// getIndexes()
StringJoiner indexNames = new StringJoiner(",");
for (Index> im : cm.getIndexes()) {
String idxName = addIndexModel(im);
indexNames.add(idxName);
}
impt(Index.class);
emit("");
emit("@Override");
emit("public List> getIndexes() {", getJavaName(cm));
push();
emit(format("return Arrays.asList(%s);", indexNames));
pop();
emit("}");
pop();
emit("");
emit("}");
emit("");
pop();
}
private Set> explodeSubs(Set> subs) {
Set> res = new HashSet<>(subs);
for (Table> sub : subs) {
res.addAll(explodeSubs(sub.getSubTables()));
}
return res;
}
private void addFieldModel(Table> cm, Field, ?> fm) {
switch (fm.getFieldType()) {
case BYTE -> addByteField(cm, fm);
case SHORT -> addShortField(cm, fm);
case INTEGER -> addIntegerField(cm, fm);
case LONG -> addLongField(cm, fm);
case FLOAT -> addFloatField(cm, fm);
case DOUBLE -> addDoubleField(cm, fm);
case BOOLEAN -> addBooleanField(cm, fm);
case DATE -> addDateField(cm, fm);
case INSTANT -> addInstantField(cm, fm);
case LOCAL_DATE_TIME -> addLocalDateTimeField(cm, fm);
case STRING -> addStringField(cm, fm);
case ENUM -> addEnumField(cm, fm);
case BYTE_ARRAY -> addByteArrayField(cm,fm);
}
}
private void addLongField(Table> cm, Field, ?> fm) {
addField(cm, fm, LongField.class, "longField");
}
private void addIntegerField(Table> cm, Field, ?> fm) {
addField(cm, fm, IntegerField.class, "integerField");
}
private void addShortField(Table> cm, Field, ?> fm) {
addField(cm, fm, ShortField.class, "shortField");
}
private void addByteField(Table> cm, Field, ?> fm) {
addField(cm, fm, ByteField.class, "byteField");
}
private void addDoubleField(Table> cm, Field, ?> fm) {
addField(cm, fm, DoubleField.class, "doubleField");
}
private void addFloatField(Table> cm, Field, ?> fm) {
addField(cm, fm, FloatField.class, "floatField");
}
private void addBooleanField(Table> cm, Field, ?> fm) {
addField(cm, fm, BooleanField.class, "booleanField");
}
private void addEnumField(Table> cm, Field, ?> fm) {
impt(EnumField.class);
String enumTypeName;
if (fm.getJavaType().getEnclosingClass() == null) {
enumTypeName = fm.getJavaType().getCanonicalName();
} else {
enumTypeName = format("%s.%s", cm.getObjectClass().getSimpleName(), fm.getJavaType().getSimpleName());
}
emit("public final %s<%s, %s> %s = builder.enumField(\"%s\", %s.class)",
EnumField.class.getSimpleName(),
cm.getObjectClass().getSimpleName(),
enumTypeName,
fm.getJavaName(),
fm.getJavaName(),
enumTypeName);
completeField(fm);
}
private void addByteArrayField(Table> cm, Field,?> fm) {
impt(ByteArrayField.class);
emit("public final %s<%s> %s = builder.byteArrayField(\"%s\")",
ByteArrayField.class.getSimpleName(),
cm.getObjectClass().getSimpleName(),
fm.getJavaName(),
fm.getJavaName());
completeField(fm);
}
private void addDateField(Table> cm, Field, ?> fm) {
addField(cm, fm, DateField.class, "dateField");
}
private void addInstantField(Table> cm, Field, ?> fm) {
addField(cm, fm, InstantField.class, "instantField");
}
private void addLocalDateTimeField(Table> cm, Field, ?> fm) {
addField(cm, fm, LocalDateTimeField.class, "localDateTimeField");
}
private void addStringField(Table> cm, Field, ?> fm) {
addField(cm, fm, StringField.class, "stringField");
}
private String addIndexModel(Index> im) {
impt(IndexPart.class);
StringJoiner sj = new StringJoiner(",");
for (Field, ?> field : im.getFields()) {
sj.add(field.getJavaName());
}
String indexName = indexName(im);
emit("private final %s %s = new %s(%s,Arrays.asList(%s));",
IndexPart.class.getSimpleName(),
indexName,
IndexPart.class.getSimpleName(),
im.isUnique(),
sj.toString());
return indexName;
}
private String indexName(Index> im) {
StringJoiner sj = new StringJoiner("_");
for (Field, ?> field : im.getFields()) {
sj.add(field.getJavaName());
}
sj.add("idx");
return sj.toString();
}
private void addField(Table> cm, Field, ?> fm, Class extends Field> fieldType, String buildMethod) {
impt(fieldType);
emit("public final %s<%s> %s = builder.%s(\"%s\")",
fieldType.getSimpleName(),
cm.getObjectClass().getSimpleName(),
fm.getJavaName(),
buildMethod,
fm.getJavaName());
completeField(fm);
}
private void completeField(Field, ?> fm) {
push();
emit(".withSqlName(\"%s\")", fm.getSqlName());
if (fm.getLength().isPresent()) {
emit(".withLength(%s)", fm.getLength().get());
}
emit(".withNullable(%b)", fm.isNullable());
emit(".withPrimaryKey(%b)", fm.isPrimaryKey());
emit(".withAutoNumber(%b)", fm.isAutoNumber());
emit(".withForeignKey(%b)", fm.isForeignKey());
if (fm.getForeignTable().isPresent()) {
emit(".withForeignTable(%s)", shortFieldName(fm.getForeignTable().get()));
}
emit(".build();");
pop();
}
private String tableName(Table> table) {
return table.getObjectClass().getSimpleName() + "Table";
}
private String getJavaName(Table> table) {
return table.getObjectClass().getSimpleName();
}
private String shortFieldName(Table> table) {
return getJavaName(table).toUpperCase();
}
private String fullFieldName(Table> table) {
return gen.getTablesPackageFor(table) + ".Tables." + shortFieldName(table);
}
private String shortDatabaseName() {
return database.getSqlDatabase().toUpperCase();
}
@Override
public String toString() {
return "Output{" + "packageName=" + packageName + '}';
}
}