diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 4af1905cd33..009c9a753e7 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -182,7 +182,7 @@ The `pull-request.yml` workflow runs on every PR and is the gating check:
| Error | Cause | Fix |
|-------|-------|-----|
| `Cannot connect to MongoDB` in tests | Docker not running / Testcontainers can't pull image | Start Docker daemon; or use `-Dmongodb=local` with a local `mongod` |
-| `No MorphiaConfig found` | Missing `morphia-config.properties` on classpath | Add the file to `src/test/resources/`, or call `Morphia.createDatastore(client, new ManualMorphiaConfig())` |
+| `No MorphiaConfig found` | Missing `morphia-config.properties` on classpath | Add the file to `src/test/resources/`, or call `Morphia.createDatastore(client, dev.morphia.config.MorphiaConfig.load())` |
| `MappingException: No usable constructor` | Entity class has no no-arg constructor accessible to Morphia | Add a `protected` or `public` no-arg constructor |
| `ClassCastException` with proxies | Lazy-loading proxy and `instanceof` check clash | Check `MorphiaInternals.proxyClassesPresent()` before using proxies, or disable lazy loading |
| Tests skipped with `SkipException` | MongoDB version below minimum for a feature | Pass a higher `-Dmongodb=` version |
diff --git a/core/pom.xml b/core/pom.xml
index 9f1e5686365..7f29488f2ff 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -128,6 +128,13 @@
generate-test-resources
+
+ morphia-annotations-asm
+
+ morphia-annotation-node
+
+ generate-sources
+
@@ -171,6 +178,27 @@
net.bytebuddy
byte-buddy
+
+ io.quarkus.gizmo
+ gizmo
+ 1.9.0
+ true
+
+
+ org.ow2.asm
+ asm-tree
+ true
+
+
+ org.ow2.asm
+ asm-util
+ true
+
+
+ org.jboss.forge.roaster
+ roaster-jdt
+ true
+
org.slf4j
slf4j-api
@@ -180,6 +208,12 @@
spotbugs-annotations
+
+ org.jboss.windup.decompiler
+ decompiler-fernflower
+ 6.3.9.Final
+ test
+
org.testng
testng
diff --git a/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java b/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java
index edda8f41469..c791eb271f8 100644
--- a/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java
+++ b/core/src/main/java/dev/morphia/config/ManualMorphiaConfig.java
@@ -17,7 +17,9 @@
import org.bson.codecs.configuration.CodecProvider;
+import static dev.morphia.config.MorphiaConfigHelper.dumpConfigurationFile;
import static dev.morphia.mapping.DateStorage.UTC;
+import static dev.morphia.mapping.DiscriminatorFunction.className;
import static dev.morphia.mapping.DiscriminatorFunction.simpleName;
import static dev.morphia.mapping.NamingStrategy.camelCase;
import static dev.morphia.mapping.NamingStrategy.identity;
@@ -32,40 +34,40 @@
@MorphiaInternal
@SuppressWarnings("removal")
public class ManualMorphiaConfig implements MorphiaConfig {
- Boolean applyCaps;
- Boolean applyDocumentValidations;
- Boolean applyIndexes;
-
- Optional codecProvider;
-
- NamingStrategy collectionNaming;
-
- String database;
-
- DateStorage dateStorage;
- DiscriminatorFunction discriminator;
- String discriminatorKey;
- Boolean enablePolymorphicQueries;
- Boolean ignoreFinals;
- MapperType mapper;
- List packages;
- PropertyDiscovery propertyDiscovery;
- List> propertyAnnotationProviders;
- NamingStrategy propertyNaming;
- QueryFactory queryFactory;
- Boolean storeEmpties;
- Boolean storeNulls;
+ private Boolean applyCaps;
+ private Boolean applyDocumentValidations;
+ private Boolean applyIndexes;
+
+ private Optional codecProvider;
+
+ private NamingStrategy collectionNaming;
+
+ private String database;
+
+ private DateStorage dateStorage;
+ private DiscriminatorFunction discriminator;
+ private String discriminatorKey;
+ private Boolean enablePolymorphicQueries;
+ private Boolean ignoreFinals;
+ private MapperType mapper;
+ private List packages;
+ private PropertyDiscovery propertyDiscovery;
+ private List> propertyAnnotationProviders;
+ private NamingStrategy propertyNaming;
+ private QueryFactory queryFactory;
+ private Boolean storeEmpties;
+ private Boolean storeNulls;
/**
* @hidden
*/
- public ManualMorphiaConfig() {
+ protected ManualMorphiaConfig() {
}
/**
* @hidden
*/
- public ManualMorphiaConfig(MorphiaConfig base) {
+ protected ManualMorphiaConfig(MorphiaConfig base) {
applyCaps = base.applyCaps();
applyDocumentValidations = base.applyDocumentValidations();
applyIndexes = base.applyIndexes();
@@ -122,90 +124,243 @@ public Boolean applyCaps() {
return orDefault(applyCaps, FALSE);
}
+ @Override
+ public MorphiaConfig applyCaps(Boolean value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.applyCaps = value;
+ return newConfig;
+ }
+
+ @Override
public Boolean applyDocumentValidations() {
return orDefault(applyDocumentValidations, FALSE);
}
+ @Override
+ public MorphiaConfig applyDocumentValidations(Boolean value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.applyDocumentValidations = value;
+ return newConfig;
+ }
+
@Override
public Boolean applyIndexes() {
return orDefault(applyIndexes, FALSE);
}
+ @Override
+ public MorphiaConfig applyIndexes(Boolean value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.applyIndexes = value;
+ return newConfig;
+ }
+
@Override
public Optional codecProvider() {
return orDefault(codecProvider, Optional.empty());
}
+ @Override
+ public MorphiaConfig codecProvider(CodecProvider value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.codecProvider = Optional.of(value);
+ return newConfig;
+ }
+
@Override
public NamingStrategy collectionNaming() {
return orDefault(collectionNaming, camelCase());
}
+ @Override
+ public MorphiaConfig collectionNaming(NamingStrategy value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.collectionNaming = value;
+ return newConfig;
+ }
+
+ @Override
+ public MorphiaConfig database(String value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.database = value;
+ return newConfig;
+ }
+
@Override
public DateStorage dateStorage() {
return orDefault(dateStorage, UTC);
}
+ @Override
+ public MorphiaConfig dateStorage(DateStorage value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.dateStorage = value;
+ return newConfig;
+ }
+
@Override
public DiscriminatorFunction discriminator() {
return orDefault(discriminator, simpleName());
}
+ @Override
+ public MorphiaConfig discriminator(DiscriminatorFunction value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.discriminator = value;
+ return newConfig;
+ }
+
@Override
public String discriminatorKey() {
return orDefault(discriminatorKey, "_t");
}
+ @Override
+ public MorphiaConfig discriminatorKey(String value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.discriminatorKey = value;
+ return newConfig;
+ }
+
@Override
public Boolean enablePolymorphicQueries() {
return orDefault(enablePolymorphicQueries, FALSE);
}
+ @Override
+ public MorphiaConfig enablePolymorphicQueries(Boolean value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.enablePolymorphicQueries = value;
+ return newConfig;
+ }
+
@Override
public Boolean ignoreFinals() {
return orDefault(ignoreFinals, FALSE);
}
+ @Override
+ public MorphiaConfig ignoreFinals(Boolean value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.ignoreFinals = value;
+ return newConfig;
+ }
+
+ @Override
+ public MorphiaConfig legacy() {
+ ManualMorphiaConfig newConfig = new ManualMorphiaConfig(this);
+ newConfig.dateStorage = DateStorage.SYSTEM_DEFAULT;
+ newConfig.discriminatorKey = "className";
+ newConfig.discriminator = className();
+ newConfig.collectionNaming = identity();
+ newConfig.propertyNaming = identity();
+ return newConfig;
+ }
+
@Override
public MapperType mapper() {
return orDefault(mapper, MapperType.LEGACY);
}
+ @Override
+ public MorphiaConfig mapper(MapperType value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.mapper = value;
+ return newConfig;
+ }
+
@Override
public List packages() {
return orDefault(packages, List.of());
}
+ @Override
+ public MorphiaConfig packages(List value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.packages = value;
+ return newConfig;
+ }
+
@Override
public List> propertyAnnotationProviders() {
return orDefault(propertyAnnotationProviders, List.of(new MorphiaPropertyAnnotationProvider()));
}
+ @Override
+ public MorphiaConfig propertyAnnotationProviders(List> list) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.propertyAnnotationProviders = list;
+ if (list.isEmpty() || list.stream().noneMatch(p -> p instanceof MorphiaPropertyAnnotationProvider)) {
+ newConfig.propertyAnnotationProviders.add(new MorphiaPropertyAnnotationProvider());
+ }
+ return newConfig;
+ }
+
@Override
public PropertyDiscovery propertyDiscovery() {
return orDefault(propertyDiscovery, FIELDS);
}
+ @Override
+ public MorphiaConfig propertyDiscovery(PropertyDiscovery value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.propertyDiscovery = value;
+ return newConfig;
+ }
+
@Override
public NamingStrategy propertyNaming() {
return orDefault(propertyNaming, identity());
}
+ @Override
+ public MorphiaConfig propertyNaming(NamingStrategy value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.propertyNaming = value;
+ return newConfig;
+ }
+
@Override
public QueryFactory queryFactory() {
return orDefault(queryFactory, new DefaultQueryFactory());
}
+ @Override
+ public MorphiaConfig queryFactory(QueryFactory value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.queryFactory = value;
+ return newConfig;
+ }
+
@Override
public Boolean storeEmpties() {
return orDefault(storeEmpties, FALSE);
}
+ @Override
+ public MorphiaConfig storeEmpties(Boolean value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.storeEmpties = value;
+ return newConfig;
+ }
+
@Override
public Boolean storeNulls() {
return orDefault(storeNulls, FALSE);
}
+ @Override
+ public MorphiaConfig storeNulls(Boolean value) {
+ var newConfig = new ManualMorphiaConfig(this);
+ newConfig.storeNulls = value;
+ return newConfig;
+ }
+
+ @Override
+ public String toConfigFormat(boolean showComplete) {
+ return dumpConfigurationFile(this, showComplete);
+ }
+
protected T orDefault(@Nullable T localValue, T defaultValue) {
return localValue != null ? localValue : defaultValue;
}
diff --git a/core/src/main/java/dev/morphia/config/MorphiaConfig.java b/core/src/main/java/dev/morphia/config/MorphiaConfig.java
index c079dc40723..ce497040d11 100644
--- a/core/src/main/java/dev/morphia/config/MorphiaConfig.java
+++ b/core/src/main/java/dev/morphia/config/MorphiaConfig.java
@@ -30,9 +30,6 @@
import io.smallrye.config.WithConverter;
import io.smallrye.config.WithDefault;
-import static dev.morphia.config.MorphiaConfigHelper.dumpConfigurationFile;
-import static dev.morphia.mapping.DiscriminatorFunction.className;
-import static dev.morphia.mapping.NamingStrategy.identity;
import static io.smallrye.config.PropertiesConfigSourceLoader.*;
import static java.lang.Thread.currentThread;
@@ -50,7 +47,7 @@ public interface MorphiaConfig {
/**
* Tries to load a configuration from the default location.
- *
+ *
* @return the loaded config
*/
static MorphiaConfig load() {
@@ -87,12 +84,7 @@ static MorphiaConfig load(String location) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig collectionNaming(NamingStrategy value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.collectionNaming = value;
- return newConfig;
- }
+ MorphiaConfig collectionNaming(NamingStrategy value);
/**
* The database name that Morphia should use. This entry is required to be present and is the only necessary configuration element
@@ -118,12 +110,7 @@ default MorphiaConfig collectionNaming(NamingStrategy value) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig applyCaps(Boolean value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.applyCaps = value;
- return newConfig;
- }
+ MorphiaConfig applyCaps(Boolean value);
/**
* If true, document validations will be enabled for entities/collections with validation mappings.
@@ -142,12 +129,7 @@ default MorphiaConfig applyCaps(Boolean value) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig applyDocumentValidations(Boolean value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.applyDocumentValidations = value;
- return newConfig;
- }
+ MorphiaConfig applyDocumentValidations(Boolean value);
/**
* If true, mapped indexes will be applied to the database at start up.
@@ -164,12 +146,7 @@ default MorphiaConfig applyDocumentValidations(Boolean value) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig applyIndexes(Boolean value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.applyIndexes = value;
- return newConfig;
- }
+ MorphiaConfig applyIndexes(Boolean value);
/**
* Specifies a {@code CodecProvider} to supply user defined codecs that Morphia should use.
@@ -188,12 +165,7 @@ default MorphiaConfig applyIndexes(Boolean value) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig codecProvider(CodecProvider value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.codecProvider = Optional.of(value);
- return newConfig;
- }
+ MorphiaConfig codecProvider(CodecProvider value);
/**
* Sets the naming strategy to be used when generating collection names for entities if name is not explicitly given in the {@code
@@ -217,12 +189,7 @@ default MorphiaConfig codecProvider(CodecProvider value) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig database(String value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.database = value;
- return newConfig;
- }
+ MorphiaConfig database(String value);
/**
* The date storage configuration Morphia should use for JSR 310 types.
@@ -239,12 +206,7 @@ default MorphiaConfig database(String value) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig dateStorage(DateStorage value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.dateStorage = value;
- return newConfig;
- }
+ MorphiaConfig dateStorage(DateStorage value);
/**
* The function to use when calculating the discriminator value for an entity
@@ -264,12 +226,7 @@ default MorphiaConfig dateStorage(DateStorage value) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig discriminator(DiscriminatorFunction value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.discriminator = value;
- return newConfig;
- }
+ MorphiaConfig discriminator(DiscriminatorFunction value);
/**
* The document field name to use when storing discriminator values
@@ -286,12 +243,7 @@ default MorphiaConfig discriminator(DiscriminatorFunction value) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig discriminatorKey(String value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.discriminatorKey = value;
- return newConfig;
- }
+ MorphiaConfig discriminatorKey(String value);
/**
* Enable polymorphic queries. By default, Morphia will only query for the given type. However, in cases where subtypes are stored
@@ -309,12 +261,7 @@ default MorphiaConfig discriminatorKey(String value) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig enablePolymorphicQueries(Boolean value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.enablePolymorphicQueries = value;
- return newConfig;
- }
+ MorphiaConfig enablePolymorphicQueries(Boolean value);
/**
* Instructs Morphia to ignore final fields.
@@ -331,32 +278,17 @@ default MorphiaConfig enablePolymorphicQueries(Boolean value) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig ignoreFinals(Boolean value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.ignoreFinals = value;
- return newConfig;
- }
+ MorphiaConfig ignoreFinals(Boolean value);
/**
* Creates a new configuration based on the current one but updated to reflect the legacy configuration. This configuration is not
* changed.
- *
+ *
* @return the update configuration
*
* @since 3.0
*/
- default MorphiaConfig legacy() {
- ManualMorphiaConfig newConfig = new ManualMorphiaConfig(this);
- newConfig.dateStorage = DateStorage.SYSTEM_DEFAULT;
- newConfig.discriminatorKey = "className";
- newConfig.discriminator = className();
- newConfig.collectionNaming = identity();
- newConfig.propertyNaming = identity();
-
- return newConfig;
-
- }
+ MorphiaConfig legacy();
/**
* The mapper implementation to use. Defaults to {@link MapperType#LEGACY} (reflection-based).
@@ -375,12 +307,7 @@ default MorphiaConfig legacy() {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig mapper(MapperType value) {
- var newConfig = new ManualMorphiaConfig(this);
-
- newConfig.mapper = value;
- return newConfig;
- }
+ MorphiaConfig mapper(MapperType value);
/**
* A comma delimited list of packages that Morphia should map. If subpackages of a specific package should also be mapped, simply add
@@ -398,12 +325,7 @@ default MorphiaConfig mapper(MapperType value) {
* @return a new instance with the updated configuration
* @since 3.0
*/
- default MorphiaConfig packages(List value) {
- var newConfig = new ManualMorphiaConfig(this);
- newConfig.packages = value;
-
- return newConfig;
- }
+ MorphiaConfig packages(List value);
/**
* Specifies the providers of any external annotations to use as markers for properties for Morphia to consider while mapping. This
@@ -440,14 +362,7 @@ default MorphiaConfig packages(List value) {
*/
@MorphiaInternal
@MorphiaExperimental
- default MorphiaConfig propertyAnnotationProviders(List> list) {
- var newConfig = new ManualMorphiaConfig(this);
- newConfig.propertyAnnotationProviders = list;
- if (list.isEmpty() || list.stream().noneMatch(p -> p instanceof MorphiaPropertyAnnotationProvider)) {
- newConfig.propertyAnnotationProviders.add(new MorphiaPropertyAnnotationProvider());
- }
- return newConfig;
- }
+ MorphiaConfig propertyAnnotationProviders(List> list);
/**
* Determines how properties are discovered. The traditional value is by scanning for fields which involves a bit more reflective
@@ -468,12 +383,7 @@ default MorphiaConfig propertyAnnotationProviders(List, Object> providerMap;
+ private final Mapper mapper;
private final CritterClassLoader classLoader;
private final boolean runtimeMode;
public PropertyFinder(Mapper mapper, CritterClassLoader classLoader, boolean runtimeMode) {
+ this.mapper = mapper;
this.providerMap = new LinkedHashMap<>();
for (var provider : mapper.getConfig().propertyAnnotationProviders()) {
providerMap.put(provider.provides(), provider);
@@ -34,33 +37,33 @@ public PropertyFinder(Mapper mapper, CritterClassLoader classLoader, boolean run
this.runtimeMode = runtimeMode;
}
- public List find(Class> entityType, ClassNode classNode) {
+ public List find(Class> entityType, ClassNode classNode, MorphiaConfig config) {
List models = new ArrayList<>();
List methods = discoverPropertyMethods(classNode);
if (methods.isEmpty()) {
List fields = discoverAllFields(entityType, classNode);
if (!runtimeMode) {
- classLoader.register(entityType.getName(), CritterGizmoGenerator.INSTANCE.fieldAccessors(entityType, fields));
+ classLoader.register(entityType.getName(), CritterGizmoGenerator.fieldAccessors(entityType, fields));
}
for (FieldNode field : fields) {
if (runtimeMode) {
- CritterGizmoGenerator.INSTANCE.varHandleAccessor(entityType, classLoader, field);
+ CritterGizmoGenerator.varHandleAccessor(entityType, classLoader, field);
} else {
- CritterGizmoGenerator.INSTANCE.propertyAccessor(entityType, classLoader, field);
+ CritterGizmoGenerator.propertyAccessor(entityType, classLoader, field);
}
- models.add(CritterGizmoGenerator.INSTANCE.propertyModelGenerator(entityType, classLoader, field));
+ models.add(CritterGizmoGenerator.propertyModelGenerator(config, entityType, classLoader, field));
}
} else {
if (!runtimeMode) {
- classLoader.register(entityType.getName(), CritterGizmoGenerator.INSTANCE.methodAccessors(entityType, methods));
+ classLoader.register(entityType.getName(), CritterGizmoGenerator.methodAccessors(entityType, methods));
}
for (MethodNode method : methods) {
if (runtimeMode) {
- CritterGizmoGenerator.INSTANCE.varHandleAccessor(entityType, classLoader, method);
+ CritterGizmoGenerator.varHandleAccessor(entityType, classLoader, method);
} else {
- CritterGizmoGenerator.INSTANCE.propertyAccessor(entityType, classLoader, method);
+ CritterGizmoGenerator.propertyAccessor(entityType, classLoader, method);
}
- models.add(CritterGizmoGenerator.INSTANCE.propertyModelGenerator(entityType, classLoader, method));
+ models.add(CritterGizmoGenerator.propertyModelGenerator(config, entityType, classLoader, method));
}
}
return models;
diff --git a/critter/core/src/main/java/dev/morphia/critter/parser/asm/AddFieldAccessorMethods.java b/core/src/main/java/dev/morphia/critter/parser/asm/AddFieldAccessorMethods.java
similarity index 100%
rename from critter/core/src/main/java/dev/morphia/critter/parser/asm/AddFieldAccessorMethods.java
rename to core/src/main/java/dev/morphia/critter/parser/asm/AddFieldAccessorMethods.java
diff --git a/critter/core/src/main/java/dev/morphia/critter/parser/asm/AddMethodAccessorMethods.java b/core/src/main/java/dev/morphia/critter/parser/asm/AddMethodAccessorMethods.java
similarity index 100%
rename from critter/core/src/main/java/dev/morphia/critter/parser/asm/AddMethodAccessorMethods.java
rename to core/src/main/java/dev/morphia/critter/parser/asm/AddMethodAccessorMethods.java
diff --git a/critter/core/src/main/java/dev/morphia/critter/parser/asm/BaseGenerator.java b/core/src/main/java/dev/morphia/critter/parser/asm/BaseGenerator.java
similarity index 100%
rename from critter/core/src/main/java/dev/morphia/critter/parser/asm/BaseGenerator.java
rename to core/src/main/java/dev/morphia/critter/parser/asm/BaseGenerator.java
diff --git a/critter/core/src/main/java/dev/morphia/critter/parser/gizmo/BaseGizmoGenerator.java b/core/src/main/java/dev/morphia/critter/parser/gizmo/BaseGizmoGenerator.java
similarity index 100%
rename from critter/core/src/main/java/dev/morphia/critter/parser/gizmo/BaseGizmoGenerator.java
rename to core/src/main/java/dev/morphia/critter/parser/gizmo/BaseGizmoGenerator.java
diff --git a/core/src/main/java/dev/morphia/critter/parser/gizmo/CritterGizmoGenerator.java b/core/src/main/java/dev/morphia/critter/parser/gizmo/CritterGizmoGenerator.java
new file mode 100644
index 00000000000..b76c1828f77
--- /dev/null
+++ b/core/src/main/java/dev/morphia/critter/parser/gizmo/CritterGizmoGenerator.java
@@ -0,0 +1,87 @@
+package dev.morphia.critter.parser.gizmo;
+
+import java.io.IOException;
+import java.util.List;
+
+import dev.morphia.config.MorphiaConfig;
+import dev.morphia.critter.CritterClassLoader;
+import dev.morphia.critter.parser.Generators;
+import dev.morphia.critter.parser.PropertyFinder;
+import dev.morphia.critter.parser.asm.AddFieldAccessorMethods;
+import dev.morphia.critter.parser.asm.AddMethodAccessorMethods;
+
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.FieldNode;
+import org.objectweb.asm.tree.MethodNode;
+
+public class CritterGizmoGenerator {
+ private CritterGizmoGenerator() {
+ }
+
+ public static GizmoEntityModelGenerator generate(Class> type, CritterClassLoader critterClassLoader,
+ Generators generators, boolean runtimeMode) {
+ ClassNode classNode = new ClassNode();
+ String resourceName = "%s.class".formatted(type.getName().replace('.', '/'));
+ try (java.io.InputStream inputStream = type.getClassLoader().getResourceAsStream(resourceName)) {
+ if (inputStream == null) {
+ throw new IllegalArgumentException("Could not find class file for %s".formatted(type.getName()));
+ }
+ new ClassReader(inputStream).accept(classNode, 0);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to read class %s".formatted(type.getName()), e);
+ }
+ PropertyFinder propertyFinder = new PropertyFinder(generators.getMapper(), critterClassLoader, runtimeMode);
+
+ return entityModel(type, critterClassLoader, classNode, propertyFinder.find(type, classNode, generators.getConfig()),
+ generators.getConfig());
+ }
+
+ public static GizmoEntityModelGenerator generate(Class> type, CritterClassLoader critterClassLoader,
+ Generators generators) {
+ return generate(type, critterClassLoader, generators, false);
+ }
+
+ public static byte[] fieldAccessors(Class> entityType, List fields) {
+ return new AddFieldAccessorMethods(entityType, fields).emit();
+ }
+
+ public static byte[] methodAccessors(Class> entityType, List methods) {
+ return new AddMethodAccessorMethods(entityType, methods).emit();
+ }
+
+ public static PropertyAccessorGenerator propertyAccessor(Class> entityType, CritterClassLoader critterClassLoader,
+ FieldNode field) {
+ return new PropertyAccessorGenerator(entityType, critterClassLoader, field).emit();
+ }
+
+ public static PropertyAccessorGenerator propertyAccessor(Class> entityType, CritterClassLoader critterClassLoader,
+ MethodNode method) {
+ return new PropertyAccessorGenerator(entityType, critterClassLoader, method).emit();
+ }
+
+ public static VarHandleAccessorGenerator varHandleAccessor(Class> entityType, CritterClassLoader critterClassLoader,
+ FieldNode field) {
+ return new VarHandleAccessorGenerator(entityType, critterClassLoader, field).emit();
+ }
+
+ public static VarHandleAccessorGenerator varHandleAccessor(Class> entityType, CritterClassLoader critterClassLoader,
+ MethodNode method) {
+ return new VarHandleAccessorGenerator(entityType, critterClassLoader, method).emit();
+ }
+
+ public static PropertyModelGenerator propertyModelGenerator(MorphiaConfig config, Class> entityType,
+ CritterClassLoader critterClassLoader, FieldNode field) {
+ return new PropertyModelGenerator(config, entityType, critterClassLoader, field).emit();
+ }
+
+ public static PropertyModelGenerator propertyModelGenerator(MorphiaConfig config, Class> entityType,
+ CritterClassLoader critterClassLoader, MethodNode method) {
+ return new PropertyModelGenerator(config, entityType, critterClassLoader, method).emit();
+ }
+
+ public static GizmoEntityModelGenerator entityModel(Class> type, CritterClassLoader critterClassLoader,
+ ClassNode classNode, List properties, MorphiaConfig config) {
+ return new GizmoEntityModelGenerator(type, critterClassLoader, classNode, properties, config).emit();
+ }
+}
diff --git a/critter/core/src/main/java/dev/morphia/critter/parser/gizmo/GizmoEntityModelGenerator.java b/core/src/main/java/dev/morphia/critter/parser/gizmo/GizmoEntityModelGenerator.java
similarity index 95%
rename from critter/core/src/main/java/dev/morphia/critter/parser/gizmo/GizmoEntityModelGenerator.java
rename to core/src/main/java/dev/morphia/critter/parser/gizmo/GizmoEntityModelGenerator.java
index c0f4cb58926..6419d95102a 100644
--- a/critter/core/src/main/java/dev/morphia/critter/parser/gizmo/GizmoEntityModelGenerator.java
+++ b/core/src/main/java/dev/morphia/critter/parser/gizmo/GizmoEntityModelGenerator.java
@@ -8,8 +8,8 @@
import dev.morphia.annotations.Entity;
import dev.morphia.annotations.internal.AnnotationNodeExtensions;
+import dev.morphia.config.MorphiaConfig;
import dev.morphia.critter.CritterClassLoader;
-import dev.morphia.critter.parser.Generators;
import dev.morphia.mapping.Mapper;
import dev.morphia.mapping.codec.pojo.EntityModel;
import dev.morphia.mapping.codec.pojo.PropertyModel;
@@ -29,10 +29,12 @@ public class GizmoEntityModelGenerator extends BaseGizmoGenerator {
private final List annotations;
private final List morphiaAnnotations;
private final Entity entityAnnotation;
+ private final MorphiaConfig config;
public GizmoEntityModelGenerator(Class> type, CritterClassLoader critterClassLoader,
- ClassNode classNode, List properties) {
+ ClassNode classNode, List properties, MorphiaConfig config) {
super(type, critterClassLoader);
+ this.config = config;
this.classNode = classNode;
this.properties = properties;
@@ -108,7 +110,7 @@ private void discriminatorKey() {
try (MethodCreator mc = getCreator().getMethodCreator("discriminatorKey", String.class)) {
String key = entityAnnotation.discriminator();
String result = Mapper.IGNORED_FIELDNAME.equals(key)
- ? Generators.INSTANCE.getConfig().discriminatorKey()
+ ? config.discriminatorKey()
: key;
mc.returnValue(mc.load(result));
}
@@ -116,7 +118,7 @@ private void discriminatorKey() {
private void discriminator() {
try (MethodCreator mc = getCreator().getMethodCreator("discriminator", String.class)) {
- String discriminator = Generators.INSTANCE.getConfig().discriminator()
+ String discriminator = config.discriminator()
.apply(entity, entityAnnotation.discriminator());
mc.returnValue(mc.load(discriminator));
}
@@ -126,7 +128,7 @@ private void collectionName() {
try (MethodCreator mc = getCreator().getMethodCreator("collectionName", String.class)) {
String key = entityAnnotation.value();
String result = Mapper.IGNORED_FIELDNAME.equals(key)
- ? Generators.INSTANCE.getConfig().collectionNaming().apply(entity.getSimpleName())
+ ? config.collectionNaming().apply(entity.getSimpleName())
: key;
mc.returnValue(mc.load(result));
}
diff --git a/critter/core/src/main/java/dev/morphia/critter/parser/gizmo/GizmoExtensions.java b/core/src/main/java/dev/morphia/critter/parser/gizmo/GizmoExtensions.java
similarity index 100%
rename from critter/core/src/main/java/dev/morphia/critter/parser/gizmo/GizmoExtensions.java
rename to core/src/main/java/dev/morphia/critter/parser/gizmo/GizmoExtensions.java
diff --git a/critter/core/src/main/java/dev/morphia/critter/parser/gizmo/PropertyAccessorGenerator.java b/core/src/main/java/dev/morphia/critter/parser/gizmo/PropertyAccessorGenerator.java
similarity index 100%
rename from critter/core/src/main/java/dev/morphia/critter/parser/gizmo/PropertyAccessorGenerator.java
rename to core/src/main/java/dev/morphia/critter/parser/gizmo/PropertyAccessorGenerator.java
diff --git a/critter/core/src/main/java/dev/morphia/critter/parser/gizmo/PropertyModelGenerator.java b/core/src/main/java/dev/morphia/critter/parser/gizmo/PropertyModelGenerator.java
similarity index 100%
rename from critter/core/src/main/java/dev/morphia/critter/parser/gizmo/PropertyModelGenerator.java
rename to core/src/main/java/dev/morphia/critter/parser/gizmo/PropertyModelGenerator.java
diff --git a/critter/core/src/main/java/dev/morphia/critter/parser/gizmo/VarHandleAccessorGenerator.java b/core/src/main/java/dev/morphia/critter/parser/gizmo/VarHandleAccessorGenerator.java
similarity index 100%
rename from critter/core/src/main/java/dev/morphia/critter/parser/gizmo/VarHandleAccessorGenerator.java
rename to core/src/main/java/dev/morphia/critter/parser/gizmo/VarHandleAccessorGenerator.java
diff --git a/critter/core/src/main/java/dev/morphia/critter/parser/java/CritterParser.java b/core/src/main/java/dev/morphia/critter/parser/java/CritterParser.java
similarity index 100%
rename from critter/core/src/main/java/dev/morphia/critter/parser/java/CritterParser.java
rename to core/src/main/java/dev/morphia/critter/parser/java/CritterParser.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/ClassfileOutput.java b/core/src/test/java/dev/morphia/critter/ClassfileOutput.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/ClassfileOutput.java
rename to core/src/test/java/dev/morphia/critter/ClassfileOutput.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/parser/BaseCritterTest.java b/core/src/test/java/dev/morphia/critter/parser/BaseCritterTest.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/parser/BaseCritterTest.java
rename to core/src/test/java/dev/morphia/critter/parser/BaseCritterTest.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/parser/GeneratorTest.java b/core/src/test/java/dev/morphia/critter/parser/GeneratorTest.java
similarity index 87%
rename from critter/core/src/test/java/dev/morphia/critter/parser/GeneratorTest.java
rename to core/src/test/java/dev/morphia/critter/parser/GeneratorTest.java
index 846fbabbd5a..4948cd15df1 100644
--- a/critter/core/src/test/java/dev/morphia/critter/parser/GeneratorTest.java
+++ b/core/src/test/java/dev/morphia/critter/parser/GeneratorTest.java
@@ -9,11 +9,13 @@
import java.util.function.Predicate;
import java.util.stream.Collectors;
+import dev.morphia.config.MorphiaConfig;
import dev.morphia.critter.ClassfileOutput;
import dev.morphia.critter.CritterClassLoader;
import dev.morphia.critter.parser.gizmo.CritterGizmoGenerator;
import dev.morphia.critter.parser.gizmo.GizmoEntityModelGenerator;
import dev.morphia.critter.sources.Example;
+import dev.morphia.mapping.ReflectiveMapper;
import dev.morphia.mapping.codec.pojo.critter.CritterEntityModel;
import io.github.classgraph.ClassGraph;
@@ -38,12 +40,14 @@ public class GeneratorTest {
} catch (Exception ignored) {
}
- GizmoEntityModelGenerator gen = CritterGizmoGenerator.INSTANCE.generate(Example.class, critterClassLoader, false);
+ MorphiaConfig config = MorphiaConfig.load();
+ Generators generators = new Generators(config, new ReflectiveMapper(config));
+ GizmoEntityModelGenerator gen = CritterGizmoGenerator.generate(Example.class, critterClassLoader, generators, false);
try {
entityModel = (CritterEntityModel) critterClassLoader
.loadClass(gen.getGeneratedType())
.getConstructors()[0]
- .newInstance(Generators.INSTANCE.getMapper());
+ .newInstance(generators.getMapper());
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/critter/core/src/test/java/dev/morphia/critter/parser/TestAccessorsMutators.java b/core/src/test/java/dev/morphia/critter/parser/TestAccessorsMutators.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/parser/TestAccessorsMutators.java
rename to core/src/test/java/dev/morphia/critter/parser/TestAccessorsMutators.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/parser/TestEntityModelGenerator.java b/core/src/test/java/dev/morphia/critter/parser/TestEntityModelGenerator.java
similarity index 93%
rename from critter/core/src/test/java/dev/morphia/critter/parser/TestEntityModelGenerator.java
rename to core/src/test/java/dev/morphia/critter/parser/TestEntityModelGenerator.java
index 2f56301ea7b..5d9b42495fc 100644
--- a/critter/core/src/test/java/dev/morphia/critter/parser/TestEntityModelGenerator.java
+++ b/core/src/test/java/dev/morphia/critter/parser/TestEntityModelGenerator.java
@@ -2,6 +2,7 @@
import java.lang.reflect.Method;
+import dev.morphia.config.MorphiaConfig;
import dev.morphia.critter.ClassfileOutput;
import dev.morphia.critter.CritterClassLoader;
import dev.morphia.mapping.Mapper;
@@ -18,7 +19,7 @@ public class TestEntityModelGenerator {
private static final Logger LOG = LoggerFactory.getLogger(TestEntityModelGenerator.class);
private final CritterEntityModel control;
- private final Mapper mapper = new ReflectiveMapper(Generators.INSTANCE.getConfig());
+ private final Mapper mapper = new ReflectiveMapper(MorphiaConfig.load());
private final CritterClassLoader critterClassLoader = new CritterClassLoader();
public TestEntityModelGenerator() {
diff --git a/critter/core/src/test/java/dev/morphia/critter/parser/TestPropertyModelGenerator.java b/core/src/test/java/dev/morphia/critter/parser/TestPropertyModelGenerator.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/parser/TestPropertyModelGenerator.java
rename to core/src/test/java/dev/morphia/critter/parser/TestPropertyModelGenerator.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/parser/TestVarHandleAccessor.java b/core/src/test/java/dev/morphia/critter/parser/TestVarHandleAccessor.java
similarity index 92%
rename from critter/core/src/test/java/dev/morphia/critter/parser/TestVarHandleAccessor.java
rename to core/src/test/java/dev/morphia/critter/parser/TestVarHandleAccessor.java
index 5dbf0349c1c..d15cbfb1b7d 100644
--- a/critter/core/src/test/java/dev/morphia/critter/parser/TestVarHandleAccessor.java
+++ b/core/src/test/java/dev/morphia/critter/parser/TestVarHandleAccessor.java
@@ -4,10 +4,12 @@
import java.util.List;
import java.util.stream.Collectors;
+import dev.morphia.config.MorphiaConfig;
import dev.morphia.critter.Critter;
import dev.morphia.critter.CritterClassLoader;
import dev.morphia.critter.parser.gizmo.CritterGizmoGenerator;
import dev.morphia.critter.sources.Example;
+import dev.morphia.mapping.ReflectiveMapper;
import org.bson.codecs.pojo.PropertyAccessor;
import org.testng.Assert;
@@ -20,7 +22,8 @@ public class TestVarHandleAccessor {
@BeforeClass
public void setup() {
classLoader = new CritterClassLoader();
- CritterGizmoGenerator.INSTANCE.generate(Example.class, classLoader, true);
+ MorphiaConfig config = dev.morphia.config.MorphiaConfig.load();
+ CritterGizmoGenerator.generate(Example.class, classLoader, new Generators(config, new ReflectiveMapper(config)), true);
}
@Test
diff --git a/critter/core/src/test/java/dev/morphia/critter/parser/TypesTest.java b/core/src/test/java/dev/morphia/critter/parser/TypesTest.java
similarity index 96%
rename from critter/core/src/test/java/dev/morphia/critter/parser/TypesTest.java
rename to core/src/test/java/dev/morphia/critter/parser/TypesTest.java
index 58d991c1951..b1b9a412409 100644
--- a/critter/core/src/test/java/dev/morphia/critter/parser/TypesTest.java
+++ b/core/src/test/java/dev/morphia/critter/parser/TypesTest.java
@@ -81,7 +81,7 @@ public Object[][] typeProvider() {
@Test(dataProvider = "types")
public void asClassConversion(Class> expected) {
Type type = Type.getType(expected);
- Class> actual = Generators.INSTANCE.asClass(type, Thread.currentThread().getContextClassLoader());
+ Class> actual = Generators.asClass(type, Thread.currentThread().getContextClassLoader());
Assert.assertEquals(actual, expected, "Type " + type.getDescriptor() + " should convert to " + expected.getName());
}
}
diff --git a/critter/core/src/test/java/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.java b/core/src/test/java/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.java
similarity index 97%
rename from critter/core/src/test/java/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.java
rename to core/src/test/java/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.java
index cddb2678738..50e8770429f 100644
--- a/critter/core/src/test/java/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.java
+++ b/core/src/test/java/dev/morphia/critter/parser/gizmo/TestGizmoGeneration.java
@@ -19,12 +19,14 @@
import dev.morphia.annotations.internal.IndexBuilder;
import dev.morphia.annotations.internal.IndexOptionsBuilder;
import dev.morphia.annotations.internal.IndexesBuilder;
+import dev.morphia.config.MorphiaConfig;
import dev.morphia.critter.ClassfileOutput;
import dev.morphia.critter.CritterClassLoader;
import dev.morphia.critter.parser.Generators;
import dev.morphia.critter.parser.asm.AddMethodAccessorMethods;
import dev.morphia.critter.sources.Example;
import dev.morphia.critter.sources.MethodExample;
+import dev.morphia.mapping.ReflectiveMapper;
import dev.morphia.mapping.codec.pojo.EntityModel;
import dev.morphia.mapping.codec.pojo.PropertyModel;
import dev.morphia.mapping.codec.pojo.TypeData;
@@ -135,7 +137,9 @@ public void testAnnotationBuilding() throws Exception {
@Test
public void testGizmo() throws Exception {
- CritterGizmoGenerator.INSTANCE.generate(Example.class, critterClassLoader, false);
+ MorphiaConfig config = dev.morphia.config.MorphiaConfig.load();
+ Generators generators = new Generators(config, new ReflectiveMapper(config));
+ CritterGizmoGenerator.generate(Example.class, critterClassLoader, generators, false);
critterClassLoader.loadClass("dev.morphia.critter.sources.__morphia.example.AgeModel");
Class> nameModel = critterClassLoader.loadClass("dev.morphia.critter.sources.__morphia.example.NameModel");
invokeAll(PropertyModel.class, nameModel);
@@ -145,7 +149,7 @@ public void testGizmo() throws Exception {
critterClassLoader.loadClass("dev.morphia.critter.sources.__morphia.example.SalaryAccessor").getConstructor().newInstance();
Class> loadClass = critterClassLoader.loadClass("dev.morphia.critter.sources.__morphia.example.ExampleEntityModel");
- EntityModel model = (EntityModel) loadClass.getConstructors()[0].newInstance(Generators.INSTANCE.getMapper());
+ EntityModel model = (EntityModel) loadClass.getConstructors()[0].newInstance(generators.getMapper());
validate(model);
}
diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/Example.java b/core/src/test/java/dev/morphia/critter/sources/Example.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/sources/Example.java
rename to core/src/test/java/dev/morphia/critter/sources/Example.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleAgeAccessorTemplate.java b/core/src/test/java/dev/morphia/critter/sources/ExampleAgeAccessorTemplate.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/sources/ExampleAgeAccessorTemplate.java
rename to core/src/test/java/dev/morphia/critter/sources/ExampleAgeAccessorTemplate.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleAgePropertyModelTemplate.java b/core/src/test/java/dev/morphia/critter/sources/ExampleAgePropertyModelTemplate.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/sources/ExampleAgePropertyModelTemplate.java
rename to core/src/test/java/dev/morphia/critter/sources/ExampleAgePropertyModelTemplate.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleEntityModelTemplate.java b/core/src/test/java/dev/morphia/critter/sources/ExampleEntityModelTemplate.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/sources/ExampleEntityModelTemplate.java
rename to core/src/test/java/dev/morphia/critter/sources/ExampleEntityModelTemplate.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleNameAccessorTemplate.java b/core/src/test/java/dev/morphia/critter/sources/ExampleNameAccessorTemplate.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/sources/ExampleNameAccessorTemplate.java
rename to core/src/test/java/dev/morphia/critter/sources/ExampleNameAccessorTemplate.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleNamePropertyModelTemplate.java b/core/src/test/java/dev/morphia/critter/sources/ExampleNamePropertyModelTemplate.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/sources/ExampleNamePropertyModelTemplate.java
rename to core/src/test/java/dev/morphia/critter/sources/ExampleNamePropertyModelTemplate.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryAccessorTemplate.java b/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryAccessorTemplate.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryAccessorTemplate.java
rename to core/src/test/java/dev/morphia/critter/sources/ExampleSalaryAccessorTemplate.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryPropertyModelTemplate.java b/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryPropertyModelTemplate.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/sources/ExampleSalaryPropertyModelTemplate.java
rename to core/src/test/java/dev/morphia/critter/sources/ExampleSalaryPropertyModelTemplate.java
diff --git a/critter/core/src/test/java/dev/morphia/critter/sources/MethodExample.java b/core/src/test/java/dev/morphia/critter/sources/MethodExample.java
similarity index 100%
rename from critter/core/src/test/java/dev/morphia/critter/sources/MethodExample.java
rename to core/src/test/java/dev/morphia/critter/sources/MethodExample.java
diff --git a/core/src/test/java/dev/morphia/test/config/TestConfig.java b/core/src/test/java/dev/morphia/test/config/TestConfig.java
index dbeefcf9173..bb5cae18058 100644
--- a/core/src/test/java/dev/morphia/test/config/TestConfig.java
+++ b/core/src/test/java/dev/morphia/test/config/TestConfig.java
@@ -8,7 +8,6 @@
import dev.morphia.Datastore;
import dev.morphia.Morphia;
import dev.morphia.MorphiaDatastore;
-import dev.morphia.config.ManualMorphiaConfig;
import dev.morphia.config.MorphiaConfig;
import dev.morphia.config.MorphiaConfigHelper;
import dev.morphia.mapping.MappingException;
@@ -48,19 +47,19 @@ public void generateExampleConfigFiles() throws IOException {
var docsTarget = new File(root, "docs/modules/ROOT/examples");
try (var writer = new FileWriter(new File(docsTarget, "complete-morphia-config.properties"))) {
- var configContents = MorphiaConfigHelper.dumpConfigurationFile(new ManualMorphiaConfig(), true);
+ var configContents = MorphiaConfigHelper.dumpConfigurationFile(dev.morphia.config.MorphiaConfig.load(), true);
writer.write(configContents);
writer.flush();
}
try (var writer = new FileWriter(new File(docsTarget, "minimal-morphia-config.properties"))) {
- var configContents = MorphiaConfigHelper.dumpConfigurationFile(new ManualMorphiaConfig(), false);
+ var configContents = MorphiaConfigHelper.dumpConfigurationFile(dev.morphia.config.MorphiaConfig.load(), false);
writer.write(configContents);
writer.flush();
}
try (var writer = new FileWriter(new File(docsTarget, "legacy-morphia-config.properties"))) {
- var configContents = MorphiaConfigHelper.dumpConfigurationFile(new ManualMorphiaConfig()
+ var configContents = MorphiaConfigHelper.dumpConfigurationFile(dev.morphia.config.MorphiaConfig.load()
.legacy(), false);
writer.write(configContents);
writer.flush();
diff --git a/critter/core/src/main/java/dev/morphia/critter/parser/gizmo/CritterGizmoGenerator.java b/critter/core/src/main/java/dev/morphia/critter/parser/gizmo/CritterGizmoGenerator.java
deleted file mode 100644
index 7c2174d9bac..00000000000
--- a/critter/core/src/main/java/dev/morphia/critter/parser/gizmo/CritterGizmoGenerator.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package dev.morphia.critter.parser.gizmo;
-
-import java.io.IOException;
-import java.util.List;
-
-import dev.morphia.critter.CritterClassLoader;
-import dev.morphia.critter.parser.Generators;
-import dev.morphia.critter.parser.PropertyFinder;
-import dev.morphia.critter.parser.asm.AddFieldAccessorMethods;
-import dev.morphia.critter.parser.asm.AddMethodAccessorMethods;
-
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.tree.ClassNode;
-import org.objectweb.asm.tree.FieldNode;
-import org.objectweb.asm.tree.MethodNode;
-
-public class CritterGizmoGenerator {
- public static final CritterGizmoGenerator INSTANCE = new CritterGizmoGenerator();
-
- private CritterGizmoGenerator() {
- }
-
- public GizmoEntityModelGenerator generate(Class> type, CritterClassLoader critterClassLoader, boolean runtimeMode) {
- ClassNode classNode = new ClassNode();
- String resourceName = "%s.class".formatted(type.getName().replace('.', '/'));
- java.io.InputStream inputStream = type.getClassLoader().getResourceAsStream(resourceName);
- if (inputStream == null) {
- throw new IllegalArgumentException("Could not find class file for %s".formatted(type.getName()));
- }
- try {
- new ClassReader(inputStream).accept(classNode, 0);
- } catch (IOException e) {
- throw new RuntimeException("Failed to read class %s".formatted(type.getName()), e);
- }
- PropertyFinder propertyFinder = new PropertyFinder(Generators.INSTANCE.getMapper(), critterClassLoader, runtimeMode);
-
- return entityModel(type, critterClassLoader, classNode, propertyFinder.find(type, classNode));
- }
-
- public GizmoEntityModelGenerator generate(Class> type, CritterClassLoader critterClassLoader) {
- return generate(type, critterClassLoader, false);
- }
-
- public byte[] fieldAccessors(Class> entityType, List fields) {
- return new AddFieldAccessorMethods(entityType, fields).emit();
- }
-
- public byte[] methodAccessors(Class> entityType, List methods) {
- return new AddMethodAccessorMethods(entityType, methods).emit();
- }
-
- public PropertyAccessorGenerator propertyAccessor(Class> entityType, CritterClassLoader critterClassLoader, FieldNode field) {
- return new PropertyAccessorGenerator(entityType, critterClassLoader, field).emit();
- }
-
- public PropertyAccessorGenerator propertyAccessor(Class> entityType, CritterClassLoader critterClassLoader, MethodNode method) {
- return new PropertyAccessorGenerator(entityType, critterClassLoader, method).emit();
- }
-
- public VarHandleAccessorGenerator varHandleAccessor(Class> entityType, CritterClassLoader critterClassLoader, FieldNode field) {
- return new VarHandleAccessorGenerator(entityType, critterClassLoader, field).emit();
- }
-
- public VarHandleAccessorGenerator varHandleAccessor(Class> entityType, CritterClassLoader critterClassLoader, MethodNode method) {
- return new VarHandleAccessorGenerator(entityType, critterClassLoader, method).emit();
- }
-
- public PropertyModelGenerator propertyModelGenerator(Class> entityType, CritterClassLoader critterClassLoader, FieldNode field) {
- return new PropertyModelGenerator(Generators.INSTANCE.getConfig(), entityType, critterClassLoader, field).emit();
- }
-
- public PropertyModelGenerator propertyModelGenerator(Class> entityType, CritterClassLoader critterClassLoader, MethodNode method) {
- return new PropertyModelGenerator(Generators.INSTANCE.getConfig(), entityType, critterClassLoader, method).emit();
- }
-
- public GizmoEntityModelGenerator entityModel(Class> type, CritterClassLoader critterClassLoader,
- ClassNode classNode, List properties) {
- return new GizmoEntityModelGenerator(type, critterClassLoader, classNode, properties).emit();
- }
-}
diff --git a/critter/critter-maven/src/main/kotlin/dev/morphia/critter/maven/CritterProcessor.kt b/critter/critter-maven/src/main/kotlin/dev/morphia/critter/maven/CritterProcessor.kt
index 5de1d6f42d7..401e0eca497 100644
--- a/critter/critter-maven/src/main/kotlin/dev/morphia/critter/maven/CritterProcessor.kt
+++ b/critter/critter-maven/src/main/kotlin/dev/morphia/critter/maven/CritterProcessor.kt
@@ -5,6 +5,7 @@ import dev.morphia.config.MorphiaConfig
import dev.morphia.critter.CritterClassLoader
import dev.morphia.critter.parser.Generators
import dev.morphia.critter.parser.gizmo.CritterGizmoGenerator
+import dev.morphia.mapping.ReflectiveMapper
import io.github.classgraph.ClassGraph
import java.io.File
import org.slf4j.Logger
@@ -20,12 +21,10 @@ class CritterProcessor(
) {
private val logger: Logger = LoggerFactory.getLogger(CritterProcessor::class.java)
- private val critterClassLoader = CritterClassLoader()
+ private val critterClassLoader = CritterClassLoader(classLoader)
+ private val generators = Generators(config, ReflectiveMapper(config))
fun process() {
- // Configure Generators with the loaded MorphiaConfig
- Generators.INSTANCE.configFile = findConfigFile()
-
val entityClasses = findEntityClasses()
if (entityClasses.isEmpty()) {
@@ -44,17 +43,6 @@ class CritterProcessor(
writeGeneratedClasses()
}
- private fun findConfigFile(): String {
- // Check if morphia-config.properties exists in the classes directory
- val configFile = File(classesDirectory, "META-INF/morphia-config.properties")
- return if (configFile.exists()) {
- "META-INF/morphia-config.properties"
- } else {
- // Return default location - Generators will use defaults if not found
- "META-INF/morphia-config.properties"
- }
- }
-
private fun findEntityClasses(): List> {
val packagesToScan =
packages.ifEmpty {
@@ -84,7 +72,7 @@ class CritterProcessor(
private fun processClass(entityClass: Class<*>) {
logger.info("Generating critter code for: ${entityClass.name}")
- CritterGizmoGenerator.INSTANCE.generate(entityClass, critterClassLoader, false)
+ CritterGizmoGenerator.generate(entityClass, critterClassLoader, generators, false)
}
private fun writeGeneratedClasses() {
diff --git a/critter/pom.xml b/critter/pom.xml
index 4c08fd018b3..a442d36d109 100644
--- a/critter/pom.xml
+++ b/critter/pom.xml
@@ -15,8 +15,7 @@
pom
- core
critter-maven
critter-integration-tests
-
\ No newline at end of file
+