added option to modelbuilder from context initialization

This commit is contained in:
wea_ondara
2022-09-08 16:54:32 +02:00
parent 6a1585f438
commit ad29897cd8
4 changed files with 89 additions and 18 deletions

View File

@@ -0,0 +1,13 @@
package jef.model;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@Builder
@NoArgsConstructor
public class DbContextOptions {
}

View File

@@ -13,6 +13,7 @@ import jef.model.constraints.PrimaryKeyConstraint;
import jef.model.constraints.UniqueKeyConstraint; import jef.model.constraints.UniqueKeyConstraint;
import jef.serializable.SerializableObject; import jef.serializable.SerializableObject;
import jef.util.Check; import jef.util.Check;
import jef.util.Util;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@@ -21,44 +22,61 @@ import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class ModelBuilder { public class ModelBuilder {
private static final List<AnnotationProcessor> annotationProcessors = new ArrayList<>();
static {//TODO move this to a passable config class
annotationProcessors.add(NotNullProcessor.INSTANCE);
annotationProcessors.add(UniqueProcessor.INSTANCE);
annotationProcessors.add(IndexProcessor.INSTANCE);
annotationProcessors.add(KeyProcessor.INSTANCE);
annotationProcessors.add(ForeignKeyProcessor.INSTANCE);
}
/** /**
* Initializes a ModelBuilder and configures the entities found in the context Class according to annotations. * Initializes a ModelBuilder and configures the entities found in the context Class according to annotations.
* *
* @param context the context to use for initialization * @param context the context to use for initialization
* @return an initialized ModelBuilder * @return an initialized ModelBuilder
*/ */
public static ModelBuilder from(Class<? extends DbContext> context) { //TODO pass optional config here public static ModelBuilder from(Class<? extends DbContext> context) {
return from(context, new ModelBuilderOptions());
}
/**
* Initializes a ModelBuilder and configures the entities found in the context Class according to annotations.
*
* @param context the context to use for initialization
* @param options the options to user during initialization
* @return an initialized ModelBuilder
*/
public static ModelBuilder from(Class<? extends DbContext> context, ModelBuilderOptions options) {
try { try {
return from0(context); return from0(context, options);
} catch (Exception e) { } catch (Throwable e) {
throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e); throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
} }
} }
private static ModelBuilder from0(Class<? extends DbContext> context) throws Exception { private static ModelBuilder from0(Class<? extends DbContext> context, ModelBuilderOptions options) throws Throwable {
var mb = new ModelBuilder(new ArrayList<>()); var mb = new ModelBuilder(new ArrayList<>());
EntityInitializer.initEntities(mb, context); EntityInitializer.initEntities(mb, context);
PrimaryKeyInitializer.initPrimaryKeys(mb); PrimaryKeyInitializer.initPrimaryKeys(mb);
ForeignKeyExposeInitializer.initForeignKeyExposures(mb); ForeignKeyExposeInitializer.initForeignKeyExposures(mb);
ForeignKeyInitializer.initForeignKeys(mb); ForeignKeyInitializer.initForeignKeys(mb);
for (AnnotationProcessor processor : annotationProcessors) { for (AnnotationProcessor processor : options.getAnnotationProcessors()) {
processor.apply(mb); processor.apply(mb);
} }
var instance = context.getDeclaredConstructor().newInstance();//TODO find constructor, //TODO optionally with config Util.ThrowableFunction<DbContextOptions, DbContext> init;
instance.onModelCreate(mb); try {
instance.onModelValidate(mb); var ctor = context.getDeclaredConstructor(DbContextOptions.class);
init = ctor::newInstance;
} catch (NoSuchMethodException e) {
try {
var ctor = context.getDeclaredConstructor();
init = o -> ctor.newInstance();
} catch (NoSuchMethodException e2) {
throw new RuntimeException(e);
}
}
try {
DbContext instance = init.apply(options.getContextOptions());
instance.onModelCreate(mb);
instance.onModelValidate(mb);
} catch (Throwable e) {
throw new RuntimeException(e);
}
return mb; return mb;
} }

View File

@@ -0,0 +1,35 @@
package jef.model;
import jef.model.annotations.processors.AnnotationProcessor;
import jef.model.annotations.processors.ForeignKeyProcessor;
import jef.model.annotations.processors.IndexProcessor;
import jef.model.annotations.processors.KeyProcessor;
import jef.model.annotations.processors.NotNullProcessor;
import jef.model.annotations.processors.UniqueProcessor;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter
@Builder
@AllArgsConstructor
public class ModelBuilderOptions {
private List<AnnotationProcessor> annotationProcessors;
private DbContextOptions contextOptions;
public ModelBuilderOptions() {
this.annotationProcessors = new ArrayList<>(List.of(
NotNullProcessor.INSTANCE,
UniqueProcessor.INSTANCE,
IndexProcessor.INSTANCE,
KeyProcessor.INSTANCE,
ForeignKeyProcessor.INSTANCE
));
this.contextOptions = new DbContextOptions();
}
}

View File

@@ -15,4 +15,9 @@ public abstract class Util {
public interface ThrowableSupplier<T> { public interface ThrowableSupplier<T> {
T get() throws Throwable; T get() throws Throwable;
} }
@FunctionalInterface
public interface ThrowableFunction<T, R> {
R apply(T t) throws Throwable;
}
} }