From e161c42109c787300d61869b7f810c971f9e126e Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Fri, 27 Jan 2023 16:24:12 +0100 Subject: [PATCH 01/19] Add javadocs to codec classes --- .../codec/InternalPropertyCodecProvider.java | 3 +++ .../en2do/internal/codec/lang/ClassCodec.java | 19 +++++++++++++++++++ .../internal/codec/map/GenericMapCodec.java | 6 ++++++ 3 files changed, 28 insertions(+) diff --git a/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java b/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java index 320bc7d2..814ca85d 100644 --- a/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java +++ b/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java @@ -10,6 +10,9 @@ import java.util.Map; +/** + * This codec provider enables the usage of the en2do custom codecs and adds them to the CodecRegistry + */ @Log public class InternalPropertyCodecProvider implements PropertyCodecProvider { diff --git a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java index f183616a..32a97887 100644 --- a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java +++ b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java @@ -7,14 +7,29 @@ import org.bson.codecs.DecoderContext; import org.bson.codecs.EncoderContext; +/** + * ClassCodec is used to encode and decode java.lang.Class objects to mongodb document fields + */ @SuppressWarnings("rawtypes") public class ClassCodec implements Codec<Class> { + /** + * See org.bson.codecs.Encoder + * @param writer the BSON writer to encode into + * @param value the value to encode + * @param encoderContext the encoder context + */ @Override public void encode(BsonWriter writer, Class value, EncoderContext encoderContext) { writer.writeString(value.getName()); } + /** + * See org.bson.codecs.Decoder + * @param reader the BSON reader + * @param decoderContext the decoder context + * @return the decoded Class + */ @Override public Class decode(BsonReader reader, DecoderContext decoderContext) { String className = reader.readString(); @@ -25,6 +40,10 @@ public Class decode(BsonReader reader, DecoderContext decoderContext) { } } + /** + * See org.bson.codecs.Encoder + * @return the class of the encoded class + */ @Override public Class<Class> getEncoderClass() { return Class.class; diff --git a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java index 8969e61a..5505403a 100644 --- a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java +++ b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java @@ -18,6 +18,12 @@ import java.util.UUID; import java.util.logging.Level; +/** + * This codec is used to allow different types as map keys, because + * mongodb pojo-codec only supports strings as map keys. + * @param <K> The type of the key of the generic map + * @param <T> The type of the value of the generic map + */ @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) @Log public class GenericMapCodec<K, T> implements Codec<Map<K, T>> { From 3b6c1b374a15ab789d7c24e310b290a4eaa69287 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Fri, 27 Jan 2023 16:40:08 +0100 Subject: [PATCH 02/19] Add javadocs to method options --- .../methods/pagination/Pagination.java | 26 +++++++++++++++++ .../en2do/repository/methods/sort/Limit.java | 6 ++++ .../en2do/repository/methods/sort/Skip.java | 6 ++++ .../en2do/repository/methods/sort/Sort.java | 29 +++++++++++++++++++ .../en2do/repository/methods/sort/SortBy.java | 9 ++++++ .../repository/methods/sort/SortByArray.java | 6 ++++ .../methods/transform/Transform.java | 8 +++++ 7 files changed, 90 insertions(+) diff --git a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java index ccb0132c..1571fb9e 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java @@ -8,10 +8,18 @@ import java.util.HashMap; import java.util.Map; +/** + * This object is used to provide simplified pagination in several repositories. + */ @Getter @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) public class Pagination { + /** + * Use this method to create a new pagination object. + * @param entitiesPerPage Sets the maximum entities per one page. + * @return The created Pagination object + */ public static Pagination of(int entitiesPerPage) { return new Pagination(entitiesPerPage); } @@ -27,15 +35,33 @@ private Pagination(int entitiesPerPage) { this.page = 1; } + /** + * Use this method to define the order / sorting by the given fields + * @param fieldName The field which is used to sort + * @param ascending The direction of the sorting + * @return The used Pagination object + */ public Pagination order(String fieldName, boolean ascending) { pageDirectionMap.put(fieldName, ascending ? 1 : -1); return this; } + /** + * Use this method to define the order / sorting of the pagination, + * but sets the ascending value to "true" + * @param fieldName The field which is used to sort + * @return The used Pagination object + */ public Pagination order(String fieldName) { return order(fieldName, true); } + /** + * Use this method to set the returned page. If the page doesn't exist, + * the method will just return an empty list. + * @param page The requested page + * @return The used Pagination object + */ public Pagination page(long page) { this.page = page; return this; diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java index 06aeeee6..1de7229f 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java @@ -5,9 +5,15 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation is used to limit the amount of the returned entities in the List. + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Limit { + /** + * @return The amount of the entities in the returned List. + */ int value(); } diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java index c7d10f8a..2b7f5422 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java @@ -5,9 +5,15 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation is used to skip the defined amount of entities by the given sorting. + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Skip { + /** + * @return The amount of the skipped entities. + */ int value(); } diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java index 3506d69c..62843937 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java @@ -7,6 +7,9 @@ import java.util.HashMap; import java.util.Map; +/** + * This object is used to enable dynamic sorting, without defining the sorting options statically through annotations. + */ @Getter @FieldDefaults(level = AccessLevel.PRIVATE) public class Sort { @@ -16,6 +19,10 @@ public static Sort create() { return of(); } + /** + * Use this method to create a new Sort object + * @return The new created sort object. + */ public static Sort of() { return new Sort(); } @@ -30,20 +37,42 @@ private Sort() { this.skip = -1; } + /** + * Use this method to define the order / sorting by the given fields + * @param fieldName The field which is used to sort + * @param ascending The direction of the sorting + * @return The used Sort object + */ public Sort order(String fieldName, boolean ascending) { fieldDirectionMap.put(fieldName, ascending ? 1 : -1); return this; } + /** + * Use this method to define the order / sorting by the given fields, + * but sets the ascending value to "true" + * @param fieldName The field which is used to sort + * @return The used Sort object + */ public Sort order(String fieldName) { return order(fieldName, true); } + /** + * Use this method to set the limit of entities of the current sorting. + * @param limit The amount of the entities in the returned List. + * @return The used Sort object + */ public Sort limit(int limit) { this.limit = limit; return this; } + /** + * Use this method to set the skipped entities of the current sorting. + * @param skip The amount of the entities, which should be skipped, before creating the List. + * @return The used Sort object + */ public Sort skip(int skip) { this.skip = skip; return this; diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java index 4059851e..a27d945a 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java @@ -2,12 +2,21 @@ import java.lang.annotation.*; +/** + * This annotation is used to define the sorting of the given fields. + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Repeatable(value = SortByArray.class) public @interface SortBy { + /** + * @return The required field, which should be sorted. + */ String field(); + /** + * @return The optional direction, which defaults to ascending = "true". + */ boolean ascending() default false; } diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java index ec107f96..31014e0f 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java @@ -5,9 +5,15 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation is used to create an array of the @SortBy annotation. + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface SortByArray { + /** + * @return The array of the @SortBy annotations. + */ SortBy[] value(); } diff --git a/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java b/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java index 6a2ce5c1..9309e1dd 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java @@ -5,9 +5,17 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation is used to "rename" a method name of the repository. + * If you use this annotation, keep in mind, that the validation uses the + * value of the annotation instead of the method name itself. + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Transform { + /** + * @return The "real" method declaration according to the en2do specification. + */ String value(); } From aecab6369c88e96efc8ed76708b46d9333e5d097 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Fri, 27 Jan 2023 16:50:32 +0100 Subject: [PATCH 03/19] Add javadocs to repository options --- .../koboo/en2do/repository/AppendMethodAsComment.java | 4 +++- .../java/eu/koboo/en2do/repository/Collection.java | 11 +++++++---- .../koboo/en2do/repository/DropEntitiesOnStart.java | 5 ++++- .../eu/koboo/en2do/repository/DropIndexesOnStart.java | 5 ++++- .../eu/koboo/en2do/repository/SeparateEntityId.java | 5 +++++ 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java index 2877317d..bf90104f 100644 --- a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java +++ b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java @@ -2,7 +2,9 @@ import java.lang.annotation.*; -@Inherited +/** + * This annotation appends the repository method name to the mongodb find queries. + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface AppendMethodAsComment { diff --git a/src/main/java/eu/koboo/en2do/repository/Collection.java b/src/main/java/eu/koboo/en2do/repository/Collection.java index 804b2aca..c0e7312d 100644 --- a/src/main/java/eu/koboo/en2do/repository/Collection.java +++ b/src/main/java/eu/koboo/en2do/repository/Collection.java @@ -1,13 +1,16 @@ package eu.koboo.en2do.repository; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; +/** + * This annotation defines the collection name of the repository in the mongodb. + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Collection { + /** + * @return The collection name in the mongodb. + */ String value(); } diff --git a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java index b77b04c4..03b21436 100644 --- a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java +++ b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java @@ -2,7 +2,10 @@ import java.lang.annotation.*; -@Inherited +/** + * This annotation drops all previously created entities, when the annotated repository is created. + * CAUTION: This will delete all entities permanently! + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface DropEntitiesOnStart { diff --git a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java index ba2eed9a..d21f25c9 100644 --- a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java +++ b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java @@ -2,7 +2,10 @@ import java.lang.annotation.*; -@Inherited +/** + * This annotation drops all previously created indexes, when the annotated repository is created. + * CAUTION: This will delete all indexes permanently! + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface DropIndexesOnStart { diff --git a/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java b/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java index 9d097aa0..b444a458 100644 --- a/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java +++ b/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java @@ -5,6 +5,11 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * This annotation separates the "_id" field of the mongodb document and the "@Id" annotated field of the + * entity. If this annotation is NOT used on the repository, the "@Id" field can't be annotated with "@NonIndex", that + * will throw an exception. + */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface SeparateEntityId { From 92e19d628b097de063a3b8d6cae28a5d523bdd2d Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Fri, 27 Jan 2023 17:00:54 +0100 Subject: [PATCH 04/19] Add javadocs to the repository interface --- .../eu/koboo/en2do/repository/Repository.java | 90 ++++++++++++++++++- 1 file changed, 88 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/koboo/en2do/repository/Repository.java b/src/main/java/eu/koboo/en2do/repository/Repository.java index c43262d3..ee1bf59f 100644 --- a/src/main/java/eu/koboo/en2do/repository/Repository.java +++ b/src/main/java/eu/koboo/en2do/repository/Repository.java @@ -5,40 +5,126 @@ import java.util.List; +/** + * The default Repository interface, which predefines several useful methods. + * @param <E> The generic type of the Entity + * @param <ID> The generic type of the field annotated with "@Id" in the Entity + */ @SuppressWarnings("unused") public interface Repository<E, ID> { + /** + * This method counts all documents of the collection in the mongodb. + * @return The amount of total entities in this repository. + */ long countAll(); + /** + * This method deletes the given entity, by filtering with the entity's "@Id" field/unique identifier. + * @param entity The entity, which should be deleted. + * @return true, if the entity was deleted successfully. + */ boolean delete(E entity); + /** + * This method deletes all entities of the given list, filtering like the "#delete(E entity)" method. + * @param entityList The List with the entities, which should be deleted. + * @return true, if all entities were deleted successfully. + */ boolean deleteAll(List<E> entityList); + /** + * This method deletes the entity with the given identifier, filtering like the "#delete(E entity)" method. + * @param identifier The unique identifier of the entity, which should be deleted. + * @return true, if the entity was deleted successfully. + */ boolean deleteById(ID identifier); + /** + * Drops / deletes all entities of the repository. + * @return true, if all entities were deleted successfully. + */ boolean drop(); + /** + * Checks if the given entity exists in the repository, by filtering with the entity's + * "@Id" field/unique identifier. + * @param entity The entity, which should be checked. + * @return true, if the entity exists in the collection. + */ boolean exists(E entity); + /** + * Checks if an entity with the given unique identifier exists in the repository, like the "#exists(E entity)" method. + * @param identifier The identifier of the entity, which should be checked. + * @return true, if an entity with the given identifier exists in the collection. + */ boolean existsById(ID identifier); + /** + * Finds all entities of the collection + * @return A List with all entities of the repository. + */ List<E> findAll(); + /** + * Find the first entity with the given unique identifier. + * If the entity is not found, "null" is returned. + * @param identifier The unique identifier of the entity, which is used to filter. + * @return The found entity, if it exists, or "null" if it not exists. + */ E findFirstById(ID identifier); + /** + * @return The collection name, defined by the "@Collection" annotation of the repository. + */ String getCollectionName(); + /** + * @return The Class of the entity of the repository. + */ Class<E> getEntityClass(); + /** + * @return The Class of the unique identifier of the entity of the repository. + */ Class<ID> getEntityUniqueIdClass(); + /** + * This method is used to get the unique identifier of the given entity. + * If the entity doesn't have a unique identifier, a NullPointerException is thrown. + * @param entity The entity, which unique identifier, should be returned + * @return The unique identifier of the given entity. + */ ID getUniqueId(E entity); - List<E> pageAll(Pagination pager); - + /** + * This method applies the pagination of all entities of the repository. + * @param pagination The pagination, which is used to page the entities. + * @return A List with the paged entities. + */ + List<E> pageAll(Pagination pagination); + + /** + * Saves the given entity to the database. + * If the entity exists, the existing document is updated. + * If the entity doesn't exist, a new document is created. + * @param entity The entity, which should be saved. + * @return true, if the entity was successfully saved. + */ boolean save(E entity); + /** + * Saves all entities of the given List to the database. + * @param entityList A List of the entities, which should be saved + * @return true, if the entities were successfully saved. + */ boolean saveAll(List<E> entityList); + /** + * This method applies the Sort object of all entities of the repository. + * @param sort The Sort object, which should be used to sort all entities. + * @return A List with the sorted entities. + */ List<E> sortAll(Sort sort); } From 61804284cbff6d8fc0c819d323a832170152bd24 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Fri, 27 Jan 2023 17:12:17 +0100 Subject: [PATCH 05/19] Add more javadocs + documentation links to gitbook --- src/main/java/eu/koboo/en2do/Credentials.java | 6 ++++++ src/main/java/eu/koboo/en2do/MongoManager.java | 6 ++++++ .../eu/koboo/en2do/repository/AppendMethodAsComment.java | 1 + src/main/java/eu/koboo/en2do/repository/Collection.java | 1 + .../eu/koboo/en2do/repository/DropEntitiesOnStart.java | 1 + .../java/eu/koboo/en2do/repository/DropIndexesOnStart.java | 1 + src/main/java/eu/koboo/en2do/repository/Repository.java | 2 ++ .../java/eu/koboo/en2do/repository/SeparateEntityId.java | 1 + src/main/java/eu/koboo/en2do/repository/entity/Id.java | 4 ++++ .../java/eu/koboo/en2do/repository/entity/NonIndex.java | 3 +++ .../eu/koboo/en2do/repository/entity/TransformField.java | 7 +++++++ .../java/eu/koboo/en2do/repository/entity/Transient.java | 5 +++++ .../repository/entity/compound/CompoundIndexArray.java | 6 ++++++ .../eu/koboo/en2do/repository/entity/ttl/TTLIndex.java | 6 ++++++ .../koboo/en2do/repository/entity/ttl/TTLIndexArray.java | 6 ++++++ .../en2do/repository/methods/pagination/Pagination.java | 1 + .../java/eu/koboo/en2do/repository/methods/sort/Limit.java | 1 + .../java/eu/koboo/en2do/repository/methods/sort/Skip.java | 1 + .../java/eu/koboo/en2do/repository/methods/sort/Sort.java | 1 + .../eu/koboo/en2do/repository/methods/sort/SortBy.java | 1 + .../koboo/en2do/repository/methods/sort/SortByArray.java | 1 + .../en2do/repository/methods/transform/Transform.java | 1 + 22 files changed, 63 insertions(+) diff --git a/src/main/java/eu/koboo/en2do/Credentials.java b/src/main/java/eu/koboo/en2do/Credentials.java index a1da9e14..0985addf 100644 --- a/src/main/java/eu/koboo/en2do/Credentials.java +++ b/src/main/java/eu/koboo/en2do/Credentials.java @@ -8,6 +8,12 @@ import java.util.Locale; import java.util.Properties; +/** + * This object is used to simplify creating credentials to the mongodb server. + * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-mongomanager">...</a> + * @param connectString The connection string to the mongodb database server + * @param database The database, which should be used + */ @SuppressWarnings("unused") public record Credentials(String connectString, String database) { diff --git a/src/main/java/eu/koboo/en2do/MongoManager.java b/src/main/java/eu/koboo/en2do/MongoManager.java index d6d7d248..5f414612 100644 --- a/src/main/java/eu/koboo/en2do/MongoManager.java +++ b/src/main/java/eu/koboo/en2do/MongoManager.java @@ -56,6 +56,12 @@ import static org.bson.codecs.configuration.CodecRegistries.fromProviders; import static org.bson.codecs.configuration.CodecRegistries.fromRegistries; +/** + * This object is the main entry point of en2do. + * The connection will be opened on construction. + * Keep in mind, that you should call "#MongoManger#close()" on application shutdown/termination. + * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-mongomanager">...</a> + */ @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) public class MongoManager { diff --git a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java index bf90104f..b52b3edf 100644 --- a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java +++ b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java @@ -4,6 +4,7 @@ /** * This annotation appends the repository method name to the mongodb find queries. + * See documentation: <a href="https://koboo.gitbook.io/en2do/repository-options/appendmethodascomment">...</a> */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/src/main/java/eu/koboo/en2do/repository/Collection.java b/src/main/java/eu/koboo/en2do/repository/Collection.java index c0e7312d..d82bc5ae 100644 --- a/src/main/java/eu/koboo/en2do/repository/Collection.java +++ b/src/main/java/eu/koboo/en2do/repository/Collection.java @@ -4,6 +4,7 @@ /** * This annotation defines the collection name of the repository in the mongodb. + * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-repository">...</a> */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java index 03b21436..d2acdba1 100644 --- a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java +++ b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java @@ -5,6 +5,7 @@ /** * This annotation drops all previously created entities, when the annotated repository is created. * CAUTION: This will delete all entities permanently! + * See documentation: <a href="https://koboo.gitbook.io/en2do/repository-options/dropentitiesonstart">...</a> */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java index d21f25c9..b8f8d4d9 100644 --- a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java +++ b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java @@ -5,6 +5,7 @@ /** * This annotation drops all previously created indexes, when the annotated repository is created. * CAUTION: This will delete all indexes permanently! + * See documentation: <a href="https://koboo.gitbook.io/en2do/repository-options/dropindexesonstart">...</a> */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/src/main/java/eu/koboo/en2do/repository/Repository.java b/src/main/java/eu/koboo/en2do/repository/Repository.java index ee1bf59f..5c90c7dd 100644 --- a/src/main/java/eu/koboo/en2do/repository/Repository.java +++ b/src/main/java/eu/koboo/en2do/repository/Repository.java @@ -7,6 +7,8 @@ /** * The default Repository interface, which predefines several useful methods. + * See documentation: <a href="https://koboo.gitbook.io/en2do/methods/predefined-methods">...</a> + * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-repository">...</a> * @param <E> The generic type of the Entity * @param <ID> The generic type of the field annotated with "@Id" in the Entity */ diff --git a/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java b/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java index b444a458..bb091cf7 100644 --- a/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java +++ b/src/main/java/eu/koboo/en2do/repository/SeparateEntityId.java @@ -9,6 +9,7 @@ * This annotation separates the "_id" field of the mongodb document and the "@Id" annotated field of the * entity. If this annotation is NOT used on the repository, the "@Id" field can't be annotated with "@NonIndex", that * will throw an exception. + * See documentation: <a href="https://koboo.gitbook.io/en2do/repository-options/separateentityid">...</a> */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/src/main/java/eu/koboo/en2do/repository/entity/Id.java b/src/main/java/eu/koboo/en2do/repository/entity/Id.java index b8d24045..8c3761e9 100644 --- a/src/main/java/eu/koboo/en2do/repository/entity/Id.java +++ b/src/main/java/eu/koboo/en2do/repository/entity/Id.java @@ -2,6 +2,10 @@ import java.lang.annotation.*; +/** + * This annotation defines the unique identifier of the entity. + * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/index/identifier-index">...</a> + */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) diff --git a/src/main/java/eu/koboo/en2do/repository/entity/NonIndex.java b/src/main/java/eu/koboo/en2do/repository/entity/NonIndex.java index 8f266bff..bfb5bf29 100644 --- a/src/main/java/eu/koboo/en2do/repository/entity/NonIndex.java +++ b/src/main/java/eu/koboo/en2do/repository/entity/NonIndex.java @@ -2,6 +2,9 @@ import java.lang.annotation.*; +/** + * This annotation disables the creating of the unique index of the "@Id" field. + */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) diff --git a/src/main/java/eu/koboo/en2do/repository/entity/TransformField.java b/src/main/java/eu/koboo/en2do/repository/entity/TransformField.java index e502dfc7..f920b059 100644 --- a/src/main/java/eu/koboo/en2do/repository/entity/TransformField.java +++ b/src/main/java/eu/koboo/en2do/repository/entity/TransformField.java @@ -2,10 +2,17 @@ import java.lang.annotation.*; +/** + * This annotation "renames" a field in the mongodb document, to the name of the value attribute. + * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/transformfield">...</a> + */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface TransformField { + /** + * @return The name of the field in the document. + */ String value(); } diff --git a/src/main/java/eu/koboo/en2do/repository/entity/Transient.java b/src/main/java/eu/koboo/en2do/repository/entity/Transient.java index 069748e6..6353c433 100644 --- a/src/main/java/eu/koboo/en2do/repository/entity/Transient.java +++ b/src/main/java/eu/koboo/en2do/repository/entity/Transient.java @@ -2,6 +2,11 @@ import java.lang.annotation.*; +/** + * This annotation sets a field "ignored" by the database. All fields with this field, aren't saved to + * the document of the entity. The value of the field will get lost, by saving and getting it from the database. + * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/transient">...</a> + */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) diff --git a/src/main/java/eu/koboo/en2do/repository/entity/compound/CompoundIndexArray.java b/src/main/java/eu/koboo/en2do/repository/entity/compound/CompoundIndexArray.java index 7c777893..da2397e0 100644 --- a/src/main/java/eu/koboo/en2do/repository/entity/compound/CompoundIndexArray.java +++ b/src/main/java/eu/koboo/en2do/repository/entity/compound/CompoundIndexArray.java @@ -2,10 +2,16 @@ import java.lang.annotation.*; +/** + * This annotation is used to create an array of the @CompoundIndex annotation. + */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface CompoundIndexArray { + /** + * @return The array of the @CompoundIndex annotations. + */ CompoundIndex[] value(); } diff --git a/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndex.java b/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndex.java index 6aa6d06d..135e0897 100644 --- a/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndex.java +++ b/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndex.java @@ -3,6 +3,12 @@ import java.lang.annotation.*; import java.util.concurrent.TimeUnit; +/** + * This annotation allows setting time-tp-live on specific fields of type "java.util.Date". MongoDB will delete + * them by itself, so the application doesn't need a repeating task other something similar, to check for the time value + * of the given field. + * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/index/ttl-index">...</a> + */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) diff --git a/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndexArray.java b/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndexArray.java index 52fc2418..8847e69b 100644 --- a/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndexArray.java +++ b/src/main/java/eu/koboo/en2do/repository/entity/ttl/TTLIndexArray.java @@ -2,10 +2,16 @@ import java.lang.annotation.*; +/** + * This annotation is used to create an array of the @TTLIndex annotation. + */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface TTLIndexArray { + /** + * @return The array of the @TTLIndex annotations. + */ TTLIndex[] value(); } diff --git a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java index 1571fb9e..3306683f 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java @@ -10,6 +10,7 @@ /** * This object is used to provide simplified pagination in several repositories. + * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/pagination">...</a> */ @Getter @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java index 1de7229f..7f9df5c5 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Limit.java @@ -7,6 +7,7 @@ /** * This annotation is used to limit the amount of the returned entities in the List. + * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/sorting/sorting-by-annotation">...</a> */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java index 2b7f5422..44166b55 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Skip.java @@ -7,6 +7,7 @@ /** * This annotation is used to skip the defined amount of entities by the given sorting. + * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/sorting/sorting-by-annotation">...</a> */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java index 62843937..754c2a09 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java @@ -9,6 +9,7 @@ /** * This object is used to enable dynamic sorting, without defining the sorting options statically through annotations. + * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/sorting/sorting-by-parameter">...</a> */ @Getter @FieldDefaults(level = AccessLevel.PRIVATE) diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java index a27d945a..6a224ae2 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortBy.java @@ -4,6 +4,7 @@ /** * This annotation is used to define the sorting of the given fields. + * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/sorting/sorting-by-annotation">...</a> */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java index 31014e0f..0496ea67 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/SortByArray.java @@ -7,6 +7,7 @@ /** * This annotation is used to create an array of the @SortBy annotation. + * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/sorting/sorting-by-annotation">...</a> */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) diff --git a/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java b/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java index 9309e1dd..8ff5ee69 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/transform/Transform.java @@ -9,6 +9,7 @@ * This annotation is used to "rename" a method name of the repository. * If you use this annotation, keep in mind, that the validation uses the * value of the annotation instead of the method name itself. + * See documentation: <a href="https://koboo.gitbook.io/en2do/usage/transform">...</a> */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) From 942e5ad726cce3b0c64839993092907be50856f3 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Fri, 27 Jan 2023 19:48:39 +0100 Subject: [PATCH 06/19] Delete unused ObjectIdUtils --- .../eu/koboo/en2do/utility/ObjectIdUtils.java | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 src/main/java/eu/koboo/en2do/utility/ObjectIdUtils.java diff --git a/src/main/java/eu/koboo/en2do/utility/ObjectIdUtils.java b/src/main/java/eu/koboo/en2do/utility/ObjectIdUtils.java deleted file mode 100644 index 9fadae7c..00000000 --- a/src/main/java/eu/koboo/en2do/utility/ObjectIdUtils.java +++ /dev/null @@ -1,18 +0,0 @@ -package eu.koboo.en2do.utility; - -import lombok.experimental.UtilityClass; -import org.bson.types.ObjectId; - -@UtilityClass -public class ObjectIdUtils { - - public ObjectId of(Object object) { - if (object instanceof ObjectId objectId) { - return objectId; - } - if (object instanceof String string) { - return new ObjectId(string); - } - return new ObjectId(String.valueOf(object)); - } -} From dcca06c0dfeb5037b378839ec3f1e2168d65e0c8 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Fri, 27 Jan 2023 19:49:54 +0100 Subject: [PATCH 07/19] Optimize imports + Reformat code --- src/main/java/eu/koboo/en2do/Credentials.java | 3 ++- .../en2do/internal/codec/lang/ClassCodec.java | 7 +++++-- .../internal/codec/map/GenericMapCodec.java | 1 + .../en2do/repository/AppendMethodAsComment.java | 5 ++++- .../eu/koboo/en2do/repository/Collection.java | 5 ++++- .../en2do/repository/DropEntitiesOnStart.java | 5 ++++- .../en2do/repository/DropIndexesOnStart.java | 5 ++++- .../eu/koboo/en2do/repository/Repository.java | 17 ++++++++++++++++- .../methods/pagination/Pagination.java | 4 ++++ .../en2do/repository/methods/sort/Sort.java | 5 +++++ 10 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/main/java/eu/koboo/en2do/Credentials.java b/src/main/java/eu/koboo/en2do/Credentials.java index 0985addf..a45e567d 100644 --- a/src/main/java/eu/koboo/en2do/Credentials.java +++ b/src/main/java/eu/koboo/en2do/Credentials.java @@ -11,8 +11,9 @@ /** * This object is used to simplify creating credentials to the mongodb server. * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-mongomanager">...</a> + * * @param connectString The connection string to the mongodb database server - * @param database The database, which should be used + * @param database The database, which should be used */ @SuppressWarnings("unused") public record Credentials(String connectString, String database) { diff --git a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java index 32a97887..9a1b971e 100644 --- a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java +++ b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java @@ -15,8 +15,9 @@ public class ClassCodec implements Codec<Class> { /** * See org.bson.codecs.Encoder - * @param writer the BSON writer to encode into - * @param value the value to encode + * + * @param writer the BSON writer to encode into + * @param value the value to encode * @param encoderContext the encoder context */ @Override @@ -26,6 +27,7 @@ public void encode(BsonWriter writer, Class value, EncoderContext encoderContext /** * See org.bson.codecs.Decoder + * * @param reader the BSON reader * @param decoderContext the decoder context * @return the decoded Class @@ -42,6 +44,7 @@ public Class decode(BsonReader reader, DecoderContext decoderContext) { /** * See org.bson.codecs.Encoder + * * @return the class of the encoded class */ @Override diff --git a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java index 5505403a..f331dff9 100644 --- a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java +++ b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java @@ -21,6 +21,7 @@ /** * This codec is used to allow different types as map keys, because * mongodb pojo-codec only supports strings as map keys. + * * @param <K> The type of the key of the generic map * @param <T> The type of the value of the generic map */ diff --git a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java index b52b3edf..7ad8d8c9 100644 --- a/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java +++ b/src/main/java/eu/koboo/en2do/repository/AppendMethodAsComment.java @@ -1,6 +1,9 @@ package eu.koboo.en2do.repository; -import java.lang.annotation.*; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * This annotation appends the repository method name to the mongodb find queries. diff --git a/src/main/java/eu/koboo/en2do/repository/Collection.java b/src/main/java/eu/koboo/en2do/repository/Collection.java index d82bc5ae..193a71a2 100644 --- a/src/main/java/eu/koboo/en2do/repository/Collection.java +++ b/src/main/java/eu/koboo/en2do/repository/Collection.java @@ -1,6 +1,9 @@ package eu.koboo.en2do.repository; -import java.lang.annotation.*; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * This annotation defines the collection name of the repository in the mongodb. diff --git a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java index d2acdba1..c5cbadac 100644 --- a/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java +++ b/src/main/java/eu/koboo/en2do/repository/DropEntitiesOnStart.java @@ -1,6 +1,9 @@ package eu.koboo.en2do.repository; -import java.lang.annotation.*; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * This annotation drops all previously created entities, when the annotated repository is created. diff --git a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java index b8f8d4d9..d9982554 100644 --- a/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java +++ b/src/main/java/eu/koboo/en2do/repository/DropIndexesOnStart.java @@ -1,6 +1,9 @@ package eu.koboo.en2do.repository; -import java.lang.annotation.*; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * This annotation drops all previously created indexes, when the annotated repository is created. diff --git a/src/main/java/eu/koboo/en2do/repository/Repository.java b/src/main/java/eu/koboo/en2do/repository/Repository.java index 5c90c7dd..f24614df 100644 --- a/src/main/java/eu/koboo/en2do/repository/Repository.java +++ b/src/main/java/eu/koboo/en2do/repository/Repository.java @@ -9,7 +9,8 @@ * The default Repository interface, which predefines several useful methods. * See documentation: <a href="https://koboo.gitbook.io/en2do/methods/predefined-methods">...</a> * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-repository">...</a> - * @param <E> The generic type of the Entity + * + * @param <E> The generic type of the Entity * @param <ID> The generic type of the field annotated with "@Id" in the Entity */ @SuppressWarnings("unused") @@ -17,12 +18,14 @@ public interface Repository<E, ID> { /** * This method counts all documents of the collection in the mongodb. + * * @return The amount of total entities in this repository. */ long countAll(); /** * This method deletes the given entity, by filtering with the entity's "@Id" field/unique identifier. + * * @param entity The entity, which should be deleted. * @return true, if the entity was deleted successfully. */ @@ -30,6 +33,7 @@ public interface Repository<E, ID> { /** * This method deletes all entities of the given list, filtering like the "#delete(E entity)" method. + * * @param entityList The List with the entities, which should be deleted. * @return true, if all entities were deleted successfully. */ @@ -37,6 +41,7 @@ public interface Repository<E, ID> { /** * This method deletes the entity with the given identifier, filtering like the "#delete(E entity)" method. + * * @param identifier The unique identifier of the entity, which should be deleted. * @return true, if the entity was deleted successfully. */ @@ -44,6 +49,7 @@ public interface Repository<E, ID> { /** * Drops / deletes all entities of the repository. + * * @return true, if all entities were deleted successfully. */ boolean drop(); @@ -51,6 +57,7 @@ public interface Repository<E, ID> { /** * Checks if the given entity exists in the repository, by filtering with the entity's * "@Id" field/unique identifier. + * * @param entity The entity, which should be checked. * @return true, if the entity exists in the collection. */ @@ -58,6 +65,7 @@ public interface Repository<E, ID> { /** * Checks if an entity with the given unique identifier exists in the repository, like the "#exists(E entity)" method. + * * @param identifier The identifier of the entity, which should be checked. * @return true, if an entity with the given identifier exists in the collection. */ @@ -65,6 +73,7 @@ public interface Repository<E, ID> { /** * Finds all entities of the collection + * * @return A List with all entities of the repository. */ List<E> findAll(); @@ -72,6 +81,7 @@ public interface Repository<E, ID> { /** * Find the first entity with the given unique identifier. * If the entity is not found, "null" is returned. + * * @param identifier The unique identifier of the entity, which is used to filter. * @return The found entity, if it exists, or "null" if it not exists. */ @@ -95,6 +105,7 @@ public interface Repository<E, ID> { /** * This method is used to get the unique identifier of the given entity. * If the entity doesn't have a unique identifier, a NullPointerException is thrown. + * * @param entity The entity, which unique identifier, should be returned * @return The unique identifier of the given entity. */ @@ -102,6 +113,7 @@ public interface Repository<E, ID> { /** * This method applies the pagination of all entities of the repository. + * * @param pagination The pagination, which is used to page the entities. * @return A List with the paged entities. */ @@ -111,6 +123,7 @@ public interface Repository<E, ID> { * Saves the given entity to the database. * If the entity exists, the existing document is updated. * If the entity doesn't exist, a new document is created. + * * @param entity The entity, which should be saved. * @return true, if the entity was successfully saved. */ @@ -118,6 +131,7 @@ public interface Repository<E, ID> { /** * Saves all entities of the given List to the database. + * * @param entityList A List of the entities, which should be saved * @return true, if the entities were successfully saved. */ @@ -125,6 +139,7 @@ public interface Repository<E, ID> { /** * This method applies the Sort object of all entities of the repository. + * * @param sort The Sort object, which should be used to sort all entities. * @return A List with the sorted entities. */ diff --git a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java index 3306683f..aca46ebd 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/pagination/Pagination.java @@ -18,6 +18,7 @@ public class Pagination { /** * Use this method to create a new pagination object. + * * @param entitiesPerPage Sets the maximum entities per one page. * @return The created Pagination object */ @@ -38,6 +39,7 @@ private Pagination(int entitiesPerPage) { /** * Use this method to define the order / sorting by the given fields + * * @param fieldName The field which is used to sort * @param ascending The direction of the sorting * @return The used Pagination object @@ -50,6 +52,7 @@ public Pagination order(String fieldName, boolean ascending) { /** * Use this method to define the order / sorting of the pagination, * but sets the ascending value to "true" + * * @param fieldName The field which is used to sort * @return The used Pagination object */ @@ -60,6 +63,7 @@ public Pagination order(String fieldName) { /** * Use this method to set the returned page. If the page doesn't exist, * the method will just return an empty list. + * * @param page The requested page * @return The used Pagination object */ diff --git a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java index 754c2a09..6f4b4381 100644 --- a/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java +++ b/src/main/java/eu/koboo/en2do/repository/methods/sort/Sort.java @@ -22,6 +22,7 @@ public static Sort create() { /** * Use this method to create a new Sort object + * * @return The new created sort object. */ public static Sort of() { @@ -40,6 +41,7 @@ private Sort() { /** * Use this method to define the order / sorting by the given fields + * * @param fieldName The field which is used to sort * @param ascending The direction of the sorting * @return The used Sort object @@ -52,6 +54,7 @@ public Sort order(String fieldName, boolean ascending) { /** * Use this method to define the order / sorting by the given fields, * but sets the ascending value to "true" + * * @param fieldName The field which is used to sort * @return The used Sort object */ @@ -61,6 +64,7 @@ public Sort order(String fieldName) { /** * Use this method to set the limit of entities of the current sorting. + * * @param limit The amount of the entities in the returned List. * @return The used Sort object */ @@ -71,6 +75,7 @@ public Sort limit(int limit) { /** * Use this method to set the skipped entities of the current sorting. + * * @param skip The amount of the entities, which should be skipped, before creating the List. * @return The used Sort object */ From 93bce409e470755736a804d04c536f7db87dcd86 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Fri, 27 Jan 2023 19:57:37 +0100 Subject: [PATCH 08/19] Add javadocs to utility classes --- .../eu/koboo/en2do/utility/AnnotationUtils.java | 12 ++++++++++++ .../java/eu/koboo/en2do/utility/DateUtils.java | 3 +++ .../java/eu/koboo/en2do/utility/EntityUtils.java | 9 +++++++++ .../java/eu/koboo/en2do/utility/FieldUtils.java | 15 +++++++++++++++ .../java/eu/koboo/en2do/utility/GenericUtils.java | 3 +++ 5 files changed, 42 insertions(+) diff --git a/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java b/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java index 3046f1a6..347bb8b4 100644 --- a/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java +++ b/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java @@ -7,9 +7,21 @@ import java.util.HashSet; import java.util.Set; +/** + * A utility class for everything related to annotations + */ @UtilityClass public class AnnotationUtils { + /** + * This method is ued to get all annotations from an entity class, using while loop, + * to iterate through all super-types. + * @param entityClass The class, which should be scanned. + * @param annotationClass the searched annotation + * @return The Set with all found annotations of type A + * @param <E> The generic type of the Class + * @param <A> The generic type of the annotation Class + */ public <E, A extends Annotation> Set<A> collectAnnotations(Class<E> entityClass, Class<A> annotationClass) { Set<A> annotationSet = new HashSet<>(); Class<?> clazz = entityClass; diff --git a/src/main/java/eu/koboo/en2do/utility/DateUtils.java b/src/main/java/eu/koboo/en2do/utility/DateUtils.java index 2058d787..ddf68576 100644 --- a/src/main/java/eu/koboo/en2do/utility/DateUtils.java +++ b/src/main/java/eu/koboo/en2do/utility/DateUtils.java @@ -10,6 +10,9 @@ import java.util.TimeZone; import java.util.concurrent.TimeUnit; +/** + * A utility class for working with "java.util.Date". + */ @UtilityClass @SuppressWarnings("unused") public class DateUtils { diff --git a/src/main/java/eu/koboo/en2do/utility/EntityUtils.java b/src/main/java/eu/koboo/en2do/utility/EntityUtils.java index 51e62f3b..e169f2d0 100644 --- a/src/main/java/eu/koboo/en2do/utility/EntityUtils.java +++ b/src/main/java/eu/koboo/en2do/utility/EntityUtils.java @@ -10,9 +10,18 @@ import java.util.Arrays; import java.util.List; +/** + * A utility class for everything related to entity properties. + */ @UtilityClass public class EntityUtils { + /** + * This method is used to copy all field values from one entity to another. + * It also works with inheritance. + * @param from The entity to copy from + * @param to The entity to copy to + */ public void copyProperties(Object from, Object to) { Class<?> fromClass = from.getClass(); Class<?> toClass = to.getClass(); diff --git a/src/main/java/eu/koboo/en2do/utility/FieldUtils.java b/src/main/java/eu/koboo/en2do/utility/FieldUtils.java index 293c2612..8264bb81 100644 --- a/src/main/java/eu/koboo/en2do/utility/FieldUtils.java +++ b/src/main/java/eu/koboo/en2do/utility/FieldUtils.java @@ -7,9 +7,18 @@ import java.util.HashSet; import java.util.Set; +/** + * A utility class for everything related to fields. + */ @UtilityClass public class FieldUtils { + /** + * This method is used to scan a class for all fields. + * @param typeClass The class, which should be scanned + * @return The Set with all found fields of the given class. + * @param <E> The generic type of the class + */ public <E> Set<Field> collectFields(Class<E> typeClass) { Set<Field> fields = new HashSet<>(); Class<?> clazz = typeClass; @@ -24,6 +33,12 @@ public <E> Set<Field> collectFields(Class<E> typeClass) { return fields; } + /** + * This method is used to iterate through a set of fields and search for a field by its name. + * @param fieldName The field name, which should be searched. + * @param fieldSet The Set, which should be iterated through + * @return The field, if found. If not found, it returns "null" + */ public Field findFieldByName(String fieldName, Set<Field> fieldSet) { for (Field field : fieldSet) { if (!field.getName().equalsIgnoreCase(fieldName)) { diff --git a/src/main/java/eu/koboo/en2do/utility/GenericUtils.java b/src/main/java/eu/koboo/en2do/utility/GenericUtils.java index a3f25905..5990d982 100644 --- a/src/main/java/eu/koboo/en2do/utility/GenericUtils.java +++ b/src/main/java/eu/koboo/en2do/utility/GenericUtils.java @@ -7,6 +7,9 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; +/** + * A utility class for everything related to generic types or class types. + */ @UtilityClass public class GenericUtils { From 12d3c74c16f2bfda66e4d700f0f4d721a0e47cc6 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Sat, 28 Jan 2023 16:35:52 +0100 Subject: [PATCH 09/19] Rename methods of GenericUtils to better match use-case --- src/main/java/eu/koboo/en2do/utility/GenericUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/koboo/en2do/utility/GenericUtils.java b/src/main/java/eu/koboo/en2do/utility/GenericUtils.java index 5990d982..da6de4c7 100644 --- a/src/main/java/eu/koboo/en2do/utility/GenericUtils.java +++ b/src/main/java/eu/koboo/en2do/utility/GenericUtils.java @@ -13,13 +13,13 @@ @UtilityClass public class GenericUtils { - public Class<?> getGenericTypeOfReturnList(Method method) { + public Class<?> getGenericTypeOfReturnType(Method method) { Type returnType = method.getGenericReturnType(); ParameterizedType type = (ParameterizedType) returnType; return (Class<?>) type.getActualTypeArguments()[0]; } - public Class<?> getGenericTypeOfParameterList(Method method, int paramIndex) { + public Class<?> getGenericTypeOfParameter(Method method, int paramIndex) { Parameter parameter = method.getParameters()[paramIndex]; Type parameterType = parameter.getParameterizedType(); ParameterizedType type = (ParameterizedType) parameterType; From 9d3a1e959e9a085d99806539ff37234341554cb1 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Sat, 28 Jan 2023 17:02:48 +0100 Subject: [PATCH 10/19] Create @Async annotation to mark methods async --- .../koboo/en2do/repository/methods/async/Async.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/eu/koboo/en2do/repository/methods/async/Async.java diff --git a/src/main/java/eu/koboo/en2do/repository/methods/async/Async.java b/src/main/java/eu/koboo/en2do/repository/methods/async/Async.java new file mode 100644 index 00000000..3cf38163 --- /dev/null +++ b/src/main/java/eu/koboo/en2do/repository/methods/async/Async.java @@ -0,0 +1,12 @@ +package eu.koboo.en2do.repository.methods.async; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Async { + +} From 5b0de78e55a2279497adaa4bead3c0fda97ff67d Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Sat, 28 Jan 2023 17:03:06 +0100 Subject: [PATCH 11/19] Update validation for async methods --- .../java/eu/koboo/en2do/MongoManager.java | 34 +++++++++++++++---- .../MethodInvalidAsyncNameException.java | 15 ++++++++ .../MethodInvalidAsyncReturnException.java | 14 ++++++++ 3 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncNameException.java create mode 100644 src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncReturnException.java diff --git a/src/main/java/eu/koboo/en2do/MongoManager.java b/src/main/java/eu/koboo/en2do/MongoManager.java index 5f414612..7f3dfe71 100644 --- a/src/main/java/eu/koboo/en2do/MongoManager.java +++ b/src/main/java/eu/koboo/en2do/MongoManager.java @@ -21,15 +21,14 @@ import eu.koboo.en2do.internal.methods.operators.FilterOperator; import eu.koboo.en2do.internal.methods.operators.MethodOperator; import eu.koboo.en2do.internal.methods.predefined.impl.*; +import eu.koboo.en2do.repository.*; import eu.koboo.en2do.repository.Collection; -import eu.koboo.en2do.repository.DropEntitiesOnStart; -import eu.koboo.en2do.repository.DropIndexesOnStart; -import eu.koboo.en2do.repository.Repository; import eu.koboo.en2do.repository.entity.Id; import eu.koboo.en2do.repository.entity.NonIndex; import eu.koboo.en2do.repository.entity.compound.CompoundIndex; import eu.koboo.en2do.repository.entity.compound.Index; import eu.koboo.en2do.repository.entity.ttl.TTLIndex; +import eu.koboo.en2do.repository.methods.async.Async; import eu.koboo.en2do.repository.methods.pagination.Pagination; import eu.koboo.en2do.repository.methods.sort.*; import eu.koboo.en2do.repository.methods.transform.Transform; @@ -50,6 +49,7 @@ import java.lang.reflect.Proxy; import java.lang.reflect.Type; import java.util.*; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; @@ -238,7 +238,7 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) { MongoCollection<E> entityCollection = database.getCollection(entityCollectionName, entityClass); - RepositoryMeta<E, ID, R> repositoryMeta = new RepositoryMeta<>( + RepositoryMeta<E, ID, R> repositoryMeta = new RepositoryMeta<>(this, repositoryClass, entityClass, entityFieldSet, entityUniqueIdClass, entityUniqueIdField, @@ -273,11 +273,13 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) { for (Method method : repositoryClass.getMethods()) { String methodName = method.getName(); + // Apply transform annotation Transform transform = method.getAnnotation(Transform.class); if (transform != null) { methodName = transform.value(); } + // Check if we catch a predefined method if (repositoryMeta.isRepositoryMethod(methodName)) { continue; } @@ -286,9 +288,29 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) { if (IGNORED_DEFAULT_METHODS.contains(methodName)) { continue; } - // Check for the return-types of the methods, and their defined names to match our pattern. + + // Get the default return type of the method Class<?> returnType = method.getReturnType(); + // Check if the method is async and if so, check for completable future return type. + boolean isAsyncMethod = method.isAnnotationPresent(Async.class); + if(isAsyncMethod) { + // Check async method name + if(methodName.startsWith("async")) { + String predefinedName = repositoryMeta.getPredefinedNameByAsyncName(methodName); + if(repositoryMeta.isRepositoryMethod(predefinedName)) { + continue; + } + throw new MethodInvalidAsyncNameException(method, repositoryClass); + } + // Check CompletableFuture return type + if(GenericUtils.isNotTypeOf(returnType, CompletableFuture.class)) { + throw new MethodInvalidAsyncReturnException(method, repositoryClass); + } + returnType = GenericUtils.getGenericTypeOfReturnType(method); + } + + // Parse the MethodOperator by the methodName MethodOperator methodOperator = MethodOperator.parseMethodStartsWith(methodName); if (methodOperator == null) { @@ -341,7 +363,7 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) { if (GenericUtils.isNotTypeOf(List.class, paramClass)) { throw new MethodMismatchingTypeException(method, repositoryClass, List.class, paramClass); } - Class<?> listType = GenericUtils.getGenericTypeOfParameterList(method, paramIndex); + Class<?> listType = GenericUtils.getGenericTypeOfParameter(method, paramIndex); if (GenericUtils.isNotTypeOf(fieldClass, listType)) { throw new MethodInvalidListParameterException(method, repositoryClass, fieldClass, listType); } diff --git a/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncNameException.java b/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncNameException.java new file mode 100644 index 00000000..523f39cc --- /dev/null +++ b/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncNameException.java @@ -0,0 +1,15 @@ +package eu.koboo.en2do.internal.exception.methods; + +import eu.koboo.en2do.repository.methods.async.Async; + +import java.lang.reflect.Method; + +public class MethodInvalidAsyncNameException extends Exception { + + public MethodInvalidAsyncNameException(Method method, Class<?> repoClass) { + super("Methods, which start with the keyword \"async\" are not allowed in repository, except the predefined methods " + + "of the repository itself. If you want to create \"async\" methods, just annotate any method with " + Async.class + + " and encapsulate the return type in a CompletableFuture<T>. Invalid method is \"" + method.getName() + "\"" + + " in repository " + repoClass.getName()); + } +} diff --git a/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncReturnException.java b/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncReturnException.java new file mode 100644 index 00000000..8ecae72d --- /dev/null +++ b/src/main/java/eu/koboo/en2do/internal/exception/methods/MethodInvalidAsyncReturnException.java @@ -0,0 +1,14 @@ +package eu.koboo.en2do.internal.exception.methods; + +import eu.koboo.en2do.repository.methods.async.Async; + +import java.lang.reflect.Method; + +public class MethodInvalidAsyncReturnException extends Exception { + + public MethodInvalidAsyncReturnException(Method method, Class<?> repoClass) { + super("Methods, which are annotated with " + Async.class + " have to return a CompletableFuture<T> with their " + + " encapsulate return type as T. Invalid method is \"" + method.getName() + "\"" + + " in repository " + repoClass.getName()); + } +} From 972daba80075634fe550042d5db72c92d998a8a6 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Sat, 28 Jan 2023 17:04:24 +0100 Subject: [PATCH 12/19] Handle async method invocation --- .../koboo/en2do/internal/MethodCallable.java | 6 +++ .../internal/RepositoryInvocationHandler.java | 48 +++++++++++++++++-- .../koboo/en2do/internal/RepositoryMeta.java | 15 ++++-- 3 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 src/main/java/eu/koboo/en2do/internal/MethodCallable.java diff --git a/src/main/java/eu/koboo/en2do/internal/MethodCallable.java b/src/main/java/eu/koboo/en2do/internal/MethodCallable.java new file mode 100644 index 00000000..2b81a1bb --- /dev/null +++ b/src/main/java/eu/koboo/en2do/internal/MethodCallable.java @@ -0,0 +1,6 @@ +package eu.koboo.en2do.internal; + +public interface MethodCallable { + + Object call() throws Exception; +} diff --git a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java index ee0044fb..7632e11a 100644 --- a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java +++ b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java @@ -3,10 +3,10 @@ import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCollection; import eu.koboo.en2do.internal.exception.methods.MethodUnsupportedException; -import eu.koboo.en2do.internal.exception.repository.RepositoryInvalidCallException; import eu.koboo.en2do.internal.methods.dynamic.DynamicMethod; import eu.koboo.en2do.internal.methods.predefined.PredefinedMethod; import eu.koboo.en2do.repository.Repository; +import eu.koboo.en2do.repository.methods.async.Async; import eu.koboo.en2do.repository.methods.transform.Transform; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -16,6 +16,7 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) @AllArgsConstructor @@ -26,12 +27,14 @@ public class RepositoryInvocationHandler<E, ID, R extends Repository<E, ID>> imp @Override @SuppressWarnings("all") public Object invoke(Object proxy, Method method, Object[] arguments) throws Throwable { - String methodName = method.getName(); + // Create value of the final methodName + String tempMethodName = method.getName(); Transform transform = method.getAnnotation(Transform.class); if (transform != null) { - methodName = transform.value(); + tempMethodName = transform.value(); } + String methodName = tempMethodName; // Get and check if a static handler for the methodName is available. PredefinedMethod<E, ID, R> methodHandler = repositoryMeta.lookupPredefinedMethod(methodName); @@ -41,6 +44,19 @@ public Object invoke(Object proxy, Method method, Object[] arguments) throws Thr } // No static handler found. + // Check for predefined method with async prefix. + boolean isAsyncMethod = method.isAnnotationPresent(Async.class); + if (transform == null && isAsyncMethod) { + String predefinedName = repositoryMeta.getPredefinedNameByAsyncName(methodName); + PredefinedMethod<E, ID, R> methodHandlerFuture = repositoryMeta.lookupPredefinedMethod(predefinedName); + if (methodHandlerFuture != null) { + // Just handle the arguments and return the object + CompletableFuture<Object> future = new CompletableFuture<>(); + executeFuture(future, () -> methodHandlerFuture.handle(method, arguments)); + return future; + } + } + // Get and check if any dynamic method matches the methodName DynamicMethod<E, ID, R> dynamicMethod = repositoryMeta.lookupDynamicMethod(methodName); if (dynamicMethod == null) { @@ -48,10 +64,22 @@ public Object invoke(Object proxy, Method method, Object[] arguments) throws Thr throw new MethodUnsupportedException(method, repositoryMeta.getRepositoryClass()); } + MethodCallable methodCallable = () -> executeMethod(dynamicMethod, arguments, method, methodName); + if(isAsyncMethod) { + CompletableFuture<Object> future = new CompletableFuture<>(); + executeFuture(future, methodCallable); + return future; + } else { + return methodCallable.call(); + } + } + + private Object executeMethod(DynamicMethod<E, ID, R> dynamicMethod, Object[] arguments, Method method, String methodName) throws Exception { // Generate bson filter by dynamic Method object. Bson filter = dynamicMethod.createBsonFilter(arguments); // Switch-case the method operator to use the correct mongo query. final MongoCollection<E> collection = repositoryMeta.getCollection(); + return switch (dynamicMethod.getMethodOperator()) { case COUNT -> collection.countDocuments(filter); case DELETE -> collection.deleteMany(filter).wasAcknowledged(); @@ -73,8 +101,18 @@ public Object invoke(Object proxy, Method method, Object[] arguments) throws Thr findIterable = repositoryMeta.applyPageObject(method, findIterable, arguments); yield findIterable.into(new ArrayList<>()); } - default -> // Couldn't find any match method operator - throw new RepositoryInvalidCallException(method, repositoryMeta.getRepositoryClass()); + // Couldn't find any match method operator, but that shouldn't happen }; } + + private void executeFuture(CompletableFuture<Object> future, MethodCallable callable) { + //TODO: Check for ExecutorService from manager + future.completeAsync(() -> { + try { + return callable.call(); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } } diff --git a/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java b/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java index 7b1ae8ac..d9a0a4e2 100644 --- a/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java +++ b/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java @@ -4,6 +4,7 @@ import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.model.Filters; +import eu.koboo.en2do.MongoManager; import eu.koboo.en2do.internal.exception.methods.MethodInvalidPageException; import eu.koboo.en2do.internal.exception.methods.MethodInvalidSortLimitException; import eu.koboo.en2do.internal.exception.methods.MethodInvalidSortSkipException; @@ -24,15 +25,13 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) @Getter public class RepositoryMeta<E, ID, R extends Repository<E, ID>> { + MongoManager mongoManager; String collectionName; MongoCollection<E> collection; @@ -54,10 +53,11 @@ public class RepositoryMeta<E, ID, R extends Repository<E, ID>> { @Getter(AccessLevel.NONE) Map<String, DynamicMethod<E, ID, R>> dynamicMethodRegistry; - public RepositoryMeta(Class<R> repositoryClass, Class<E> entityClass, + public RepositoryMeta(MongoManager mongoManager, Class<R> repositoryClass, Class<E> entityClass, Set<Field> entityFieldSet, Class<ID> entityUniqueIdClass, Field entityUniqueIdField, MongoCollection<E> collection, String collectionName) { + this.mongoManager = mongoManager; this.collectionName = collectionName; this.collection = collection; @@ -254,4 +254,9 @@ public FindIterable<E> applyPageObject(Method method, FindIterable<E> findIterab findIterable.allowDiskUse(true); return findIterable; } + + public String getPredefinedNameByAsyncName(String asyncName) { + String predefinedName = asyncName.replaceFirst("async", ""); + return predefinedName.substring(0, 1).toLowerCase(Locale.ROOT) + predefinedName.substring(1); + } } From 8a984155f76ba9ac35026dabb637acfed23e7f8e Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Sat, 28 Jan 2023 17:09:11 +0100 Subject: [PATCH 13/19] Create interface for async repositories --- .../en2do/repository/AsyncRepository.java | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/main/java/eu/koboo/en2do/repository/AsyncRepository.java diff --git a/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java b/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java new file mode 100644 index 00000000..a47ef4eb --- /dev/null +++ b/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java @@ -0,0 +1,111 @@ +package eu.koboo.en2do.repository; + +import eu.koboo.en2do.repository.methods.async.Async; +import eu.koboo.en2do.repository.methods.pagination.Pagination; +import eu.koboo.en2do.repository.methods.sort.Sort; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * The default Repository interface, which predefines several useful methods. + * See documentation: <a href="https://koboo.gitbook.io/en2do/methods/predefined-methods">...</a> + * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-repository">...</a> + * + * @param <E> The generic type of the Entity + * @param <ID> The generic type of the field annotated with "@Id" in the Entity + */ +@SuppressWarnings("unused") +public interface AsyncRepository<E, ID> { + + /** + * Async representation + * @see Repository#countAll() + */ + @Async + CompletableFuture<Long> asyncCountAll(); + + /** + * Async representation + * @see Repository#delete(Object) + */ + @Async + CompletableFuture<Boolean> asyncDelete(E entity); + + /** + * Async representation + * @see Repository#deleteAll(List) + */ + @Async + CompletableFuture<Boolean> asyncDeleteAll(List<E> entityList); + + /** + * Async representation + * @see Repository#deleteById(Object) + */ + @Async + CompletableFuture<Boolean> asyncDeleteById(ID identifier); + + /** + * Async representation + * @see Repository#drop() + */ + @Async + CompletableFuture<Boolean> asyncDrop(); + + /** + * Async representation + * @see Repository#exists(Object) + */ + @Async + CompletableFuture<Boolean> asyncExists(E entity); + + /** + * Async representation + * @see Repository#existsById(Object) + */ + @Async + CompletableFuture<Boolean> asyncExistsById(ID identifier); + + /** + * Async representation + * @see Repository#findAll() + */ + @Async + CompletableFuture<List<E>> asyncFindAll(); + + /** + * Async representation + * @see Repository#findFirstById(Object) + */ + @Async + CompletableFuture<E> asyncFindFirstById(ID identifier); + + /** + * Async representation + * @see Repository#pageAll(Pagination) + */ + @Async + CompletableFuture<List<E>> asyncPageAll(Pagination pagination); + + /** + * Async representation + * @see Repository#save(Object) + */ + @Async + CompletableFuture<Boolean> asyncSave(E entity); + + /** + * Async representation + * @see Repository#saveAll(List) + */ + @Async + CompletableFuture<Boolean> asyncSaveAll(List<E> entityList); + + /** + * Async representation + * @see Repository#sortAll(Sort) + */ + @Async + CompletableFuture<List<E>> asyncSortAll(Sort sort); +} From cf5c58aa99b88a044f9a1dbdf1a50658f64d2e10 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Sat, 28 Jan 2023 17:09:27 +0100 Subject: [PATCH 14/19] Refactor changes --- .../methods/operators/MethodOperator.java | 4 +- .../CustomerExtendedRepository.java | 12 ++-- ...xtendedFindFirstByFirstNameExistsTest.java | 56 +++++++++++++++++++ 3 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 src/test/java/eu/koboo/en2do/test/customerextended/tests/CustomerExtendedFindFirstByFirstNameExistsTest.java diff --git a/src/main/java/eu/koboo/en2do/internal/methods/operators/MethodOperator.java b/src/main/java/eu/koboo/en2do/internal/methods/operators/MethodOperator.java index 29b171c3..70c98bff 100644 --- a/src/main/java/eu/koboo/en2do/internal/methods/operators/MethodOperator.java +++ b/src/main/java/eu/koboo/en2do/internal/methods/operators/MethodOperator.java @@ -23,7 +23,7 @@ public enum MethodOperator { if (GenericUtils.isNotTypeOf(List.class, returnType)) { throw new MethodFindListReturnTypeException(method, entityClass, repoClass); } - Class<?> listType = GenericUtils.getGenericTypeOfReturnList(method); + Class<?> listType = GenericUtils.getGenericTypeOfReturnType(method); if (!listType.isAssignableFrom(entityClass)) { throw new MethodFindListTypeException(method, repoClass, listType); } @@ -47,7 +47,7 @@ public enum MethodOperator { if (GenericUtils.isNotTypeOf(List.class, returnType)) { throw new MethodFindListReturnTypeException(method, entityClass, repoClass); } - Class<?> listType = GenericUtils.getGenericTypeOfReturnList(method); + Class<?> listType = GenericUtils.getGenericTypeOfReturnType(method); if (!listType.isAssignableFrom(entityClass)) { throw new MethodFindListTypeException(method, repoClass, listType); } diff --git a/src/test/java/eu/koboo/en2do/test/customerextended/CustomerExtendedRepository.java b/src/test/java/eu/koboo/en2do/test/customerextended/CustomerExtendedRepository.java index dd5571c1..d394955d 100644 --- a/src/test/java/eu/koboo/en2do/test/customerextended/CustomerExtendedRepository.java +++ b/src/test/java/eu/koboo/en2do/test/customerextended/CustomerExtendedRepository.java @@ -1,16 +1,18 @@ package eu.koboo.en2do.test.customerextended; -import eu.koboo.en2do.repository.Collection; -import eu.koboo.en2do.repository.DropEntitiesOnStart; -import eu.koboo.en2do.repository.DropIndexesOnStart; -import eu.koboo.en2do.repository.Repository; +import eu.koboo.en2do.repository.*; +import eu.koboo.en2do.repository.methods.async.Async; import java.util.UUID; +import java.util.concurrent.CompletableFuture; @Collection("customer_extended_repository") @DropIndexesOnStart @DropEntitiesOnStart -public interface CustomerExtendedRepository extends Repository<CustomerExtended, UUID> { +public interface CustomerExtendedRepository extends Repository<CustomerExtended, UUID>, AsyncRepository<CustomerExtended, UUID> { CustomerExtended findFirstByFirstName(String firstName); + + @Async + CompletableFuture<CustomerExtended> findFirstByFirstNameExists(); } diff --git a/src/test/java/eu/koboo/en2do/test/customerextended/tests/CustomerExtendedFindFirstByFirstNameExistsTest.java b/src/test/java/eu/koboo/en2do/test/customerextended/tests/CustomerExtendedFindFirstByFirstNameExistsTest.java new file mode 100644 index 00000000..e0859616 --- /dev/null +++ b/src/test/java/eu/koboo/en2do/test/customerextended/tests/CustomerExtendedFindFirstByFirstNameExistsTest.java @@ -0,0 +1,56 @@ +package eu.koboo.en2do.test.customerextended.tests; + +import eu.koboo.en2do.test.Const; +import eu.koboo.en2do.test.customer.Customer; +import eu.koboo.en2do.test.customerextended.CustomerExtended; +import eu.koboo.en2do.test.customerextended.CustomerExtendedRepositoryTest; +import eu.koboo.en2do.utility.EntityUtils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +public class CustomerExtendedFindFirstByFirstNameExistsTest extends CustomerExtendedRepositoryTest { + + @Test + @Order(1) + public void cleanUpRepository() { + List<CustomerExtended> customerList = repository.findAll(); + assertNotNull(customerList); + assertTrue(customerList.isEmpty()); + } + + @Test + @Order(2) + public void saveCustomer() { + Customer customer = Const.createNewCustomer(); + CustomerExtended customerExtended = new CustomerExtended(); + EntityUtils.copyProperties(customer, customerExtended); + customerExtended.setOrderStatus("Ordered"); + customerExtended.setLockStatus("Not Locked"); + assertNotNull(customerExtended); + repository.asyncSave(customerExtended) + .thenAccept(Assertions::assertTrue) + .thenAccept(v -> repository.asyncExists(customerExtended).thenAccept(Assertions::assertTrue)); + } + + @Test + @Order(3) + public void operationTest() throws Exception { + repository.findFirstByFirstNameExists().thenAccept(customer -> { + assertNotNull(customer); + assertEquals("Ordered", customer.getOrderStatus()); + assertEquals("Not Locked", customer.getLockStatus()); + assertEquals(Const.CUSTOMER_ID, customer.getCustomerId()); + assertEquals(Const.FIRST_NAME, customer.getFirstName()); + assertEquals(Const.LAST_NAME, customer.getLastName()); + assertEquals(Const.BIRTHDAY, customer.getBirthday()); + assertEquals(Const.PHONE_NUMBER, customer.getPhoneNumber()); + assertEquals(Const.ORDERS.size(), customer.getOrders().size()); + }); + Thread.sleep(1000); + } +} From 66ebd30da360b91ec0ea47455ff1ecdfd50124b3 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Sat, 28 Jan 2023 17:09:52 +0100 Subject: [PATCH 15/19] Reformat code + Clean up code --- src/main/java/eu/koboo/en2do/MongoManager.java | 12 +++++++----- .../en2do/internal/RepositoryInvocationHandler.java | 2 +- .../eu/koboo/en2do/repository/AsyncRepository.java | 13 +++++++++++++ .../eu/koboo/en2do/utility/AnnotationUtils.java | 7 ++++--- .../java/eu/koboo/en2do/utility/EntityUtils.java | 3 ++- .../java/eu/koboo/en2do/utility/FieldUtils.java | 6 ++++-- 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/main/java/eu/koboo/en2do/MongoManager.java b/src/main/java/eu/koboo/en2do/MongoManager.java index 7f3dfe71..a413e21f 100644 --- a/src/main/java/eu/koboo/en2do/MongoManager.java +++ b/src/main/java/eu/koboo/en2do/MongoManager.java @@ -21,8 +21,10 @@ import eu.koboo.en2do.internal.methods.operators.FilterOperator; import eu.koboo.en2do.internal.methods.operators.MethodOperator; import eu.koboo.en2do.internal.methods.predefined.impl.*; -import eu.koboo.en2do.repository.*; import eu.koboo.en2do.repository.Collection; +import eu.koboo.en2do.repository.DropEntitiesOnStart; +import eu.koboo.en2do.repository.DropIndexesOnStart; +import eu.koboo.en2do.repository.Repository; import eu.koboo.en2do.repository.entity.Id; import eu.koboo.en2do.repository.entity.NonIndex; import eu.koboo.en2do.repository.entity.compound.CompoundIndex; @@ -294,17 +296,17 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) { // Check if the method is async and if so, check for completable future return type. boolean isAsyncMethod = method.isAnnotationPresent(Async.class); - if(isAsyncMethod) { + if (isAsyncMethod) { // Check async method name - if(methodName.startsWith("async")) { + if (methodName.startsWith("async")) { String predefinedName = repositoryMeta.getPredefinedNameByAsyncName(methodName); - if(repositoryMeta.isRepositoryMethod(predefinedName)) { + if (repositoryMeta.isRepositoryMethod(predefinedName)) { continue; } throw new MethodInvalidAsyncNameException(method, repositoryClass); } // Check CompletableFuture return type - if(GenericUtils.isNotTypeOf(returnType, CompletableFuture.class)) { + if (GenericUtils.isNotTypeOf(returnType, CompletableFuture.class)) { throw new MethodInvalidAsyncReturnException(method, repositoryClass); } returnType = GenericUtils.getGenericTypeOfReturnType(method); diff --git a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java index 7632e11a..8648c7c9 100644 --- a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java +++ b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java @@ -65,7 +65,7 @@ public Object invoke(Object proxy, Method method, Object[] arguments) throws Thr } MethodCallable methodCallable = () -> executeMethod(dynamicMethod, arguments, method, methodName); - if(isAsyncMethod) { + if (isAsyncMethod) { CompletableFuture<Object> future = new CompletableFuture<>(); executeFuture(future, methodCallable); return future; diff --git a/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java b/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java index a47ef4eb..e75c79d5 100644 --- a/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java +++ b/src/main/java/eu/koboo/en2do/repository/AsyncRepository.java @@ -20,6 +20,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#countAll() */ @Async @@ -27,6 +28,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#delete(Object) */ @Async @@ -34,6 +36,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#deleteAll(List) */ @Async @@ -41,6 +44,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#deleteById(Object) */ @Async @@ -48,6 +52,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#drop() */ @Async @@ -55,6 +60,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#exists(Object) */ @Async @@ -62,6 +68,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#existsById(Object) */ @Async @@ -69,6 +76,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#findAll() */ @Async @@ -76,6 +84,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#findFirstById(Object) */ @Async @@ -83,6 +92,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#pageAll(Pagination) */ @Async @@ -90,6 +100,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#save(Object) */ @Async @@ -97,6 +108,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#saveAll(List) */ @Async @@ -104,6 +116,7 @@ public interface AsyncRepository<E, ID> { /** * Async representation + * * @see Repository#sortAll(Sort) */ @Async diff --git a/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java b/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java index 347bb8b4..cc236067 100644 --- a/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java +++ b/src/main/java/eu/koboo/en2do/utility/AnnotationUtils.java @@ -16,11 +16,12 @@ public class AnnotationUtils { /** * This method is ued to get all annotations from an entity class, using while loop, * to iterate through all super-types. - * @param entityClass The class, which should be scanned. + * + * @param entityClass The class, which should be scanned. * @param annotationClass the searched annotation + * @param <E> The generic type of the Class + * @param <A> The generic type of the annotation Class * @return The Set with all found annotations of type A - * @param <E> The generic type of the Class - * @param <A> The generic type of the annotation Class */ public <E, A extends Annotation> Set<A> collectAnnotations(Class<E> entityClass, Class<A> annotationClass) { Set<A> annotationSet = new HashSet<>(); diff --git a/src/main/java/eu/koboo/en2do/utility/EntityUtils.java b/src/main/java/eu/koboo/en2do/utility/EntityUtils.java index e169f2d0..8ce57946 100644 --- a/src/main/java/eu/koboo/en2do/utility/EntityUtils.java +++ b/src/main/java/eu/koboo/en2do/utility/EntityUtils.java @@ -19,8 +19,9 @@ public class EntityUtils { /** * This method is used to copy all field values from one entity to another. * It also works with inheritance. + * * @param from The entity to copy from - * @param to The entity to copy to + * @param to The entity to copy to */ public void copyProperties(Object from, Object to) { Class<?> fromClass = from.getClass(); diff --git a/src/main/java/eu/koboo/en2do/utility/FieldUtils.java b/src/main/java/eu/koboo/en2do/utility/FieldUtils.java index 8264bb81..a91f7d39 100644 --- a/src/main/java/eu/koboo/en2do/utility/FieldUtils.java +++ b/src/main/java/eu/koboo/en2do/utility/FieldUtils.java @@ -15,9 +15,10 @@ public class FieldUtils { /** * This method is used to scan a class for all fields. + * * @param typeClass The class, which should be scanned + * @param <E> The generic type of the class * @return The Set with all found fields of the given class. - * @param <E> The generic type of the class */ public <E> Set<Field> collectFields(Class<E> typeClass) { Set<Field> fields = new HashSet<>(); @@ -35,8 +36,9 @@ public <E> Set<Field> collectFields(Class<E> typeClass) { /** * This method is used to iterate through a set of fields and search for a field by its name. + * * @param fieldName The field name, which should be searched. - * @param fieldSet The Set, which should be iterated through + * @param fieldSet The Set, which should be iterated through * @return The field, if found. If not found, it returns "null" */ public Field findFieldByName(String fieldName, Set<Field> fieldSet) { From e206f32dfab7f58b467ee5dc4581ead47326712c Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Sat, 28 Jan 2023 20:48:25 +0100 Subject: [PATCH 16/19] Add javadocs see to codec classes --- .../codec/InternalPropertyCodecProvider.java | 7 +++++++ .../en2do/internal/codec/lang/ClassCodec.java | 3 +-- .../internal/codec/map/GenericMapCodec.java | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java b/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java index 814ca85d..bef2a25d 100644 --- a/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java +++ b/src/main/java/eu/koboo/en2do/internal/codec/InternalPropertyCodecProvider.java @@ -16,6 +16,13 @@ @Log public class InternalPropertyCodecProvider implements PropertyCodecProvider { + /** + * @see PropertyCodecProvider + * @param type the class and bound type parameters for which to get a Codec + * @param registry the registry to use for resolving dependent Codec instances + * @return The codec from the type + * @param <T> The type of the codec + */ @Override @SuppressWarnings({"rawtypes", "unchecked"}) public <T> Codec<T> get(TypeWithTypeParameters<T> type, PropertyCodecRegistry registry) { diff --git a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java index 9a1b971e..400aebdd 100644 --- a/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java +++ b/src/main/java/eu/koboo/en2do/internal/codec/lang/ClassCodec.java @@ -43,8 +43,7 @@ public Class decode(BsonReader reader, DecoderContext decoderContext) { } /** - * See org.bson.codecs.Encoder - * + * @see org.bson.codecs.Encoder * @return the class of the encoded class */ @Override diff --git a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java index f331dff9..950878cb 100644 --- a/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java +++ b/src/main/java/eu/koboo/en2do/internal/codec/map/GenericMapCodec.java @@ -40,6 +40,12 @@ public GenericMapCodec(Class<Map<K, T>> encoderClass, Codec<K> keyCodec, Codec<T this.valueCodec = valueCodec; } + /** + * @see org.bson.codecs.Encoder + * @param writer the BSON writer to encode into + * @param map the value to encode + * @param encoderContext the encoder context + */ @Override public void encode(BsonWriter writer, Map<K, T> map, EncoderContext encoderContext) { try (BsonDocumentWriter documentWriter = new BsonDocumentWriter(new BsonDocument())) { @@ -70,6 +76,12 @@ public void encode(BsonWriter writer, Map<K, T> map, EncoderContext encoderConte writer.writeEndDocument(); } + /** + * @see org.bson.codecs.Decoder + * @param reader the BSON reader + * @param context the decoder context + * @return The decoded map instance + */ @Override @SuppressWarnings("unchecked") public Map<K, T> decode(BsonReader reader, DecoderContext context) { @@ -97,6 +109,10 @@ public Map<K, T> decode(BsonReader reader, DecoderContext context) { return map; } + /** + * Used to get a new instance of the saved map + * @return The new created map instance + */ private Map<K, T> getInstance() { if (encoderClass.isInterface()) { return new HashMap<>(); From b04d0adc086080dfc7ada874f535131a71fa9647 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Sat, 28 Jan 2023 21:48:15 +0100 Subject: [PATCH 17/19] Add parameter to MongoManager to allow custom ExecutorServices --- .../java/eu/koboo/en2do/MongoManager.java | 26 ++++++++++++++++--- .../internal/RepositoryInvocationHandler.java | 5 ++-- .../koboo/en2do/internal/RepositoryMeta.java | 5 +--- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/main/java/eu/koboo/en2do/MongoManager.java b/src/main/java/eu/koboo/en2do/MongoManager.java index a413e21f..f5de32a2 100644 --- a/src/main/java/eu/koboo/en2do/MongoManager.java +++ b/src/main/java/eu/koboo/en2do/MongoManager.java @@ -53,6 +53,7 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; import java.util.regex.Pattern; import static org.bson.codecs.configuration.CodecRegistries.fromProviders; @@ -65,6 +66,7 @@ * See documentation: <a href="https://koboo.gitbook.io/en2do/get-started/create-the-mongomanager">...</a> */ @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) +@SuppressWarnings("unused") public class MongoManager { // Predefined methods by Java objects @@ -76,15 +78,19 @@ public class MongoManager { Map<Class<?>, Repository<?, ?>> repositoryRegistry; Map<Class<?>, RepositoryMeta<?, ?, ?>> repositoryMetaRegistry; + ExecutorService executorService; + @Getter CodecRegistry codecRegistry; MongoClient client; MongoDatabase database; - public MongoManager(Credentials credentials) { + public MongoManager(Credentials credentials, ExecutorService executorService) { repositoryRegistry = new ConcurrentHashMap<>(); repositoryMetaRegistry = new ConcurrentHashMap<>(); + this.executorService = executorService; + // If no credentials given, try loading them from default file. if (credentials == null) { credentials = Credentials.fromFile(); @@ -139,12 +145,24 @@ public MongoManager(Credentials credentials) { database = client.getDatabase(databaseString); } + public MongoManager(Credentials credentials) { + this(credentials, null); + } + public MongoManager() { - this(null); + this(null, null); } + public boolean close() { + return close(true); + } + + public boolean close(boolean shutdownExecutor) { try { + if(executorService != null && shutdownExecutor) { + executorService.shutdown(); + } if (repositoryRegistry != null) { repositoryRegistry.clear(); } @@ -240,7 +258,7 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) { MongoCollection<E> entityCollection = database.getCollection(entityCollectionName, entityClass); - RepositoryMeta<E, ID, R> repositoryMeta = new RepositoryMeta<>(this, + RepositoryMeta<E, ID, R> repositoryMeta = new RepositoryMeta<>( repositoryClass, entityClass, entityFieldSet, entityUniqueIdClass, entityUniqueIdField, @@ -529,7 +547,7 @@ public <E, ID, R extends Repository<E, ID>> R create(Class<R> repositoryClass) { ClassLoader repoClassLoader = repositoryClass.getClassLoader(); Class<?>[] interfaces = new Class[]{repositoryClass}; Repository<E, ID> repository = (Repository<E, ID>) Proxy.newProxyInstance(repoClassLoader, interfaces, - new RepositoryInvocationHandler<>(repositoryMeta)); + new RepositoryInvocationHandler<>(repositoryMeta, executorService)); repositoryRegistry.put(repositoryClass, repository); repositoryMetaRegistry.put(repositoryClass, repositoryMeta); return (R) repository; diff --git a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java index 8648c7c9..8735ec3b 100644 --- a/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java +++ b/src/main/java/eu/koboo/en2do/internal/RepositoryInvocationHandler.java @@ -17,12 +17,14 @@ import java.lang.reflect.Method; import java.util.ArrayList; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true) @AllArgsConstructor public class RepositoryInvocationHandler<E, ID, R extends Repository<E, ID>> implements InvocationHandler { RepositoryMeta<E, ID, R> repositoryMeta; + ExecutorService executorService; @Override @SuppressWarnings("all") @@ -106,13 +108,12 @@ private Object executeMethod(DynamicMethod<E, ID, R> dynamicMethod, Object[] arg } private void executeFuture(CompletableFuture<Object> future, MethodCallable callable) { - //TODO: Check for ExecutorService from manager future.completeAsync(() -> { try { return callable.call(); } catch (Exception e) { throw new RuntimeException(e); } - }); + }, executorService == null ? future.defaultExecutor() : executorService); } } diff --git a/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java b/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java index d9a0a4e2..f8c368d9 100644 --- a/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java +++ b/src/main/java/eu/koboo/en2do/internal/RepositoryMeta.java @@ -4,7 +4,6 @@ import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.model.Filters; -import eu.koboo.en2do.MongoManager; import eu.koboo.en2do.internal.exception.methods.MethodInvalidPageException; import eu.koboo.en2do.internal.exception.methods.MethodInvalidSortLimitException; import eu.koboo.en2do.internal.exception.methods.MethodInvalidSortSkipException; @@ -31,7 +30,6 @@ @Getter public class RepositoryMeta<E, ID, R extends Repository<E, ID>> { - MongoManager mongoManager; String collectionName; MongoCollection<E> collection; @@ -53,11 +51,10 @@ public class RepositoryMeta<E, ID, R extends Repository<E, ID>> { @Getter(AccessLevel.NONE) Map<String, DynamicMethod<E, ID, R>> dynamicMethodRegistry; - public RepositoryMeta(MongoManager mongoManager, Class<R> repositoryClass, Class<E> entityClass, + public RepositoryMeta(Class<R> repositoryClass, Class<E> entityClass, Set<Field> entityFieldSet, Class<ID> entityUniqueIdClass, Field entityUniqueIdField, MongoCollection<E> collection, String collectionName) { - this.mongoManager = mongoManager; this.collectionName = collectionName; this.collection = collection; From 20dd0c78e3225af6a7e9541e40987270ac37d395 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Sun, 29 Jan 2023 01:56:45 +0100 Subject: [PATCH 18/19] Fix validator issues --- src/main/java/eu/koboo/en2do/internal/Validator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/eu/koboo/en2do/internal/Validator.java b/src/main/java/eu/koboo/en2do/internal/Validator.java index 973b8a1d..9c1c24ba 100644 --- a/src/main/java/eu/koboo/en2do/internal/Validator.java +++ b/src/main/java/eu/koboo/en2do/internal/Validator.java @@ -86,7 +86,7 @@ public static <E, ID, R extends Repository<E, ID>> void validateCompatibility( .findFirst() .orElse(null); if (field == null) { - throw new RepositoryDescriptorException(typeClass, repositoryClass, descriptor.getName()); + continue; } // Ignore all fields annotated with transient, because pojo doesn't touch that. From d5fbbff368e6ffd432478f78531527eba5d56e49 Mon Sep 17 00:00:00 2001 From: Koboo <14143908+Koboo@users.noreply.github.com> Date: Sun, 29 Jan 2023 01:58:13 +0100 Subject: [PATCH 19/19] Update version to 2.2.0 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 72a63d81..6313ad35 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ ### Project properties ### projectGroup=eu.koboo -projectVersion=2.1.0 +projectVersion=2.2.0 # ### Dependency versions ### lombokVersion=1.18.24