From 0c4ac136df5986ea39f3f068ca788d393ed09dd5 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 18 Aug 2020 09:58:20 +0200 Subject: [PATCH] Revert "implement kotlin support for mongodb panache" This reverts commit 0adc1d3d82403733cdaa76e735b1b8f398505172. --- bom/application/pom.xml | 15 - .../io/quarkus/deployment/Capability.java | 1 - .../quarkus/deployment/ExtensionLoader.java | 15 +- .../java/io/quarkus/deployment/Feature.java | 1 - .../io/quarkus/deployment/util/AsmUtil.java | 80 -- .../reactive/MongoWithReplicasTestBase.java | 4 +- .../KotlinPanacheCompanionEnhancer.java | 2 +- .../KotlinPanacheEntityClassVisitor.java | 20 +- .../KotlinPanacheEntityEnhancer.java | 14 +- .../KotlinPanacheRepositoryClassVisitor.java | 8 +- .../KotlinPanacheRepositoryEnhancer.java | 2 +- .../KotlinPanacheResourceProcessor.java | 44 +- .../runtime/pom.xml | 1 - .../orm/panache/kotlin/PanacheCompanion.kt | 2 +- .../PanacheHibernateResourceProcessor.java | 5 +- .../deployment/PanacheJpaEntityEnhancer.java | 8 +- .../PanacheJpaRepositoryEnhancer.java | 23 +- .../mongodb-panache-common/deployment/pom.xml | 67 -- .../BasePanacheMongoResourceProcessor.java | 384 -------- .../panache/deployment/ByteCodeType.java | 57 -- .../panache/deployment/TypeBundle.java | 23 - .../PanacheMongoEntityClassVisitor.java | 128 --- .../panache/mongodb-panache-common/pom.xml | 20 - .../mongodb-panache-common/runtime/pom.xml | 88 -- .../CommonReactivePanacheQueryImpl.java | 238 ----- .../runtime/CommonPanacheQueryImpl.java | 229 ----- .../mongodb-panache-kotlin/deployment/pom.xml | 63 -- .../kotlin/deployment/KotlinGenerator.java | 205 ----- .../KotlinImperativeTypeBundle.java | 66 -- .../KotlinPanacheMongoEntityEnhancer.java | 55 -- .../KotlinPanacheMongoRepositoryEnhancer.java | 28 - .../KotlinPanacheMongoResourceProcessor.java | 144 --- .../deployment/KotlinReactiveTypeBundle.java | 66 -- .../PanacheMongoCompanionEnhancer.java | 53 -- ...linPanacheMongoRepositoryClassVisitor.java | 107 --- .../PanacheMongoCompanionClassVisitor.java | 94 -- .../panache/mongodb-panache-kotlin/pom.xml | 20 - .../mongodb-panache-kotlin/runtime/pom.xml | 203 ----- .../runtime/ReactivePanacheQueryImpl.java | 126 --- .../kotlin/runtime/PanacheQueryImpl.java | 125 --- .../panache/kotlin/PanacheMongoCompanion.kt | 702 --------------- .../panache/kotlin/PanacheMongoEntity.kt | 31 - .../panache/kotlin/PanacheMongoEntityBase.kt | 62 -- .../panache/kotlin/PanacheMongoRepository.kt | 13 - .../kotlin/PanacheMongoRepositoryBase.kt | 728 --------------- .../mongodb/panache/kotlin/PanacheQuery.kt | 187 ---- .../reactive/ReactivePanacheMongoCompanion.kt | 771 ---------------- .../reactive/ReactivePanacheMongoEntity.kt | 31 - .../ReactivePanacheMongoEntityBase.kt | 64 -- .../ReactivePanacheMongoRepository.kt | 13 - .../ReactivePanacheMongoRepositoryBase.kt | 833 ------------------ .../kotlin/reactive/ReactivePanacheQuery.kt | 186 ---- .../runtime/KotlinReactiveMongoOperations.kt | 59 -- .../kotlin/runtime/KotlinMongoOperations.kt | 57 -- .../mongodb/panache/kotlin/TestAnalogs.kt | 224 ----- .../mongodb-panache/deployment/pom.xml | 2 +- .../deployment/ImperativeTypeBundle.java | 61 -- .../PanacheMongoEntityClassBuildItem.java | 0 .../PanacheMongoEntityEnhancer.java | 64 +- .../PanacheMongoRepositoryEnhancer.java | 52 +- .../PanacheMongoResourceProcessor.java | 458 +++++++++- .../deployment/ProjectionForEnhancer.java | 0 .../PropertyMappingClassBuildStep.java | 2 +- .../ReactivePanacheMongoEntityEnhancer.java | 88 ++ ...eactivePanacheMongoRepositoryEnhancer.java | 62 ++ .../deployment/ReactiveTypeBundle.java | 61 -- .../PanacheMongoRepositoryClassVisitor.java | 120 --- .../panache/mongodb-panache/runtime/pom.xml | 6 +- .../quarkus/mongodb/panache/MongoEntity.java | 0 .../panache/PanacheMongoEntityBase.java | 133 +-- .../mongodb/panache/PanacheMongoRecorder.java | 0 .../panache/PanacheMongoRepositoryBase.java | 128 +-- .../mongodb/panache/PanacheUpdate.java | 0 .../mongodb/panache/ProjectionFor.java | 2 +- .../panache/binder/CommonQueryBinder.java | 0 .../panache/binder/MongoParserVisitor.java | 0 .../panache/binder/NativeQueryBinder.java | 0 .../panache/binder/PanacheQlQueryBinder.java | 0 .../panache/jackson/ObjectIdDeserializer.java | 0 .../panache/jackson/ObjectIdSerializer.java | 0 .../panache/jsonb/ObjectIdDeserializer.java | 0 .../panache/jsonb/ObjectIdSerializer.java | 0 .../ReactivePanacheMongoEntityBase.java | 130 +-- .../ReactivePanacheMongoRepositoryBase.java | 253 +++--- .../reactive/ReactivePanacheUpdate.java | 0 .../runtime/JavaReactiveMongoOperations.java | 35 - .../runtime/ReactiveMongoOperations.java | 249 +++--- .../runtime/ReactivePanacheQueryImpl.java | 179 +++- .../runtime/ReactivePanacheUpdateImpl.java | 18 +- .../mongodb/panache/runtime/BeanUtils.java | 0 .../panache/runtime/JavaMongoOperations.java | 33 - .../panache/runtime/MongoOperations.java | 251 +++--- .../panache/runtime/MongoPropertyUtil.java | 0 .../panache/runtime/PanacheQueryImpl.java | 174 +++- .../panache/runtime/PanacheUpdateImpl.java | 8 +- .../panache/runtime/MongoOperationsTest.java | 158 ++-- .../deployment/PanacheEntityEnhancer.java | 296 ++++++- .../deployment/PanacheRepositoryEnhancer.java | 248 +++++- .../visitors/PanacheEntityClassVisitor.java | 293 ------ .../PanacheRepositoryClassVisitor.java | 258 ------ extensions/panache/pom.xml | 2 - .../io/quarkus/it/panache/JacksonTest.java | 1 - .../mongodb-panache-kotlin/pom.xml | 233 ----- .../quarkus/it/mongodb/panache/book/Book.kt | 58 -- .../it/mongodb/panache/book/BookDetail.kt | 18 - .../it/mongodb/panache/book/BookEntity.kt | 59 -- .../panache/book/BookEntityResource.kt | 111 --- .../it/mongodb/panache/book/BookRepository.kt | 7 - .../panache/book/BookRepositoryResource.kt | 114 --- .../it/mongodb/panache/book/BookShortView.kt | 15 - .../panache/bugs/AbstractRepository.kt | 5 - .../panache/bugs/Bug5274EntityRepository.kt | 7 - .../panache/bugs/Bug5885AbstractRepository.kt | 5 - .../panache/bugs/Bug5885EntityRepository.kt | 7 - .../panache/bugs/Bug6324AbstractRepository.kt | 5 - .../panache/bugs/Bug6324ConcreteRepository.kt | 6 - .../mongodb/panache/bugs/Bug6324Repository.kt | 7 - .../it/mongodb/panache/bugs/BugResource.kt | 94 -- .../it/mongodb/panache/bugs/DateEntity.kt | 19 - .../it/mongodb/panache/bugs/LinkedEntity.kt | 12 - .../it/mongodb/panache/bugs/NeedReflection.kt | 5 - .../person/MockablePersonRepository.kt | 14 - .../it/mongodb/panache/person/Person.kt | 10 - .../it/mongodb/panache/person/PersonEntity.kt | 20 - .../panache/person/PersonEntityResource.kt | 87 -- .../it/mongodb/panache/person/PersonName.kt | 18 - .../panache/person/PersonRepository.kt | 8 - .../person/PersonRepositoryResource.kt | 98 --- .../reactive/book/ReactiveBookEntity.kt | 53 -- .../book/ReactiveBookEntityResource.kt | 125 --- .../reactive/book/ReactiveBookRepository.kt | 8 - .../book/ReactiveBookRepositoryResource.kt | 128 --- .../reactive/person/ReactivePersonEntity.kt | 14 - .../person/ReactivePersonEntityResource.kt | 88 -- .../person/ReactivePersonRepository.kt | 8 - .../ReactivePersonRepositoryResource.kt | 95 -- .../panache/test/TestImperativeEntity.kt | 19 - .../panache/test/TestImperativeRepository.kt | 7 - .../panache/test/TestReactiveEntity.kt | 18 - .../panache/test/TestReactiveRepository.kt | 7 - .../it/mongodb/panache/test/TestResource.kt | 745 ---------------- .../src/main/resources/application.properties | 9 - .../io/quarkus/it/mongodb/panache/BookDTO.kt | 73 -- .../it/mongodb/panache/MongoTestResource.kt | 66 -- .../panache/MongodbPanacheMockingTest.kt | 107 --- .../panache/MongodbPanacheResourceTest.kt | 333 ------- .../NativeMongodbPanacheResourceIT.kt | 7 - .../NativeReactiveMongodbPanacheResourceIT.kt | 6 - .../ReactiveMongodbPanacheResourceTest.kt | 351 -------- integration-tests/pom.xml | 1 - 150 files changed, 2261 insertions(+), 11669 deletions(-) delete mode 100644 extensions/panache/mongodb-panache-common/deployment/pom.xml delete mode 100644 extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/BasePanacheMongoResourceProcessor.java delete mode 100644 extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ByteCodeType.java delete mode 100644 extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/TypeBundle.java delete mode 100644 extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/visitors/PanacheMongoEntityClassVisitor.java delete mode 100644 extensions/panache/mongodb-panache-common/pom.xml delete mode 100644 extensions/panache/mongodb-panache-common/runtime/pom.xml delete mode 100644 extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/CommonReactivePanacheQueryImpl.java delete mode 100644 extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/CommonPanacheQueryImpl.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/deployment/pom.xml delete mode 100644 extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinGenerator.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinImperativeTypeBundle.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoEntityEnhancer.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoRepositoryEnhancer.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoResourceProcessor.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinReactiveTypeBundle.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/PanacheMongoCompanionEnhancer.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/visitors/KotlinPanacheMongoRepositoryClassVisitor.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/visitors/PanacheMongoCompanionClassVisitor.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/pom.xml delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/pom.xml delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/java/io/quarkus/mongodb/panache/kotlin/reactive/runtime/ReactivePanacheQueryImpl.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/java/io/quarkus/mongodb/panache/kotlin/runtime/PanacheQueryImpl.java delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoCompanion.kt delete mode 100755 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoEntity.kt delete mode 100755 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoEntityBase.kt delete mode 100755 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoRepository.kt delete mode 100755 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoRepositoryBase.kt delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheQuery.kt delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoCompanion.kt delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoEntity.kt delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoEntityBase.kt delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoRepository.kt delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoRepositoryBase.kt delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheQuery.kt delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/runtime/KotlinReactiveMongoOperations.kt delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/runtime/KotlinMongoOperations.kt delete mode 100644 extensions/panache/mongodb-panache-kotlin/runtime/src/test/kotlin/io/quarkus/mongodb/panache/kotlin/TestAnalogs.kt delete mode 100644 extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ImperativeTypeBundle.java rename extensions/panache/{mongodb-panache-common => mongodb-panache}/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoEntityClassBuildItem.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ProjectionForEnhancer.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PropertyMappingClassBuildStep.java (88%) create mode 100644 extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactivePanacheMongoEntityEnhancer.java create mode 100644 extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactivePanacheMongoRepositoryEnhancer.java delete mode 100644 extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactiveTypeBundle.java delete mode 100644 extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/visitors/PanacheMongoRepositoryClassVisitor.java rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/MongoEntity.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoRecorder.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheUpdate.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/ProjectionFor.java (92%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/binder/CommonQueryBinder.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/binder/MongoParserVisitor.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/binder/NativeQueryBinder.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/binder/PanacheQlQueryBinder.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/jackson/ObjectIdDeserializer.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/jackson/ObjectIdSerializer.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/jsonb/ObjectIdDeserializer.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/jsonb/ObjectIdSerializer.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheUpdate.java (100%) delete mode 100644 extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/JavaReactiveMongoOperations.java rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactiveMongoOperations.java (67%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactivePanacheUpdateImpl.java (69%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/BeanUtils.java (100%) delete mode 100644 extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/JavaMongoOperations.java rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoOperations.java (65%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoPropertyUtil.java (100%) rename extensions/panache/{mongodb-panache-common => mongodb-panache}/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/PanacheUpdateImpl.java (77%) delete mode 100644 extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/visitors/PanacheEntityClassVisitor.java delete mode 100644 extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/visitors/PanacheRepositoryClassVisitor.java delete mode 100755 integration-tests/mongodb-panache-kotlin/pom.xml delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/Book.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookDetail.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntity.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntityResource.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookRepositoryResource.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookShortView.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/AbstractRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5274EntityRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5885AbstractRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5885EntityRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324AbstractRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324ConcreteRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324Repository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/BugResource.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/DateEntity.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/LinkedEntity.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/NeedReflection.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/MockablePersonRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/Person.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonEntity.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonEntityResource.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonName.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonRepositoryResource.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntityResource.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookRepositoryResource.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonEntity.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonEntityResource.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonRepositoryResource.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestImperativeEntity.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestImperativeRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestReactiveEntity.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestReactiveRepository.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestResource.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/main/resources/application.properties delete mode 100644 integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/BookDTO.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongoTestResource.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongodbPanacheMockingTest.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongodbPanacheResourceTest.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/NativeMongodbPanacheResourceIT.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/NativeReactiveMongodbPanacheResourceIT.kt delete mode 100644 integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/ReactiveMongodbPanacheResourceTest.kt diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 381fc3ebdcb4b..93166305a5bb9 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -639,11 +639,6 @@ quarkus-panache-common-deployment ${project.version} - - io.quarkus - quarkus-mongodb-panache-common-deployment - ${project.version} - io.quarkus quarkus-panache-mock @@ -714,16 +709,6 @@ quarkus-mongodb-panache-deployment ${project.version} - - io.quarkus - quarkus-mongodb-panache-kotlin - ${project.version} - - - io.quarkus - quarkus-mongodb-panache-common - ${project.version} - io.quarkus quarkus-hibernate-search-elasticsearch diff --git a/core/deployment/src/main/java/io/quarkus/deployment/Capability.java b/core/deployment/src/main/java/io/quarkus/deployment/Capability.java index dc1263da2918b..f2672f2ec5ea6 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/Capability.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/Capability.java @@ -31,7 +31,6 @@ public enum Capability { JWT, TIKA, MONGODB_PANACHE, - MONGODB_PANACHE_KOTLIN, FLYWAY, LIQUIBASE, SECURITY, diff --git a/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java b/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java index 90461bc4d0ee1..2f1c3145eb830 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/ExtensionLoader.java @@ -10,7 +10,6 @@ import static io.quarkus.deployment.util.ReflectUtil.rawTypeIs; import static io.quarkus.deployment.util.ReflectUtil.rawTypeOf; import static io.quarkus.deployment.util.ReflectUtil.rawTypeOfParameter; -import static java.util.Arrays.asList; import java.io.IOException; import java.lang.reflect.AnnotatedElement; @@ -254,9 +253,6 @@ public static Consumer loadStepsFrom(Class clazz, BuildTim final Constructor[] constructors = clazz.getDeclaredConstructors(); // this is the chain configuration that will contain all steps on this class and be returned Consumer chainConfig = Functions.discardingConsumer(); - if (Modifier.isAbstract(clazz.getModifiers())) { - return chainConfig; - } // this is the step configuration that applies to all steps on this class Consumer stepConfig = Functions.discardingConsumer(); // this is the build step instance setup that applies to all steps on this class @@ -486,7 +482,7 @@ public static Consumer loadStepsFrom(Class clazz, BuildTim } // now iterate the methods - final List methods = getMethods(clazz); + final Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { final int mods = method.getModifiers(); if (Modifier.isStatic(mods)) { @@ -967,15 +963,6 @@ public String toString() { return chainConfig; } - protected static List getMethods(Class clazz) { - List declaredMethods = new ArrayList<>(); - if (!clazz.getName().equals(Object.class.getName())) { - declaredMethods.addAll(getMethods(clazz.getSuperclass())); - declaredMethods.addAll(asList(clazz.getDeclaredMethods())); - } - return declaredMethods; - } - private static BooleanSupplier and(BooleanSupplier a, BooleanSupplier b) { return () -> a.getAsBoolean() && b.getAsBoolean(); } diff --git a/core/deployment/src/main/java/io/quarkus/deployment/Feature.java b/core/deployment/src/main/java/io/quarkus/deployment/Feature.java index 843cd31d9f4fd..56bab5e6a90d5 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/Feature.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/Feature.java @@ -59,7 +59,6 @@ public enum Feature { MAILER, MONGODB_CLIENT, MONGODB_PANACHE, - MONGODB_PANACHE_KOTLIN, MUTINY, NARAYANA_JTA, NARAYANA_STM, diff --git a/core/deployment/src/main/java/io/quarkus/deployment/util/AsmUtil.java b/core/deployment/src/main/java/io/quarkus/deployment/util/AsmUtil.java index c72b9c9d88ba5..b1d43433b0780 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/util/AsmUtil.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/util/AsmUtil.java @@ -1,20 +1,7 @@ package io.quarkus.deployment.util; -import static java.util.Arrays.asList; -import static org.objectweb.asm.Type.BOOLEAN_TYPE; -import static org.objectweb.asm.Type.BYTE_TYPE; -import static org.objectweb.asm.Type.CHAR_TYPE; -import static org.objectweb.asm.Type.FLOAT_TYPE; -import static org.objectweb.asm.Type.INT_TYPE; -import static org.objectweb.asm.Type.LONG_TYPE; -import static org.objectweb.asm.Type.SHORT_TYPE; -import static org.objectweb.asm.Type.VOID_TYPE; -import static org.objectweb.asm.Type.getType; - import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.function.Function; import org.jboss.jandex.ArrayType; @@ -33,36 +20,6 @@ */ public class AsmUtil { - public static final List PRIMITIVES = asList( - VOID_TYPE, - BOOLEAN_TYPE, - CHAR_TYPE, - BYTE_TYPE, - SHORT_TYPE, - INT_TYPE, - FLOAT_TYPE, - LONG_TYPE); - public static final List WRAPPERS = asList( - getType(Void.class), - getType(Boolean.class), - getType(Character.class), - getType(Byte.class), - getType(Short.class), - getType(Integer.class), - getType(Float.class), - getType(Long.class)); - public static final Map WRAPPER_TO_PRIMITIVE = new HashMap<>(); - - static { - for (int i = 0; i < AsmUtil.PRIMITIVES.size(); i++) { - AsmUtil.WRAPPER_TO_PRIMITIVE.put(AsmUtil.WRAPPERS.get(i), AsmUtil.PRIMITIVES.get(i)); - } - } - - public static org.objectweb.asm.Type autobox(org.objectweb.asm.Type primitive) { - return WRAPPERS.get(primitive.getSort()); - } - /** * Returns the Java bytecode signature of a given Jandex MethodInfo using the given type argument mappings. * For example, given this method: @@ -474,43 +431,6 @@ public static void unboxIfRequired(MethodVisitor mv, Type jandexType) { } } - /** - * Calls the right unboxing method for the given Jandex Type if it is a primitive. - * - * @param mv The MethodVisitor on which to visit the unboxing instructions - * @param type The Jandex Type to unbox if it is a primitive. - */ - public static void unboxIfRequired(MethodVisitor mv, org.objectweb.asm.Type type) { - if (type.getSort() <= org.objectweb.asm.Type.DOUBLE) { - switch (type.getSort()) { - case org.objectweb.asm.Type.BOOLEAN: - unbox(mv, "java/lang/Boolean", "booleanValue", "Z"); - break; - case org.objectweb.asm.Type.BYTE: - unbox(mv, "java/lang/Byte", "byteValue", "B"); - break; - case org.objectweb.asm.Type.CHAR: - unbox(mv, "java/lang/Character", "charValue", "C"); - break; - case org.objectweb.asm.Type.DOUBLE: - unbox(mv, "java/lang/Double", "doubleValue", "D"); - break; - case org.objectweb.asm.Type.FLOAT: - unbox(mv, "java/lang/Float", "floatValue", "F"); - break; - case org.objectweb.asm.Type.INT: - unbox(mv, "java/lang/Integer", "intValue", "I"); - break; - case org.objectweb.asm.Type.LONG: - unbox(mv, "java/lang/Long", "longValue", "J"); - break; - case org.objectweb.asm.Type.SHORT: - unbox(mv, "java/lang/Short", "shortValue", "S"); - break; - } - } - } - private static void unbox(MethodVisitor mv, String owner, String methodName, String returnTypeSignature) { mv.visitTypeInsn(Opcodes.CHECKCAST, owner); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, methodName, "()" + returnTypeSignature, false); diff --git a/extensions/mongodb-client/runtime/src/test/java/io/quarkus/mongodb/reactive/MongoWithReplicasTestBase.java b/extensions/mongodb-client/runtime/src/test/java/io/quarkus/mongodb/reactive/MongoWithReplicasTestBase.java index f9aa3a09c5589..23561d8a5c24c 100644 --- a/extensions/mongodb-client/runtime/src/test/java/io/quarkus/mongodb/reactive/MongoWithReplicasTestBase.java +++ b/extensions/mongodb-client/runtime/src/test/java/io/quarkus/mongodb/reactive/MongoWithReplicasTestBase.java @@ -108,10 +108,10 @@ protected String getConnectionString() { } private static void initializeReplicaSet(final List mongodConfigList) throws UnknownHostException { - final String arbiterAddress = "mongodb://" + mongodConfigList.get(0).net().getServerAddress().getHostName() + ":" + final String arbitrerAddress = "mongodb://" + mongodConfigList.get(0).net().getServerAddress().getHostName() + ":" + mongodConfigList.get(0).net().getPort(); final MongoClientSettings mo = MongoClientSettings.builder() - .applyConnectionString(new ConnectionString(arbiterAddress)).build(); + .applyConnectionString(new ConnectionString(arbitrerAddress)).build(); try (MongoClient mongo = MongoClients.create(mo)) { final MongoDatabase mongoAdminDB = mongo.getDatabase("admin"); diff --git a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheCompanionEnhancer.java b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheCompanionEnhancer.java index a8e4585184f37..620bb5cb771bb 100644 --- a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheCompanionEnhancer.java +++ b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheCompanionEnhancer.java @@ -23,7 +23,7 @@ public class KotlinPanacheCompanionEnhancer extends PanacheEntityEnhancer methodCustomizers) { - super(index, methodCustomizers); + super(index, KotlinPanacheResourceProcessor.PANACHE_ENTITY_BASE_DOTNAME, methodCustomizers); modelInfo = new MetamodelInfo<>(); } diff --git a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheEntityClassVisitor.java b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheEntityClassVisitor.java index 74b478f1a039a..49df9ed685726 100644 --- a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheEntityClassVisitor.java +++ b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheEntityClassVisitor.java @@ -13,17 +13,18 @@ import io.quarkus.panache.common.deployment.EntityField; import io.quarkus.panache.common.deployment.EntityModel; import io.quarkus.panache.common.deployment.MetamodelInfo; +import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; -import io.quarkus.panache.common.deployment.visitors.PanacheEntityClassVisitor; /** * This visitor process kotlin entities and removes the final modifier from the compiler generated getters and setters. * Unlike Java entities, we don't need to generate the getters and setters because kotlinc does that for us but kotlin, * by default, is final so we need to open those up for hibernate to add its hooks. */ -class KotlinPanacheEntityClassVisitor extends PanacheEntityClassVisitor { +class KotlinPanacheEntityClassVisitor extends PanacheEntityEnhancer.PanacheEntityClassVisitor { private String entityBinaryType; + private org.objectweb.asm.Type entityType; public KotlinPanacheEntityClassVisitor(String className, ClassVisitor outputClassVisitor, MetamodelInfo> modelInfo, @@ -37,7 +38,8 @@ public KotlinPanacheEntityClassVisitor(String className, ClassVisitor outputClas public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { super.visit(version, access, name, signature, superName, interfaces); - entityBinaryType = name; + entityBinaryType = name.replace('.', '/'); + entityType = org.objectweb.asm.Type.getType("L" + entityBinaryType + ";"); } @Override @@ -50,10 +52,20 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str } @Override - protected String getPanacheOperationsInternalName() { + protected String getModelDescriptor() { + return "Ljava/lang/Class;"; + } + + @Override + protected String getPanacheOperationsBinaryName() { return KotlinPanacheEntityEnhancer.JPA_OPERATIONS_BINARY_NAME; } + @Override + protected void injectModel(MethodVisitor mv) { + mv.visitLdcInsn(entityType); + } + @Override protected void generateAccessorSetField(MethodVisitor mv, EntityField field) { mv.visitMethodInsn( diff --git a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheEntityEnhancer.java b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheEntityEnhancer.java index f976635ad80ef..bd682866d26bd 100644 --- a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheEntityEnhancer.java +++ b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheEntityEnhancer.java @@ -1,11 +1,10 @@ package io.quarkus.hibernate.orm.panache.kotlin.deployment; -import static io.quarkus.hibernate.orm.panache.kotlin.deployment.KotlinPanacheResourceProcessor.PANACHE_ENTITY_BASE; -import static io.quarkus.hibernate.orm.panache.kotlin.deployment.KotlinPanacheResourceProcessor.TRANSIENT; - import java.lang.reflect.Modifier; import java.util.List; +import javax.persistence.Transient; + import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.FieldInfo; @@ -25,15 +24,16 @@ public class KotlinPanacheEntityEnhancer extends PanacheEntityEnhancer methodCustomizers) { - super(index, methodCustomizers); + super(index, KotlinPanacheResourceProcessor.PANACHE_ENTITY_BASE_DOTNAME, methodCustomizers); modelInfo = new MetamodelInfo<>(); } @Override public ClassVisitor apply(String className, ClassVisitor outputClassVisitor) { - return new KotlinPanacheEntityClassVisitor(className, outputClassVisitor, modelInfo, - indexView.getClassByName(PANACHE_ENTITY_BASE), + return new KotlinPanacheEntityClassVisitor(className, outputClassVisitor, modelInfo, panacheEntityBaseClassInfo, indexView.getClassByName(DotName.createSimple(className)), methodCustomizers); } @@ -43,7 +43,7 @@ public void collectFields(ClassInfo classInfo) { String name = fieldInfo.name(); if (Modifier.isPublic(fieldInfo.flags()) && !Modifier.isStatic(fieldInfo.flags()) - && !fieldInfo.hasAnnotation(TRANSIENT)) { + && !fieldInfo.hasAnnotation(DOTNAME_TRANSIENT)) { entityModel.addField(new EntityField(name, DescriptorUtils.typeToString(fieldInfo.type()))); } } diff --git a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheRepositoryClassVisitor.java b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheRepositoryClassVisitor.java index 6fd8e6b5b4a4b..674bf0ba3a44f 100644 --- a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheRepositoryClassVisitor.java +++ b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheRepositoryClassVisitor.java @@ -1,11 +1,11 @@ package io.quarkus.hibernate.orm.panache.kotlin.deployment; -import static io.quarkus.deployment.util.AsmUtil.autobox; import static io.quarkus.gizmo.Gizmo.ASM_API_VERSION; import static io.quarkus.hibernate.orm.panache.kotlin.deployment.KotlinPanacheResourceProcessor.JPA_OPERATIONS; -import static io.quarkus.hibernate.orm.panache.kotlin.deployment.KotlinPanacheResourceProcessor.PANACHE_REPOSITORY_BASE; +import static io.quarkus.hibernate.orm.panache.kotlin.deployment.KotlinPanacheResourceProcessor.PANACHE_REPOSITORY_BASE_DOTNAME; +import static io.quarkus.hibernate.orm.panache.kotlin.deployment.KotlinPanacheResourceProcessor.autobox; import static io.quarkus.hibernate.orm.panache.kotlin.deployment.KotlinPanacheResourceProcessor.sanitize; -import static io.quarkus.panache.common.deployment.visitors.PanacheRepositoryClassVisitor.findEntityTypeArgumentsForPanacheRepository; +import static io.quarkus.panache.common.deployment.PanacheRepositoryEnhancer.PanacheRepositoryClassVisitor.findEntityTypeArgumentsForPanacheRepository; import static org.jboss.jandex.DotName.createSimple; import static org.objectweb.asm.Opcodes.ALOAD; import static org.objectweb.asm.Opcodes.INVOKESTATIC; @@ -57,7 +57,7 @@ public void visit(int version, int access, String name, String signature, String final String repositoryClassName = name.replace('/', '.'); String[] foundTypeArguments = findEntityTypeArgumentsForPanacheRepository(indexView, repositoryClassName, - PANACHE_REPOSITORY_BASE); + PANACHE_REPOSITORY_BASE_DOTNAME); String entityBinaryType = foundTypeArguments[0]; entitySignature = "L" + entityBinaryType + ";"; diff --git a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheRepositoryEnhancer.java b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheRepositoryEnhancer.java index 53e58e4f21d47..003d256378604 100644 --- a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheRepositoryEnhancer.java +++ b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheRepositoryEnhancer.java @@ -8,7 +8,7 @@ public class KotlinPanacheRepositoryEnhancer extends PanacheRepositoryEnhancer { public KotlinPanacheRepositoryEnhancer(IndexView index) { - super(index, KotlinPanacheResourceProcessor.PANACHE_REPOSITORY_BASE); + super(index, KotlinPanacheResourceProcessor.PANACHE_REPOSITORY_BASE_DOTNAME); } @Override diff --git a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheResourceProcessor.java b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheResourceProcessor.java index a3b4e29795ca3..f463cca99af13 100644 --- a/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheResourceProcessor.java +++ b/extensions/panache/hibernate-orm-panache-kotlin/deployment/src/main/java/io/quarkus/hibernate/orm/panache/kotlin/deployment/KotlinPanacheResourceProcessor.java @@ -11,7 +11,6 @@ import java.util.stream.Collectors; import javax.persistence.EntityManager; -import javax.persistence.Transient; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; @@ -41,6 +40,7 @@ import io.quarkus.panache.common.deployment.PanacheFieldAccessEnhancer; import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; import io.quarkus.panache.common.deployment.PanacheMethodCustomizerBuildItem; +import io.quarkus.panache.common.deployment.PanacheRepositoryEnhancer; public final class KotlinPanacheResourceProcessor { @@ -49,12 +49,12 @@ public final class KotlinPanacheResourceProcessor { static final String JPA_OPERATIONS = createSimple(JpaOperations.class.getName()) .toString().replace(".", "/"); - static final DotName PANACHE_REPOSITORY_BASE = createSimple(PanacheRepositoryBase.class.getName()); - static final DotName PANACHE_REPOSITORY = createSimple(PanacheRepository.class.getName()); + static final DotName PANACHE_REPOSITORY_BASE_DOTNAME = createSimple(PanacheRepositoryBase.class.getName()); + static final DotName PANACHE_REPOSITORY_DOTNAME = createSimple(PanacheRepository.class.getName()); - static final DotName PANACHE_ENTITY_BASE = createSimple(PanacheEntityBase.class.getName()); - static final DotName PANACHE_ENTITY = createSimple(PanacheEntity.class.getName()); - static final DotName PANACHE_COMPANION = createSimple(PanacheCompanion.class.getName()); + static final DotName PANACHE_ENTITY_BASE_DOTNAME = createSimple(PanacheEntityBase.class.getName()); + static final DotName PANACHE_ENTITY_DOTNAME = createSimple(PanacheEntity.class.getName()); + static final DotName PANACHE_COMPANION_DOTNAME = createSimple(PanacheCompanion.class.getName()); static final String PANACHE_ENTITY_BASE_SIGNATURE = toBinarySignature(PanacheEntityBase.class); static final String PANACHE_ENTITY_SIGNATURE = toBinarySignature(PanacheEntity.class); @@ -62,7 +62,6 @@ public final class KotlinPanacheResourceProcessor { static final String OBJECT_SIGNATURE = toBinarySignature(Object.class); static final String CLASS_SIGNATURE = toBinarySignature(Class.class); - static final DotName TRANSIENT = DotName.createSimple(Transient.class.getName()); static final org.objectweb.asm.Type CLASS_TYPE = org.objectweb.asm.Type.getType(Class.class); static final org.objectweb.asm.Type OBJECT_TYPE = org.objectweb.asm.Type.getType(Object.class); @@ -73,6 +72,15 @@ public final class KotlinPanacheResourceProcessor { org.objectweb.asm.Type.getType(PanacheEntityBase.class), org.objectweb.asm.Type.getType(PanacheEntity.class), org.objectweb.asm.Type.getType(PanacheCompanion.class)); + public static final List PRIMITIVE_TYPES = asList( + org.objectweb.asm.Type.getType(Void.class), + org.objectweb.asm.Type.getType(Boolean.class), + org.objectweb.asm.Type.getType(Character.class), + org.objectweb.asm.Type.getType(Byte.class), + org.objectweb.asm.Type.getType(Short.class), + org.objectweb.asm.Type.getType(Integer.class), + org.objectweb.asm.Type.getType(Float.class), + org.objectweb.asm.Type.getType(Long.class)); static org.objectweb.asm.Type sanitize(org.objectweb.asm.Type[] argumentTypes) { org.objectweb.asm.Type primitiveReplaced = null; @@ -90,6 +98,10 @@ static org.objectweb.asm.Type sanitize(org.objectweb.asm.Type[] argumentTypes) { return primitiveReplaced; } + static org.objectweb.asm.Type autobox(org.objectweb.asm.Type primitive) { + return PRIMITIVE_TYPES.get(primitive.getSort()); + } + @NotNull static String toBinarySignature(Class type) { return org.objectweb.asm.Type.getType(type).getDescriptor(); @@ -135,16 +147,16 @@ void build(CombinedIndexBuildItem index, KotlinPanacheRepositoryEnhancer daoEnhancer = new KotlinPanacheRepositoryEnhancer(index.getIndex()); Set daoClasses = new HashSet<>(); - for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(PANACHE_REPOSITORY_BASE)) { + for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(PANACHE_REPOSITORY_BASE_DOTNAME)) { // Skip PanacheRepository - if (classInfo.name().equals(PANACHE_REPOSITORY)) + if (classInfo.name().equals(PANACHE_REPOSITORY_DOTNAME)) continue; - if (daoEnhancer.skipRepository(classInfo)) + if (PanacheRepositoryEnhancer.skipRepository(classInfo)) continue; daoClasses.add(classInfo.name().toString()); } - for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(PANACHE_REPOSITORY)) { - if (daoEnhancer.skipRepository(classInfo)) + for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(PANACHE_REPOSITORY_DOTNAME)) { + if (PanacheRepositoryEnhancer.skipRepository(classInfo)) continue; daoClasses.add(classInfo.name().toString()); } @@ -159,15 +171,15 @@ void build(CombinedIndexBuildItem index, // Note that we do this in two passes because for some reason Jandex does not give us subtypes // of PanacheEntity if we ask for subtypes of PanacheEntityBase // NOTE: we don't skip abstract/generic entities because they still need accessors - for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(PANACHE_COMPANION)) { - if (classInfo.name().equals(PANACHE_ENTITY)) + for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(PANACHE_COMPANION_DOTNAME)) { + if (classInfo.name().equals(PANACHE_ENTITY_DOTNAME)) continue; if (modelClasses.add(classInfo.name().toString())) { transformers.produce(new BytecodeTransformerBuildItem(classInfo.name().toString(), companionEnhancer)); } } - for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(PANACHE_ENTITY_BASE)) { - if (classInfo.name().equals(PANACHE_ENTITY)) + for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(PANACHE_ENTITY_BASE_DOTNAME)) { + if (classInfo.name().equals(PANACHE_ENTITY_DOTNAME)) continue; if (modelClasses.add(classInfo.name().toString())) { entityEnhancer.collectFields(classInfo); diff --git a/extensions/panache/hibernate-orm-panache-kotlin/runtime/pom.xml b/extensions/panache/hibernate-orm-panache-kotlin/runtime/pom.xml index a9890fa2d479b..7b468b79fa036 100644 --- a/extensions/panache/hibernate-orm-panache-kotlin/runtime/pom.xml +++ b/extensions/panache/hibernate-orm-panache-kotlin/runtime/pom.xml @@ -63,7 +63,6 @@ org.jetbrains.kotlin kotlin-reflect ${kotlin.version} - test org.ow2.asm diff --git a/extensions/panache/hibernate-orm-panache-kotlin/runtime/src/main/kotlin/io/quarkus/hibernate/orm/panache/kotlin/PanacheCompanion.kt b/extensions/panache/hibernate-orm-panache-kotlin/runtime/src/main/kotlin/io/quarkus/hibernate/orm/panache/kotlin/PanacheCompanion.kt index beaf6597c9e6c..c230798d60e58 100644 --- a/extensions/panache/hibernate-orm-panache-kotlin/runtime/src/main/kotlin/io/quarkus/hibernate/orm/panache/kotlin/PanacheCompanion.kt +++ b/extensions/panache/hibernate-orm-panache-kotlin/runtime/src/main/kotlin/io/quarkus/hibernate/orm/panache/kotlin/PanacheCompanion.kt @@ -56,7 +56,7 @@ interface PanacheCompanion { fun find(query: String, vararg params: Any): PanacheQuery = injectionMissing() /** - * Find entities using a query and the given sort options with optional indexed parameters. + * Find entities using a query and the given sort options, with optional indexed parameters. * * @param query a query string * @param sort the sort strategy to use diff --git a/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheHibernateResourceProcessor.java b/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheHibernateResourceProcessor.java index f8b88fad31145..e1c600b6add26 100644 --- a/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheHibernateResourceProcessor.java +++ b/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheHibernateResourceProcessor.java @@ -40,6 +40,7 @@ import io.quarkus.panache.common.deployment.PanacheFieldAccessEnhancer; import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; import io.quarkus.panache.common.deployment.PanacheMethodCustomizerBuildItem; +import io.quarkus.panache.common.deployment.PanacheRepositoryEnhancer; public final class PanacheHibernateResourceProcessor { @@ -116,12 +117,12 @@ void build(CombinedIndexBuildItem index, // Skip PanacheRepository if (classInfo.name().equals(DOTNAME_PANACHE_REPOSITORY)) continue; - if (daoEnhancer.skipRepository(classInfo)) + if (PanacheRepositoryEnhancer.skipRepository(classInfo)) continue; daoClasses.add(classInfo.name().toString()); } for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(DOTNAME_PANACHE_REPOSITORY)) { - if (daoEnhancer.skipRepository(classInfo)) + if (PanacheRepositoryEnhancer.skipRepository(classInfo)) continue; daoClasses.add(classInfo.name().toString()); } diff --git a/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheJpaEntityEnhancer.java b/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheJpaEntityEnhancer.java index df2ee5f216cdc..b66738d056c75 100644 --- a/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheJpaEntityEnhancer.java +++ b/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheJpaEntityEnhancer.java @@ -24,7 +24,6 @@ import io.quarkus.panache.common.deployment.MetamodelInfo; import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; -import io.quarkus.panache.common.deployment.visitors.PanacheEntityClassVisitor; public class PanacheJpaEntityEnhancer extends PanacheEntityEnhancer>> { @@ -42,14 +41,13 @@ public class PanacheJpaEntityEnhancer extends PanacheEntityEnhancer methodCustomizers) { - super(index, methodCustomizers); + super(index, PanacheHibernateResourceProcessor.DOTNAME_PANACHE_ENTITY_BASE, methodCustomizers); modelInfo = new MetamodelInfo<>(); } @Override public ClassVisitor apply(String className, ClassVisitor outputClassVisitor) { - return new PanacheJpaEntityClassVisitor(className, outputClassVisitor, modelInfo, - indexView.getClassByName(PanacheHibernateResourceProcessor.DOTNAME_PANACHE_ENTITY_BASE), + return new PanacheJpaEntityClassVisitor(className, outputClassVisitor, modelInfo, panacheEntityBaseClassInfo, indexView.getClassByName(DotName.createSimple(className)), methodCustomizers); } @@ -74,7 +72,7 @@ protected String getModelDescriptor() { } @Override - protected String getPanacheOperationsInternalName() { + protected String getPanacheOperationsBinaryName() { return JPA_OPERATIONS_BINARY_NAME; } diff --git a/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheJpaRepositoryEnhancer.java b/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheJpaRepositoryEnhancer.java index 29ef3e9d485b5..16dace472aeba 100644 --- a/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheJpaRepositoryEnhancer.java +++ b/extensions/panache/hibernate-orm-panache/deployment/src/main/java/io/quarkus/hibernate/orm/panache/deployment/PanacheJpaRepositoryEnhancer.java @@ -1,13 +1,14 @@ package io.quarkus.hibernate.orm.panache.deployment; +import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.IndexView; import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; import io.quarkus.hibernate.orm.panache.PanacheRepository; import io.quarkus.hibernate.orm.panache.PanacheRepositoryBase; import io.quarkus.panache.common.deployment.PanacheRepositoryEnhancer; -import io.quarkus.panache.common.deployment.visitors.PanacheRepositoryClassVisitor; public class PanacheJpaRepositoryEnhancer extends PanacheRepositoryEnhancer { @@ -21,14 +22,15 @@ public PanacheJpaRepositoryEnhancer(IndexView index) { @Override public ClassVisitor apply(String className, ClassVisitor outputClassVisitor) { - return new PanacheJpaRepositoryClassVisitor(className, outputClassVisitor, + return new PanacheJpaRepositoryClassVisitor(className, outputClassVisitor, panacheRepositoryBaseClassInfo, this.indexView); } static class PanacheJpaRepositoryClassVisitor extends PanacheRepositoryClassVisitor { - public PanacheJpaRepositoryClassVisitor(String className, ClassVisitor outputClassVisitor, IndexView indexView) { - super(className, outputClassVisitor, indexView); + public PanacheJpaRepositoryClassVisitor(String className, ClassVisitor outputClassVisitor, + ClassInfo panacheRepositoryBaseClassInfo, IndexView indexView) { + super(className, outputClassVisitor, panacheRepositoryBaseClassInfo, indexView); } @Override @@ -42,8 +44,19 @@ protected DotName getPanacheRepositoryBaseDotName() { } @Override - protected String getPanacheOperationsInternalName() { + protected String getPanacheOperationsBinaryName() { return PanacheJpaEntityEnhancer.JPA_OPERATIONS_BINARY_NAME; } + + @Override + protected void injectModel(MethodVisitor mv) { + // inject Class + mv.visitLdcInsn(entityType); + } + + @Override + protected String getModelDescriptor() { + return "Ljava/lang/Class;"; + } } } diff --git a/extensions/panache/mongodb-panache-common/deployment/pom.xml b/extensions/panache/mongodb-panache-common/deployment/pom.xml deleted file mode 100644 index c3c794379512d..0000000000000 --- a/extensions/panache/mongodb-panache-common/deployment/pom.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - quarkus-mongodb-panache-common-parent - io.quarkus - 999-SNAPSHOT - ../ - - 4.0.0 - - quarkus-mongodb-panache-common-deployment - Quarkus - MongoDB with Panache - Common Deployment - - - - io.quarkus - quarkus-core-deployment - - - io.quarkus - quarkus-jsonb-spi - - - io.quarkus - quarkus-jackson-spi - - - io.quarkus - quarkus-panache-common-deployment - - - io.quarkus - quarkus-mongodb-client-deployment - - - io.quarkus - quarkus-mongodb-panache-common - - - - io.quarkus - quarkus-junit5-internal - test - - - - - - - maven-compiler-plugin - - - - io.quarkus - quarkus-extension-processor - ${project.version} - - - - - - - - - \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/BasePanacheMongoResourceProcessor.java b/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/BasePanacheMongoResourceProcessor.java deleted file mode 100644 index ed1f5649ef18c..0000000000000 --- a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/BasePanacheMongoResourceProcessor.java +++ /dev/null @@ -1,384 +0,0 @@ -package io.quarkus.mongodb.panache.deployment; - -import static io.quarkus.deployment.util.JandexUtil.resolveTypeParameters; -import static org.jboss.jandex.DotName.createSimple; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; - -import org.bson.codecs.pojo.annotations.BsonId; -import org.bson.codecs.pojo.annotations.BsonIgnore; -import org.bson.codecs.pojo.annotations.BsonProperty; -import org.bson.types.ObjectId; -import org.jboss.jandex.AnnotationInstance; -import org.jboss.jandex.AnnotationValue; -import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.CompositeIndex; -import org.jboss.jandex.DotName; -import org.jboss.jandex.FieldInfo; -import org.jboss.jandex.IndexView; -import org.jboss.jandex.Indexer; -import org.jboss.jandex.MethodInfo; -import org.jboss.jandex.Type; - -import io.quarkus.arc.deployment.ValidationPhaseBuildItem; -import io.quarkus.builder.BuildException; -import io.quarkus.deployment.annotations.BuildProducer; -import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.deployment.annotations.ExecutionTime; -import io.quarkus.deployment.annotations.Record; -import io.quarkus.deployment.bean.JavaBeanUtil; -import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem; -import io.quarkus.deployment.builditem.ApplicationIndexBuildItem; -import io.quarkus.deployment.builditem.BytecodeTransformerBuildItem; -import io.quarkus.deployment.builditem.CombinedIndexBuildItem; -import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; -import io.quarkus.deployment.builditem.nativeimage.ReflectiveHierarchyBuildItem; -import io.quarkus.deployment.index.IndexingUtil; -import io.quarkus.deployment.util.JandexUtil; -import io.quarkus.jackson.spi.JacksonModuleBuildItem; -import io.quarkus.jsonb.spi.JsonbDeserializerBuildItem; -import io.quarkus.jsonb.spi.JsonbSerializerBuildItem; -import io.quarkus.mongodb.deployment.MongoClientNameBuildItem; -import io.quarkus.mongodb.deployment.MongoUnremovableClientsBuildItem; -import io.quarkus.mongodb.panache.MongoEntity; -import io.quarkus.mongodb.panache.PanacheMongoRecorder; -import io.quarkus.mongodb.panache.ProjectionFor; -import io.quarkus.mongodb.panache.jackson.ObjectIdDeserializer; -import io.quarkus.mongodb.panache.jackson.ObjectIdSerializer; -import io.quarkus.panache.common.deployment.PanacheEntityClassesBuildItem; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; -import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; -import io.quarkus.panache.common.deployment.PanacheMethodCustomizerBuildItem; -import io.quarkus.panache.common.deployment.PanacheRepositoryEnhancer; - -public abstract class BasePanacheMongoResourceProcessor { - public static final DotName BSON_ID = createSimple(BsonId.class.getName()); - public static final DotName BSON_IGNORE = createSimple(BsonIgnore.class.getName()); - public static final DotName BSON_PROPERTY = createSimple(BsonProperty.class.getName()); - public static final DotName MONGO_ENTITY = createSimple(MongoEntity.class.getName()); - public static final DotName OBJECT_ID = createSimple(ObjectId.class.getName()); - public static final String OBJECT_SIGNATURE = toBinarySignature(Object.class); - public static final DotName PROJECTION_FOR = createSimple(ProjectionFor.class.getName()); - - protected static String toBinarySignature(Class type) { - return org.objectweb.asm.Type.getType(type).getDescriptor(); - } - - @BuildStep - public void buildImperative(CombinedIndexBuildItem index, ApplicationIndexBuildItem applicationIndex, - BuildProducer transformers, - BuildProducer reflectiveClass, - BuildProducer propertyMappingClass, - List methodCustomizersBuildItems) { - - List methodCustomizers = methodCustomizersBuildItems.stream() - .map(bi -> bi.getMethodCustomizer()).collect(Collectors.toList()); - - processTypes(index, transformers, reflectiveClass, propertyMappingClass, getImperativeTypeBundle(), - createRepositoryEnhancer(index), createEntityEnhancer(index, methodCustomizers)); - } - - @BuildStep - public void buildReactive(CombinedIndexBuildItem index, - BuildProducer reflectiveClass, - BuildProducer propertyMappingClass, - BuildProducer transformers, - List methodCustomizersBuildItems) { - List methodCustomizers = methodCustomizersBuildItems.stream() - .map(bi -> bi.getMethodCustomizer()).collect(Collectors.toList()); - - processTypes(index, transformers, reflectiveClass, propertyMappingClass, getReactiveTypeBundle(), - createReactiveRepositoryEnhancer(index), createReactiveEntityEnhancer(index, methodCustomizers)); - } - - @BuildStep - @Record(ExecutionTime.STATIC_INIT) - protected void buildReplacementMap(List propertyMappingClasses, CombinedIndexBuildItem index, - PanacheMongoRecorder recorder) { - Map> replacementMap = new ConcurrentHashMap<>(); - for (PropertyMappingClassBuildStep classToMap : propertyMappingClasses) { - DotName dotName = createSimple(classToMap.getClassName()); - ClassInfo classInfo = index.getIndex().getClassByName(dotName); - if (classInfo != null) { - // only compute field replacement for types inside the index - Map classReplacementMap = replacementMap.computeIfAbsent(classToMap.getClassName(), - className -> computeReplacement(classInfo)); - if (classToMap.getAliasClassName() != null) { - // also register the replacement map for the projection classes - replacementMap.put(classToMap.getAliasClassName(), classReplacementMap); - } - } - } - - recorder.setReplacementCache(replacementMap); - } - - private Map computeReplacement(ClassInfo classInfo) { - Map replacementMap = new HashMap<>(); - for (FieldInfo field : classInfo.fields()) { - AnnotationInstance bsonProperty = field.annotation(BSON_PROPERTY); - if (bsonProperty != null) { - replacementMap.put(field.name(), bsonProperty.value().asString()); - } - } - for (MethodInfo method : classInfo.methods()) { - if (method.name().startsWith("get")) { - // we try to replace also for getter - AnnotationInstance bsonProperty = method.annotation(BSON_PROPERTY); - if (bsonProperty != null) { - String fieldName = JavaBeanUtil.decapitalize(method.name().substring(3)); - replacementMap.put(fieldName, bsonProperty.value().asString()); - } - } - } - return replacementMap.isEmpty() ? Collections.emptyMap() : replacementMap; - } - - protected abstract PanacheEntityEnhancer createEntityEnhancer(CombinedIndexBuildItem index, - List methodCustomizers); - - protected abstract PanacheEntityEnhancer createReactiveEntityEnhancer(CombinedIndexBuildItem index, - List methodCustomizers); - - protected abstract PanacheRepositoryEnhancer createReactiveRepositoryEnhancer(CombinedIndexBuildItem index); - - protected abstract PanacheRepositoryEnhancer createRepositoryEnhancer(CombinedIndexBuildItem index); - - private void extractMappings(Map classPropertyMapping, ClassInfo target, CombinedIndexBuildItem index) { - for (FieldInfo fieldInfo : target.fields()) { - if (fieldInfo.hasAnnotation(BSON_PROPERTY)) { - AnnotationInstance bsonProperty = fieldInfo.annotation(BSON_PROPERTY); - classPropertyMapping.put(fieldInfo.name(), bsonProperty.value().asString()); - } - } - for (MethodInfo methodInfo : target.methods()) { - if (methodInfo.hasAnnotation(BSON_PROPERTY)) { - AnnotationInstance bsonProperty = methodInfo.annotation(BSON_PROPERTY); - classPropertyMapping.put(methodInfo.name(), bsonProperty.value().asString()); - } - } - - // climb up the hierarchy of types - if (!target.superClassType().name().equals(JandexUtil.DOTNAME_OBJECT)) { - Type superType = target.superClassType(); - ClassInfo superClass = index.getIndex().getClassByName(superType.name()); - extractMappings(classPropertyMapping, superClass, index); - } - } - - @BuildStep - protected PanacheEntityClassesBuildItem findEntityClasses(List entityClasses) { - if (!entityClasses.isEmpty()) { - Set ret = new HashSet<>(); - for (PanacheMongoEntityClassBuildItem entityClass : entityClasses) { - ret.add(entityClass.get().name().toString()); - } - return new PanacheEntityClassesBuildItem(ret); - } - return null; - } - - protected abstract TypeBundle getImperativeTypeBundle(); - - protected abstract TypeBundle getReactiveTypeBundle(); - - @BuildStep - protected void handleProjectionFor(CombinedIndexBuildItem index, - BuildProducer propertyMappingClass, - BuildProducer transformers) { - // manage @BsonProperty for the @ProjectionFor annotation - Map> propertyMapping = new HashMap<>(); - for (AnnotationInstance annotationInstance : index.getIndex().getAnnotations(PROJECTION_FOR)) { - Type targetClass = annotationInstance.value().asClass(); - ClassInfo target = index.getIndex().getClassByName(targetClass.name()); - Map classPropertyMapping = new HashMap<>(); - extractMappings(classPropertyMapping, target, index); - propertyMapping.put(targetClass.name(), classPropertyMapping); - } - for (AnnotationInstance annotationInstance : index.getIndex().getAnnotations(PROJECTION_FOR)) { - Type targetClass = annotationInstance.value().asClass(); - Map targetPropertyMapping = propertyMapping.get(targetClass.name()); - if (targetPropertyMapping != null && !targetPropertyMapping.isEmpty()) { - ClassInfo info = annotationInstance.target().asClass(); - ProjectionForEnhancer fieldEnhancer = new ProjectionForEnhancer(targetPropertyMapping); - transformers.produce(new BytecodeTransformerBuildItem(info.name().toString(), fieldEnhancer)); - } - - // Register for building the property mapping cache - propertyMappingClass - .produce(new PropertyMappingClassBuildStep(targetClass.name().toString(), - annotationInstance.target().asClass().name().toString())); - } - } - - @BuildStep - public void mongoClientNames(ApplicationArchivesBuildItem applicationArchivesBuildItem, - BuildProducer mongoClientName) { - Set values = new HashSet<>(); - IndexView indexView = applicationArchivesBuildItem.getRootArchive().getIndex(); - Collection instances = indexView.getAnnotations(MONGO_ENTITY); - for (AnnotationInstance annotation : instances) { - AnnotationValue clientName = annotation.value("clientName"); - if ((clientName != null) && !clientName.asString().isEmpty()) { - values.add(clientName.asString()); - } - } - for (String value : values) { - // we don't want the qualifier @MongoClientName qualifier added - // as these clients will only be looked up programmatically via name - // see MongoOperations#mongoClient - mongoClientName.produce(new MongoClientNameBuildItem(value, false)); - } - } - - protected void processEntities(CombinedIndexBuildItem index, - BuildProducer transformers, BuildProducer reflectiveClass, - BuildProducer propertyMappingClass, - PanacheEntityEnhancer entityEnhancer, TypeBundle typeBundle) { - - Set modelClasses = new HashSet<>(); - // Note that we do this in two passes because for some reason Jandex does not give us subtypes - // of PanacheMongoEntity if we ask for subtypes of PanacheMongoEntityBase - for (ClassInfo classInfo : index.getIndex().getAllKnownSubclasses(typeBundle.entityBase().dotName())) { - if (classInfo.name().equals(typeBundle.entity().dotName())) { - continue; - } - if (modelClasses.add(classInfo.name().toString())) - entityEnhancer.collectFields(classInfo); - } - for (ClassInfo classInfo : index.getIndex().getAllKnownSubclasses(typeBundle.entity().dotName())) { - if (modelClasses.add(classInfo.name().toString())) - entityEnhancer.collectFields(classInfo); - } - - // iterate over all the entity classes - for (String modelClass : modelClasses) { - transformers.produce(new BytecodeTransformerBuildItem(modelClass, entityEnhancer)); - - //register for reflection entity classes - reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, modelClass)); - - // Register for building the property mapping cache - propertyMappingClass.produce(new PropertyMappingClassBuildStep(modelClass)); - } - } - - protected void processRepositories(CombinedIndexBuildItem index, - BuildProducer transformers, - BuildProducer reflectiveClass, - BuildProducer propertyMappingClass, - PanacheRepositoryEnhancer repositoryEnhancer, TypeBundle typeBundle) { - - Set daoClasses = new HashSet<>(); - Set daoTypeParameters = new HashSet<>(); - for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(typeBundle.repositoryBase().dotName())) { - // Skip PanacheMongoRepository and abstract repositories - if (classInfo.name().equals(typeBundle.repository().dotName()) || repositoryEnhancer.skipRepository(classInfo)) { - continue; - } - daoClasses.add(classInfo.name().toString()); - daoTypeParameters.addAll( - resolveTypeParameters(classInfo.name(), typeBundle.repositoryBase().dotName(), index.getIndex())); - } - for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(typeBundle.repository().dotName())) { - if (repositoryEnhancer.skipRepository(classInfo)) { - continue; - } - daoClasses.add(classInfo.name().toString()); - daoTypeParameters.addAll( - resolveTypeParameters(classInfo.name(), typeBundle.repositoryBase().dotName(), index.getIndex())); - } - for (String daoClass : daoClasses) { - transformers.produce(new BytecodeTransformerBuildItem(daoClass, repositoryEnhancer)); - } - - for (Type parameterType : daoTypeParameters) { - // Register for reflection the type parameters of the repository: this should be the entity class and the ID class - reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, parameterType.name().toString())); - - // Register for building the property mapping cache - propertyMappingClass.produce(new PropertyMappingClassBuildStep(parameterType.name().toString())); - } - } - - protected void processTypes(CombinedIndexBuildItem index, - BuildProducer transformers, - BuildProducer reflectiveClass, - BuildProducer propertyMappingClass, - TypeBundle typeBundle, PanacheRepositoryEnhancer repositoryEnhancer, - PanacheEntityEnhancer entityEnhancer) { - - processRepositories(index, transformers, reflectiveClass, propertyMappingClass, - repositoryEnhancer, typeBundle); - processEntities(index, transformers, reflectiveClass, propertyMappingClass, - entityEnhancer, typeBundle); - } - - @BuildStep - protected ReflectiveHierarchyBuildItem registerForReflection(CombinedIndexBuildItem index) { - Indexer indexer = new Indexer(); - Set additionalIndex = new HashSet<>(); - IndexingUtil.indexClass(ObjectId.class.getName(), indexer, index.getIndex(), additionalIndex, - BasePanacheMongoResourceProcessor.class.getClassLoader()); - CompositeIndex compositeIndex = CompositeIndex.create(index.getIndex(), indexer.complete()); - Type type = Type.create(OBJECT_ID, Type.Kind.CLASS); - return new ReflectiveHierarchyBuildItem(type, compositeIndex); - } - - @BuildStep - protected void registerJacksonSerDeser(BuildProducer customSerDeser) { - customSerDeser.produce( - new JacksonModuleBuildItem.Builder("ObjectIdModule") - .add(ObjectIdSerializer.class.getName(), - ObjectIdDeserializer.class.getName(), - ObjectId.class.getName()) - .build()); - } - - @BuildStep - protected void registerJsonbSerDeser(BuildProducer jsonbSerializers, - BuildProducer jsonbDeserializers) { - jsonbSerializers - .produce(new JsonbSerializerBuildItem(io.quarkus.mongodb.panache.jsonb.ObjectIdSerializer.class.getName())); - jsonbDeserializers - .produce(new JsonbDeserializerBuildItem(io.quarkus.mongodb.panache.jsonb.ObjectIdDeserializer.class.getName())); - } - - @BuildStep - public void unremovableClients(BuildProducer unremovable) { - unremovable.produce(new MongoUnremovableClientsBuildItem()); - } - - @BuildStep - protected ValidationPhaseBuildItem.ValidationErrorBuildItem validate(ValidationPhaseBuildItem validationPhase, - CombinedIndexBuildItem index) throws BuildException { - // we verify that no ID fields are defined (via @BsonId) when extending PanacheMongoEntity or ReactivePanacheMongoEntity - for (AnnotationInstance annotationInstance : index.getIndex().getAnnotations(BSON_ID)) { - ClassInfo info = JandexUtil.getEnclosingClass(annotationInstance); - if (JandexUtil.isSubclassOf(index.getIndex(), info, - getImperativeTypeBundle().entity().dotName())) { - BuildException be = new BuildException("You provide a MongoDB identifier via @BsonId inside '" + info.name() + - "' but one is already provided by PanacheMongoEntity, " + - "your class should extend PanacheMongoEntityBase instead, or use the id provided by PanacheMongoEntity", - Collections.emptyList()); - return new ValidationPhaseBuildItem.ValidationErrorBuildItem(be); - } else if (JandexUtil.isSubclassOf(index.getIndex(), info, - getReactiveTypeBundle().entity().dotName())) { - BuildException be = new BuildException("You provide a MongoDB identifier via @BsonId inside '" + info.name() + - "' but one is already provided by ReactivePanacheMongoEntity, " + - "your class should extend ReactivePanacheMongoEntityBase instead, or use the id provided by ReactivePanacheMongoEntity", - Collections.emptyList()); - return new ValidationPhaseBuildItem.ValidationErrorBuildItem(be); - } - } - return null; - } -} diff --git a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ByteCodeType.java b/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ByteCodeType.java deleted file mode 100644 index 498bd126b2edd..0000000000000 --- a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ByteCodeType.java +++ /dev/null @@ -1,57 +0,0 @@ -package io.quarkus.mongodb.panache.deployment; - -import static org.jboss.jandex.DotName.createSimple; -import static org.objectweb.asm.Type.getType; - -import java.util.StringJoiner; - -import org.jboss.jandex.DotName; -import org.objectweb.asm.Type; - -import io.quarkus.deployment.util.AsmUtil; - -public class ByteCodeType { - private final Type type; - - public ByteCodeType(Type type) { - this.type = type; - } - - public ByteCodeType(Class type) { - this.type = getType(type); - } - - public ByteCodeType(org.jboss.jandex.Type type) { - String typeDescriptor = type.kind() == org.jboss.jandex.Type.Kind.PRIMITIVE - ? type.toString() - : "L" + type.name().toString().replace('.', '/') + ";"; - this.type = getType(typeDescriptor); - } - - public String descriptor() { - return type.getDescriptor(); - } - - public DotName dotName() { - return createSimple(type.getClassName()); - } - - public String internalName() { - return type.getInternalName(); - } - - @Override - public String toString() { - return new StringJoiner(", ", ByteCodeType.class.getSimpleName() + "[", "]") - .add(type.toString()) - .toString(); - } - - public Type type() { - return this.type; - } - - public ByteCodeType unbox() { - return new ByteCodeType(AsmUtil.WRAPPER_TO_PRIMITIVE.getOrDefault(type, type)); - } -} diff --git a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/TypeBundle.java b/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/TypeBundle.java deleted file mode 100644 index a0d5f99671896..0000000000000 --- a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/TypeBundle.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.quarkus.mongodb.panache.deployment; - -public interface TypeBundle { - ByteCodeType entity(); - - ByteCodeType entityBase(); - - ByteCodeType entityBaseCompanion(); - - ByteCodeType entityCompanion(); - - ByteCodeType entityCompanionBase(); - - ByteCodeType operations(); - - ByteCodeType queryType(); - - ByteCodeType repository(); - - ByteCodeType repositoryBase(); - - ByteCodeType updateType(); -} diff --git a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/visitors/PanacheMongoEntityClassVisitor.java b/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/visitors/PanacheMongoEntityClassVisitor.java deleted file mode 100644 index a9448f118af45..0000000000000 --- a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/visitors/PanacheMongoEntityClassVisitor.java +++ /dev/null @@ -1,128 +0,0 @@ -package io.quarkus.mongodb.panache.deployment.visitors; - -import static io.quarkus.deployment.util.AsmUtil.getDescriptor; -import static io.quarkus.mongodb.panache.deployment.BasePanacheMongoResourceProcessor.OBJECT_SIGNATURE; -import static java.util.Arrays.asList; -import static org.objectweb.asm.Opcodes.CHECKCAST; -import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; - -import java.util.List; -import java.util.StringJoiner; -import java.util.function.Function; - -import org.jboss.jandex.AnnotationInstance; -import org.jboss.jandex.AnnotationValue; -import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.MethodInfo; -import org.jboss.jandex.Type; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -import io.quarkus.deployment.util.AsmUtil; -import io.quarkus.mongodb.panache.deployment.ByteCodeType; -import io.quarkus.mongodb.panache.deployment.TypeBundle; -import io.quarkus.panache.common.deployment.EntityField; -import io.quarkus.panache.common.deployment.EntityModel; -import io.quarkus.panache.common.deployment.MetamodelInfo; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; -import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; -import io.quarkus.panache.common.deployment.visitors.PanacheEntityClassVisitor; - -public class PanacheMongoEntityClassVisitor extends PanacheEntityClassVisitor { - private static final ByteCodeType CLASS = new ByteCodeType(Class.class); - - private final TypeBundle typeBundle; - - public PanacheMongoEntityClassVisitor(String className, - ClassVisitor outputClassVisitor, - MetamodelInfo> modelInfo, - ClassInfo panacheEntityBaseClassInfo, - ClassInfo entityInfo, - List methodCustomizers, - TypeBundle typeBundle) { - super(className, outputClassVisitor, modelInfo, panacheEntityBaseClassInfo, entityInfo, methodCustomizers); - this.typeBundle = typeBundle; - } - - @Override - protected void generateMethod(MethodInfo method, AnnotationValue targetReturnTypeErased) { - String descriptor = AsmUtil.getDescriptor(method, name -> null); - String signature = AsmUtil.getSignature(method, name -> null); - List parameters = method.parameters(); - - MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, - method.name(), - descriptor, - signature, - null); - for (int i = 0; i < parameters.size(); i++) { - mv.visitParameter(method.parameterName(i), 0 /* modifiers */); - } - mv.visitCode(); - for (PanacheMethodCustomizer customizer : methodCustomizers) { - customizer.customize(thisClass, method, mv); - } - mv.visitFieldInsn(Opcodes.GETSTATIC, thisClass.getInternalName(), "operations", - typeBundle.operations().descriptor()); - injectModel(mv); - for (int i = 0; i < parameters.size(); i++) { - mv.visitIntInsn(Opcodes.ALOAD, i); - } - invokeOperation(mv, method, method.parameters()); - mv.visitMaxs(0, 0); - mv.visitEnd(); - - } - - private void invokeOperation(MethodVisitor mv, MethodInfo method, List parameters) { - String operationDescriptor; - Function argMapper = type -> null; - - AnnotationInstance bridge = method.annotation(PanacheEntityEnhancer.DOTNAME_GENERATE_BRIDGE); - AnnotationValue targetReturnTypeErased = bridge.value("targetReturnTypeErased"); - boolean erased = targetReturnTypeErased != null && targetReturnTypeErased.asBoolean(); - - StringJoiner joiner = new StringJoiner("", "(", ")"); - joiner.add(CLASS.descriptor()); - for (Type parameter : parameters) { - joiner.add(getDescriptor(parameter, argMapper)); - } - - List names = asList(typeBundle.queryType().dotName().toString(), - typeBundle.updateType().dotName().toString()); - operationDescriptor = joiner + - (erased || names.contains(method.returnType().name().toString()) - ? OBJECT_SIGNATURE - : getDescriptor(method.returnType(), argMapper)); - - mv.visitMethodInsn(INVOKEVIRTUAL, typeBundle.operations().internalName(), method.name(), - operationDescriptor, false); - if (method.returnType().kind() != Type.Kind.PRIMITIVE) { - Type type = method.returnType(); - String cast; - if (erased) { - cast = thisClass.getInternalName(); - } else { - cast = type.name().toString().replace('.', '/'); - } - mv.visitTypeInsn(CHECKCAST, cast); - } - mv.visitInsn(AsmUtil.getReturnInstruction(method.returnType())); - } - - @Override - protected String getPanacheOperationsInternalName() { - return typeBundle.operations().internalName(); - } - - @Override - protected void generateAccessorSetField(MethodVisitor mv, EntityField field) { - mv.visitFieldInsn(Opcodes.PUTFIELD, thisClass.getInternalName(), field.name, field.descriptor); - } - - @Override - protected void generateAccessorGetField(MethodVisitor mv, EntityField field) { - mv.visitFieldInsn(Opcodes.GETFIELD, thisClass.getInternalName(), field.name, field.descriptor); - } -} diff --git a/extensions/panache/mongodb-panache-common/pom.xml b/extensions/panache/mongodb-panache-common/pom.xml deleted file mode 100644 index 9510146247760..0000000000000 --- a/extensions/panache/mongodb-panache-common/pom.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - quarkus-build-parent - io.quarkus - 999-SNAPSHOT - ../../../build-parent/pom.xml - - 4.0.0 - - quarkus-mongodb-panache-common-parent - Quarkus - MongoDB with Panache - Common - pom - - runtime - deployment - - \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-common/runtime/pom.xml b/extensions/panache/mongodb-panache-common/runtime/pom.xml deleted file mode 100644 index b27a973cba4d0..0000000000000 --- a/extensions/panache/mongodb-panache-common/runtime/pom.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - quarkus-mongodb-panache-common-parent - io.quarkus - 999-SNAPSHOT - ../ - - 4.0.0 - - quarkus-mongodb-panache-common - Quarkus - MongoDB with Panache - Common Runtime - - - - io.quarkus - quarkus-core - - - io.quarkus - quarkus-panache-common - - - io.quarkus - quarkus-mongodb-client - - - io.quarkus - quarkus-panacheql - - - - - io.quarkus - quarkus-jsonb - true - - - - - io.quarkus - quarkus-jackson - true - - - org.junit.jupiter - junit-jupiter - test - - - org.junit.jupiter - junit-jupiter-api - test - - - - - - - maven-compiler-plugin - - -proc:none - - - - io.quarkus - quarkus-bootstrap-maven-plugin - - - - org.jboss.jandex - jandex-maven-plugin - - - make-index - - jandex - - - - - - - - - diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/CommonReactivePanacheQueryImpl.java b/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/CommonReactivePanacheQueryImpl.java deleted file mode 100644 index b767f36126dfa..0000000000000 --- a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/CommonReactivePanacheQueryImpl.java +++ /dev/null @@ -1,238 +0,0 @@ -package io.quarkus.mongodb.panache.reactive.runtime; - -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import org.bson.Document; -import org.bson.conversions.Bson; - -import com.mongodb.client.model.Collation; - -import io.quarkus.mongodb.FindOptions; -import io.quarkus.mongodb.panache.runtime.MongoPropertyUtil; -import io.quarkus.mongodb.reactive.ReactiveMongoCollection; -import io.quarkus.panache.common.Page; -import io.quarkus.panache.common.Range; -import io.quarkus.panache.common.exception.PanacheQueryException; -import io.smallrye.mutiny.Multi; -import io.smallrye.mutiny.Uni; - -public class CommonReactivePanacheQueryImpl { - private ReactiveMongoCollection collection; - private Bson mongoQuery; - private Bson sort; - private Bson projections; - - private Page page; - private Uni count; - - private Range range; - - private Collation collation; - - public CommonReactivePanacheQueryImpl(ReactiveMongoCollection collection, Bson mongoQuery, Bson sort) { - this.collection = collection; - this.mongoQuery = mongoQuery; - this.sort = sort; - } - - private CommonReactivePanacheQueryImpl(CommonReactivePanacheQueryImpl previousQuery, Bson projections, Class type) { - this.collection = previousQuery.collection.withDocumentClass(type); - this.mongoQuery = previousQuery.mongoQuery; - this.sort = previousQuery.sort; - this.projections = projections; - this.page = previousQuery.page; - this.count = previousQuery.count; - this.range = previousQuery.range; - this.collation = previousQuery.collation; - } - - // Builder - - public CommonReactivePanacheQueryImpl project(Class type) { - // collect field names from public fields and getters - Set fieldNames = MongoPropertyUtil.collectFields(type); - - // create the projection document - Document projections = new Document(); - for (String fieldName : fieldNames) { - projections.append(fieldName, 1); - } - - return new CommonReactivePanacheQueryImpl(this, projections, type); - } - - @SuppressWarnings("unchecked") - public CommonReactivePanacheQueryImpl page(Page page) { - this.page = page; - this.range = null; // reset the range to be able to switch from range to page - return (CommonReactivePanacheQueryImpl) this; - } - - public CommonReactivePanacheQueryImpl page(int pageIndex, int pageSize) { - return page(Page.of(pageIndex, pageSize)); - } - - public CommonReactivePanacheQueryImpl nextPage() { - checkPagination(); - return page(page.next()); - } - - public CommonReactivePanacheQueryImpl previousPage() { - checkPagination(); - return page(page.previous()); - } - - public CommonReactivePanacheQueryImpl firstPage() { - checkPagination(); - return page(page.first()); - } - - public Uni> lastPage() { - checkPagination(); - Uni> map = pageCount().map(pageCount -> page(page.index(pageCount - 1))); - return map; - } - - public Uni hasNextPage() { - checkPagination(); - return pageCount().map(pageCount -> page.index < (pageCount - 1)); - } - - public boolean hasPreviousPage() { - checkPagination(); - return page.index > 0; - } - - public Uni pageCount() { - checkPagination(); - return count().map(count -> { - if (count == 0) - return 1; // a single page of zero results - return (int) Math.ceil((double) count / (double) page.size); - }); - } - - public Page page() { - checkPagination(); - return page; - } - - private void checkPagination() { - if (page == null) { - throw new UnsupportedOperationException( - "Cannot call a page related method, " - + "call page(Page) or page(int, int) to initiate pagination first"); - } - if (range != null) { - throw new UnsupportedOperationException("Cannot call a page related method in a ranged query, " + - "call page(Page) or page(int, int) to initiate pagination first"); - } - } - - public CommonReactivePanacheQueryImpl range(int startIndex, int lastIndex) { - this.range = Range.of(startIndex, lastIndex); - // reset the page to its default to be able to switch from page to range - this.page = null; - return (CommonReactivePanacheQueryImpl) this; - } - - public CommonReactivePanacheQueryImpl withCollation(Collation collation) { - this.collation = collation; - return (CommonReactivePanacheQueryImpl) this; - } - - // Results - - @SuppressWarnings("unchecked") - public Uni count() { - if (count == null) { - count = collection.countDocuments(mongoQuery); - } - return count; - } - - @SuppressWarnings("unchecked") - public Uni> list() { - Multi results = stream(); - return results.collectItems().asList(); - } - - @SuppressWarnings("unchecked") - public Multi stream() { - FindOptions options = buildOptions(); - return mongoQuery == null ? collection.find(options) : collection.find(mongoQuery, options); - } - - public Uni firstResult() { - Uni> optionalEntity = firstResultOptional(); - return optionalEntity.map(optional -> optional.orElse(null)); - } - - public Uni> firstResultOptional() { - FindOptions options = buildOptions(1); - Multi results = mongoQuery == null ? collection.find(options) : collection.find(mongoQuery, options); - return results.collectItems().first().map(o -> Optional.ofNullable(o)); - } - - @SuppressWarnings("unchecked") - public Uni singleResult() { - FindOptions options = buildOptions(2); - Multi results = mongoQuery == null ? collection.find(options) : collection.find(mongoQuery, options); - return results.collectItems().asList().map(list -> { - if (list.size() != 1) { - throw new PanacheQueryException("There should be only one result"); - } else { - return list.get(0); - } - }); - } - - public Uni> singleResultOptional() { - FindOptions options = buildOptions(2); - Multi results = mongoQuery == null ? collection.find(options) : collection.find(mongoQuery, options); - return results.collectItems().asList().map(list -> { - if (list.size() == 2) { - throw new PanacheQueryException("There should be no more than one result"); - } - return list.isEmpty() ? Optional.empty() : Optional.of(list.get(0)); - }); - } - - private FindOptions buildOptions() { - FindOptions options = new FindOptions(); - options.sort(sort); - if (range != null) { - // range is 0 based, so we add 1 to the limit - options.skip(range.getStartIndex()).limit(range.getLastIndex() - range.getStartIndex() + 1); - } else if (page != null) { - options.skip(page.index * page.size).limit(page.size); - } - if (projections != null) { - options.projection(this.projections); - } - if (this.collation != null) { - options.collation(collation); - } - return options; - } - - private FindOptions buildOptions(int maxResults) { - FindOptions options = new FindOptions(); - options.sort(sort); - if (range != null) { - // range is 0 based, so we add 1 to the limit - options.skip(range.getStartIndex()); - } else if (page != null) { - options.skip(page.index * page.size); - } - if (projections != null) { - options.projection(this.projections); - } - if (this.collation != null) { - options.collation(collation); - } - return options.limit(maxResults); - } -} diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/CommonPanacheQueryImpl.java b/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/CommonPanacheQueryImpl.java deleted file mode 100644 index 84b76af387ca7..0000000000000 --- a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/CommonPanacheQueryImpl.java +++ /dev/null @@ -1,229 +0,0 @@ -package io.quarkus.mongodb.panache.runtime; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Stream; - -import org.bson.Document; -import org.bson.conversions.Bson; - -import com.mongodb.client.FindIterable; -import com.mongodb.client.MongoCollection; -import com.mongodb.client.MongoCursor; -import com.mongodb.client.model.Collation; - -import io.quarkus.panache.common.Page; -import io.quarkus.panache.common.Range; -import io.quarkus.panache.common.exception.PanacheQueryException; - -public class CommonPanacheQueryImpl { - private MongoCollection collection; - private Bson mongoQuery; - private Bson sort; - private Bson projections; - - private Page page; - private Long count; - - private Range range; - - private Collation collation; - - public CommonPanacheQueryImpl(MongoCollection collection, Bson mongoQuery, Bson sort) { - this.collection = collection; - this.mongoQuery = mongoQuery; - this.sort = sort; - } - - private CommonPanacheQueryImpl(CommonPanacheQueryImpl previousQuery, Bson projections, Class documentClass) { - this.collection = previousQuery.collection.withDocumentClass(documentClass); - this.mongoQuery = previousQuery.mongoQuery; - this.sort = previousQuery.sort; - this.projections = projections; - this.page = previousQuery.page; - this.count = previousQuery.count; - this.range = previousQuery.range; - this.collation = previousQuery.collation; - } - - public CommonPanacheQueryImpl project(Class type) { - // collect field names from public fields and getters - Set fieldNames = MongoPropertyUtil.collectFields(type); - - // create the projection document - Document projections = new Document(); - for (String fieldName : fieldNames) { - projections.append(fieldName, 1); - } - - return new CommonPanacheQueryImpl<>(this, projections, type); - } - - @SuppressWarnings("unchecked") - public CommonPanacheQueryImpl page(Page page) { - this.page = page; - this.range = null; // reset the range to be able to switch from range to page - return (CommonPanacheQueryImpl) this; - } - - public CommonPanacheQueryImpl page(int pageIndex, int pageSize) { - return page(Page.of(pageIndex, pageSize)); - } - - public CommonPanacheQueryImpl nextPage() { - checkPagination(); - return page(page.next()); - } - - public CommonPanacheQueryImpl previousPage() { - checkPagination(); - return page(page.previous()); - } - - public CommonPanacheQueryImpl firstPage() { - checkPagination(); - return page(page.first()); - } - - public CommonPanacheQueryImpl lastPage() { - checkPagination(); - return page(page.index(pageCount() - 1)); - } - - public boolean hasNextPage() { - checkPagination(); - return page.index < (pageCount() - 1); - } - - public boolean hasPreviousPage() { - checkPagination(); - return page.index > 0; - } - - public int pageCount() { - checkPagination(); - long count = count(); - if (count == 0) - return 1; // a single page of zero results - return (int) Math.ceil((double) count / (double) page.size); - } - - public Page page() { - checkPagination(); - return page; - } - - private void checkPagination() { - if (page == null) { - throw new UnsupportedOperationException( - "Cannot call a page related method, " - + "call page(Page) or page(int, int) to initiate pagination first"); - } - if (range != null) { - throw new UnsupportedOperationException("Cannot call a page related method in a ranged query, " + - "call page(Page) or page(int, int) to initiate pagination first"); - } - } - - public CommonPanacheQueryImpl range(int startIndex, int lastIndex) { - this.range = Range.of(startIndex, lastIndex); - // reset the page to its default to be able to switch from page to range - this.page = null; - return (CommonPanacheQueryImpl) this; - } - - public CommonPanacheQueryImpl withCollation(Collation collation) { - this.collation = collation; - return (CommonPanacheQueryImpl) this; - } - - // Results - - @SuppressWarnings("unchecked") - public long count() { - if (count == null) { - count = collection.countDocuments(mongoQuery); - } - return count; - } - - public List list() { - return list(null); - } - - @SuppressWarnings("unchecked") - private List list(Integer limit) { - List list = new ArrayList<>(); - FindIterable find = mongoQuery == null ? collection.find() : collection.find(mongoQuery); - if (this.projections != null) { - find.projection(projections); - } - if (this.collation != null) { - find.collation(collation); - } - manageOffsets(find, limit); - MongoCursor cursor = find.sort(sort).iterator(); - - try { - while (cursor.hasNext()) { - T entity = cursor.next(); - list.add(entity); - } - } finally { - cursor.close(); - } - return list; - } - - @SuppressWarnings("unchecked") - public Stream stream() { - return (Stream) list().stream(); - } - - public T firstResult() { - List list = list(1); - return list.isEmpty() ? null : list.get(0); - } - - public Optional firstResultOptional() { - return Optional.ofNullable(firstResult()); - } - - public T singleResult() { - List list = list(2); - if (list.size() != 1) { - throw new PanacheQueryException("There should be only one result"); - } - - return list.get(0); - } - - public Optional singleResultOptional() { - List list = list(2); - if (list.size() > 1) { - throw new PanacheQueryException("There should be no more than one result"); - } - - return list.isEmpty() ? Optional.empty() : Optional.of(list.get(0)); - } - - private void manageOffsets(FindIterable find, Integer limit) { - if (range != null) { - find.skip(range.getStartIndex()); - if (limit == null) { - // range is 0 based, so we add 1 to the limit - find.limit(range.getLastIndex() - range.getStartIndex() + 1); - } - } else if (page != null) { - find.skip(page.index * page.size); - if (limit == null) { - find.limit(page.size); - } - } - if (limit != null) { - find.limit(limit); - } - } -} diff --git a/extensions/panache/mongodb-panache-kotlin/deployment/pom.xml b/extensions/panache/mongodb-panache-kotlin/deployment/pom.xml deleted file mode 100644 index d5f09d2c73332..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/deployment/pom.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - quarkus-mongodb-panache-kotlin-parent - io.quarkus - 999-SNAPSHOT - ../ - - 4.0.0 - - quarkus-mongodb-panache-kotlin-deployment - Quarkus - MongoDB with Panache - Kotlin Deployment - - - - io.quarkus - quarkus-mongodb-panache-kotlin - - - io.quarkus - quarkus-mongodb-panache-common-deployment - - - io.quarkus - quarkus-mongodb-client-deployment - - - io.quarkus - quarkus-jsonb-spi - - - io.quarkus - quarkus-jackson-spi - - - - io.quarkus - quarkus-junit5-internal - test - - - - - - - maven-compiler-plugin - - - - io.quarkus - quarkus-extension-processor - ${project.version} - - - - - - - - - \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinGenerator.java b/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinGenerator.java deleted file mode 100644 index 51967b9c7d08b..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinGenerator.java +++ /dev/null @@ -1,205 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.deployment; - -import static io.quarkus.deployment.util.AsmUtil.getDescriptor; -import static io.quarkus.deployment.util.AsmUtil.getSignature; -import static io.quarkus.mongodb.panache.deployment.BasePanacheMongoResourceProcessor.OBJECT_SIGNATURE; -import static java.util.Arrays.asList; -import static org.objectweb.asm.Opcodes.ALOAD; -import static org.objectweb.asm.Opcodes.CHECKCAST; -import static org.objectweb.asm.Opcodes.GETSTATIC; -import static org.objectweb.asm.Opcodes.ILOAD; -import static org.objectweb.asm.Opcodes.INVOKESTATIC; -import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; -import static org.objectweb.asm.Type.ARRAY; -import static org.objectweb.asm.Type.getMethodDescriptor; -import static org.objectweb.asm.Type.getType; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.StringJoiner; -import java.util.function.Function; - -import org.jboss.jandex.AnnotationInstance; -import org.jboss.jandex.AnnotationValue; -import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.DotName; -import org.jboss.jandex.IndexView; -import org.jboss.jandex.MethodInfo; -import org.jboss.jandex.Type; -import org.jetbrains.annotations.NotNull; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -import io.quarkus.deployment.util.AsmUtil; -import io.quarkus.deployment.util.JandexUtil; -import io.quarkus.mongodb.panache.deployment.ByteCodeType; -import io.quarkus.mongodb.panache.deployment.TypeBundle; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; - -public class KotlinGenerator { - public static final ByteCodeType NOT_NULL = new ByteCodeType(NotNull.class); - private static final ByteCodeType CLASS = new ByteCodeType(Class.class); - - private final Function argMapper; - private final ClassVisitor cv; - private final List methods = new ArrayList<>(); - private final Map typeArguments; - private final TypeBundle types; - private final Map typeParameters; - - public KotlinGenerator(ClassVisitor classVisitor, Map typeParameters, - Map typeArguments, TypeBundle types) { - this.cv = classVisitor; - this.typeParameters = typeParameters; - this.typeArguments = typeArguments; - this.types = types; - this.argMapper = type -> typeArguments.get(type); - } - - public static ByteCodeType[] findEntityTypeArguments(IndexView indexView, String repositoryClassName, - DotName repositoryDotName) { - for (ClassInfo classInfo : indexView.getAllKnownImplementors(repositoryDotName)) { - if (repositoryClassName.equals(classInfo.name().toString())) { - return recursivelyFindEntityTypeArguments(indexView, classInfo.name(), repositoryDotName); - } - } - - return null; - } - - public static ByteCodeType[] recursivelyFindEntityTypeArguments(IndexView indexView, DotName clazz, - DotName repositoryDotName) { - if (clazz.equals(JandexUtil.DOTNAME_OBJECT)) { - return null; - } - - List typeParameters = JandexUtil - .resolveTypeParameters(clazz, repositoryDotName, indexView); - if (typeParameters.isEmpty()) - throw new IllegalStateException( - "Failed to find supertype " + repositoryDotName + " from entity class " + clazz); - return new ByteCodeType[] { - new ByteCodeType(typeParameters.get(0)), - new ByteCodeType(typeParameters.get(1)) - }; - } - - public void add(MethodInfo methodInfo) { - methods.add(methodInfo); - } - - private void addNullityChecks(MethodVisitor mv, List parameters) { - for (int i = 0; i < parameters.size(); i++) { - Type parameter = parameters.get(i); - if (parameter.hasAnnotation(NOT_NULL.dotName())) { - mv.visitVarInsn(ALOAD, i + 1); - mv.visitLdcInsn(parameter.name()); - mv.visitMethodInsn(INVOKESTATIC, "kotlin/jvm/internal/Intrinsics", "checkParameterIsNotNull", - "(Ljava/lang/Object;Ljava/lang/String;)V", false); - } - } - } - - public void generate() { - methods.forEach(m -> generate(m)); - } - - public void generate(MethodInfo method) { - // Note: we can't use SYNTHETIC here because otherwise Mockito will never mock these methods - MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, method.name(), - getDescriptor(method, argMapper), getSignature(method, argMapper), null); - - List parameters = method.parameters(); - for (int i = 0; i < parameters.size(); i++) { - mv.visitParameter(method.parameterName(i), 0 /* modifiers */); - } - - addNullityChecks(mv, parameters); - - loadOperationsReference(mv); - - loadArguments(mv, parameters); - invokeOperation(mv, method, parameters); - - mv.visitMaxs(parameters.size() + 1, parameters.size()); - - for (int i = 0; i < parameters.size(); i++) { - Type argument = parameters.get(i); - for (AnnotationInstance annotation : argument.annotations()) { - mv.visitParameterAnnotation(i, "L" + annotation.name() + ";", true); - } - } - } - - private void invokeOperation(MethodVisitor mv, MethodInfo method, List parameters) { - String operationDescriptor; - - AnnotationInstance bridge = method.annotation(PanacheEntityEnhancer.DOTNAME_GENERATE_BRIDGE); - AnnotationValue targetReturnTypeErased = bridge.value("targetReturnTypeErased"); - boolean erased = targetReturnTypeErased != null && targetReturnTypeErased.asBoolean(); - - StringJoiner joiner = new StringJoiner("", "(", ")"); - joiner.add(CLASS.descriptor()); - for (Type parameter : parameters) { - if (parameter.kind() != Type.Kind.PRIMITIVE) { - String descriptor = getDescriptor(parameter, argMapper); - if (typeArguments.containsValue(descriptor)) { - descriptor = OBJECT_SIGNATURE; - } - joiner.add(descriptor); - } else { - joiner.add(OBJECT_SIGNATURE); - } - } - - List names = asList(types.queryType().dotName().toString(), types.updateType().dotName().toString()); - operationDescriptor = joiner + - (erased || names.contains(method.returnType().name().toString()) - ? OBJECT_SIGNATURE - : getDescriptor(method.returnType(), argMapper)); - - mv.visitMethodInsn(INVOKEVIRTUAL, types.operations().internalName(), method.name(), - operationDescriptor, false); - if (method.returnType().kind() != Type.Kind.PRIMITIVE) { - Type type = method.returnType(); - String cast; - if (type.kind() == Type.Kind.TYPE_VARIABLE) { - String applied = argMapper.apply(type.asTypeVariable().identifier()); - cast = applied.substring(1, applied.length() - 1); - } else { - cast = type.name().toString().replace('.', '/'); - } - mv.visitTypeInsn(CHECKCAST, cast); - } - mv.visitInsn(AsmUtil.getReturnInstruction(method.returnType())); - } - - private void loadArguments(MethodVisitor mv, List parameters) { - mv.visitLdcInsn(org.objectweb.asm.Type.getType(typeArguments.get("Entity"))); - for (int i = 0; i < parameters.size(); i++) { - Type methodParameter = parameters.get(i); - org.objectweb.asm.Type parameter; - if (methodParameter.kind() == Type.Kind.TYPE_VARIABLE) { - parameter = typeParameters.get(parameters.get(i).asTypeVariable().identifier()).type(); - } else { - parameter = getType(getDescriptor(methodParameter, s -> null)); - } - mv.visitVarInsn(parameter.getOpcode(ILOAD), i + 1); - if (parameter.getSort() < ARRAY) { - org.objectweb.asm.Type wrapper = AsmUtil.autobox(parameter); - mv.visitMethodInsn(INVOKESTATIC, wrapper.getInternalName(), "valueOf", - getMethodDescriptor(wrapper, parameter), false); - } - - } - } - - private void loadOperationsReference(MethodVisitor mv) { - mv.visitFieldInsn(GETSTATIC, types.entityBase().internalName(), "Companion", - types.entityBaseCompanion().descriptor()); - mv.visitMethodInsn(INVOKEVIRTUAL, types.entityBaseCompanion().internalName(), "getOperations", - "()" + types.operations().descriptor(), false); - } -} diff --git a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinImperativeTypeBundle.java b/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinImperativeTypeBundle.java deleted file mode 100644 index 9cc932c72e32c..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinImperativeTypeBundle.java +++ /dev/null @@ -1,66 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.deployment; - -import io.quarkus.mongodb.panache.PanacheUpdate; -import io.quarkus.mongodb.panache.deployment.ByteCodeType; -import io.quarkus.mongodb.panache.deployment.TypeBundle; -import io.quarkus.mongodb.panache.kotlin.PanacheMongoCompanion; -import io.quarkus.mongodb.panache.kotlin.PanacheMongoCompanionBase; -import io.quarkus.mongodb.panache.kotlin.PanacheMongoEntity; -import io.quarkus.mongodb.panache.kotlin.PanacheMongoEntityBase; -import io.quarkus.mongodb.panache.kotlin.PanacheMongoRepository; -import io.quarkus.mongodb.panache.kotlin.PanacheMongoRepositoryBase; -import io.quarkus.mongodb.panache.kotlin.PanacheQuery; -import io.quarkus.mongodb.panache.kotlin.runtime.KotlinMongoOperations; - -class KotlinImperativeTypeBundle implements TypeBundle { - - @Override - public ByteCodeType entity() { - return new ByteCodeType(PanacheMongoEntity.class); - } - - @Override - public ByteCodeType entityBase() { - return new ByteCodeType(PanacheMongoEntityBase.class); - } - - @Override - public ByteCodeType entityBaseCompanion() { - return new ByteCodeType(PanacheMongoEntityBase.Companion.class); - } - - @Override - public ByteCodeType entityCompanion() { - return new ByteCodeType(PanacheMongoCompanion.class); - } - - @Override - public ByteCodeType entityCompanionBase() { - return new ByteCodeType(PanacheMongoCompanionBase.class); - } - - @Override - public ByteCodeType operations() { - return new ByteCodeType(KotlinMongoOperations.class); - } - - @Override - public ByteCodeType queryType() { - return new ByteCodeType(PanacheQuery.class); - } - - @Override - public ByteCodeType repository() { - return new ByteCodeType(PanacheMongoRepository.class); - } - - @Override - public ByteCodeType repositoryBase() { - return new ByteCodeType(PanacheMongoRepositoryBase.class); - } - - @Override - public ByteCodeType updateType() { - return new ByteCodeType(PanacheUpdate.class); - } -} diff --git a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoEntityEnhancer.java b/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoEntityEnhancer.java deleted file mode 100644 index e2eda00f666ed..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoEntityEnhancer.java +++ /dev/null @@ -1,55 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.deployment; - -import static io.quarkus.mongodb.panache.deployment.BasePanacheMongoResourceProcessor.BSON_IGNORE; - -import java.lang.reflect.Modifier; -import java.util.List; - -import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.DotName; -import org.jboss.jandex.FieldInfo; -import org.jboss.jandex.IndexView; -import org.objectweb.asm.ClassVisitor; - -import io.quarkus.gizmo.DescriptorUtils; -import io.quarkus.mongodb.panache.deployment.TypeBundle; -import io.quarkus.mongodb.panache.deployment.visitors.PanacheMongoEntityClassVisitor; -import io.quarkus.panache.common.deployment.EntityField; -import io.quarkus.panache.common.deployment.EntityModel; -import io.quarkus.panache.common.deployment.MetamodelInfo; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; -import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; - -public class KotlinPanacheMongoEntityEnhancer extends PanacheEntityEnhancer>> { - private final TypeBundle types; - - public KotlinPanacheMongoEntityEnhancer(IndexView index, List methodCustomizers, - TypeBundle types) { - super(index, methodCustomizers); - modelInfo = new MetamodelInfo<>(); - this.types = types; - } - - @Override - public ClassVisitor apply(String className, ClassVisitor outputClassVisitor) { - return new PanacheMongoEntityClassVisitor(className, outputClassVisitor, this.modelInfo, - this.indexView.getClassByName(this.types.entityBase().dotName()), - this.indexView.getClassByName(DotName.createSimple(className)), - this.methodCustomizers, this.types); - } - - @Override - public void collectFields(ClassInfo classInfo) { - EntityModel entityModel = new EntityModel<>(classInfo); - for (FieldInfo fieldInfo : classInfo.fields()) { - String name = fieldInfo.name(); - if (Modifier.isPublic(fieldInfo.flags()) - && !Modifier.isStatic(fieldInfo.flags()) - && !fieldInfo.hasAnnotation(BSON_IGNORE)) { - entityModel.addField(new EntityField(name, DescriptorUtils.typeToString(fieldInfo.type()))); - } - } - modelInfo.addEntityModel(entityModel); - } - -} diff --git a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoRepositoryEnhancer.java b/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoRepositoryEnhancer.java deleted file mode 100644 index 210de669dd7f8..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoRepositoryEnhancer.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.deployment; - -import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.IndexView; -import org.objectweb.asm.ClassVisitor; - -import io.quarkus.mongodb.panache.deployment.TypeBundle; -import io.quarkus.mongodb.panache.kotlin.deployment.visitors.KotlinPanacheMongoRepositoryClassVisitor; -import io.quarkus.panache.common.deployment.PanacheRepositoryEnhancer; - -public class KotlinPanacheMongoRepositoryEnhancer extends PanacheRepositoryEnhancer { - private TypeBundle types; - - public KotlinPanacheMongoRepositoryEnhancer(IndexView index, TypeBundle types) { - super(index, types.repositoryBase().dotName()); - this.types = types; - } - - @Override - public ClassVisitor apply(String className, ClassVisitor outputClassVisitor) { - return new KotlinPanacheMongoRepositoryClassVisitor(this.indexView, outputClassVisitor, className, types); - } - - @Override - public boolean skipRepository(ClassInfo classInfo) { - return false; - } -} diff --git a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoResourceProcessor.java b/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoResourceProcessor.java deleted file mode 100644 index 6c1c2cd8eede0..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinPanacheMongoResourceProcessor.java +++ /dev/null @@ -1,144 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.deployment; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import org.jboss.jandex.ClassInfo; - -import io.quarkus.deployment.Capability; -import io.quarkus.deployment.Feature; -import io.quarkus.deployment.annotations.BuildProducer; -import io.quarkus.deployment.annotations.BuildStep; -import io.quarkus.deployment.builditem.ApplicationIndexBuildItem; -import io.quarkus.deployment.builditem.BytecodeTransformerBuildItem; -import io.quarkus.deployment.builditem.CapabilityBuildItem; -import io.quarkus.deployment.builditem.CombinedIndexBuildItem; -import io.quarkus.deployment.builditem.FeatureBuildItem; -import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; -import io.quarkus.mongodb.panache.deployment.BasePanacheMongoResourceProcessor; -import io.quarkus.mongodb.panache.deployment.PropertyMappingClassBuildStep; -import io.quarkus.mongodb.panache.deployment.TypeBundle; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; -import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; -import io.quarkus.panache.common.deployment.PanacheMethodCustomizerBuildItem; -import io.quarkus.panache.common.deployment.PanacheRepositoryEnhancer; - -public class KotlinPanacheMongoResourceProcessor extends BasePanacheMongoResourceProcessor { - public static final KotlinImperativeTypeBundle IMPERATIVE_TYPE_BUNDLE = new KotlinImperativeTypeBundle(); - public static final KotlinReactiveTypeBundle REACTIVE_TYPE_BUNDLE = new KotlinReactiveTypeBundle(); - - @BuildStep - public void buildImperativeCompanions(CombinedIndexBuildItem index, ApplicationIndexBuildItem applicationIndex, - BuildProducer transformers, - BuildProducer reflectiveClass, - BuildProducer propertyMappingClass, - List methodCustomizersBuildItems) { - - List methodCustomizers = methodCustomizersBuildItems.stream() - .map(bi -> bi.getMethodCustomizer()).collect(Collectors.toList()); - - processCompanions(index, transformers, reflectiveClass, propertyMappingClass, - createCompanionEnhancer(index, methodCustomizers), - getImperativeTypeBundle()); - } - - @BuildStep - public void buildReactiveCompanions(CombinedIndexBuildItem index, - BuildProducer reflectiveClass, - BuildProducer propertyMappingClass, - BuildProducer transformers, - List methodCustomizersBuildItems) { - - List methodCustomizers = methodCustomizersBuildItems.stream() - .map(bi -> bi.getMethodCustomizer()).collect(Collectors.toList()); - - processCompanions(index, transformers, reflectiveClass, propertyMappingClass, - createReactiveCompanionEnhancer(index, methodCustomizers), - getReactiveTypeBundle()); - } - - protected KotlinImperativeTypeBundle getImperativeTypeBundle() { - return IMPERATIVE_TYPE_BUNDLE; - } - - protected KotlinReactiveTypeBundle getReactiveTypeBundle() { - return REACTIVE_TYPE_BUNDLE; - } - - @BuildStep - protected CapabilityBuildItem capability() { - return new CapabilityBuildItem(Capability.MONGODB_PANACHE_KOTLIN); - } - - @BuildStep - protected FeatureBuildItem featureBuildItem() { - return new FeatureBuildItem(Feature.MONGODB_PANACHE_KOTLIN); - } - - @Override - public PanacheEntityEnhancer createEntityEnhancer(CombinedIndexBuildItem index, - List methodCustomizers) { - return new KotlinPanacheMongoEntityEnhancer(index.getIndex(), methodCustomizers, getImperativeTypeBundle()); - } - - private PanacheMongoCompanionEnhancer createCompanionEnhancer(CombinedIndexBuildItem index, - List methodCustomizers) { - return new PanacheMongoCompanionEnhancer(index.getIndex(), methodCustomizers, getImperativeTypeBundle()); - } - - private PanacheMongoCompanionEnhancer createReactiveCompanionEnhancer(CombinedIndexBuildItem index, - List methodCustomizers) { - return new PanacheMongoCompanionEnhancer(index.getIndex(), methodCustomizers, getReactiveTypeBundle()); - } - - @Override - public PanacheEntityEnhancer createReactiveEntityEnhancer(CombinedIndexBuildItem index, - List methodCustomizers) { - return new KotlinPanacheMongoEntityEnhancer(index.getIndex(), methodCustomizers, getImperativeTypeBundle()); - } - - @Override - public PanacheRepositoryEnhancer createRepositoryEnhancer(CombinedIndexBuildItem index) { - return new KotlinPanacheMongoRepositoryEnhancer(index.getIndex(), getImperativeTypeBundle()); - } - - @Override - public PanacheRepositoryEnhancer createReactiveRepositoryEnhancer(CombinedIndexBuildItem index) { - return new KotlinPanacheMongoRepositoryEnhancer(index.getIndex(), getReactiveTypeBundle()); - } - - private void processCompanions(CombinedIndexBuildItem index, - BuildProducer transformers, - BuildProducer reflectiveClass, - BuildProducer propertyMappingClass, - PanacheEntityEnhancer entityEnhancer, TypeBundle typeBundle) { - - Set modelClasses = new HashSet<>(); - // Note that we do this in two passes because for some reason Jandex does not give us subtypes - // of PanacheMongoEntity if we ask for subtypes of PanacheMongoEntityBase - for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(typeBundle.entityCompanionBase().dotName())) { - if (classInfo.name().equals(typeBundle.entityCompanion().dotName())) { - continue; - } - if (modelClasses.add(classInfo.name().toString())) - entityEnhancer.collectFields(classInfo); - } - for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(typeBundle.entityCompanion().dotName())) { - if (modelClasses.add(classInfo.name().toString())) - entityEnhancer.collectFields(classInfo); - } - - // iterate over all the entity classes - for (String modelClass : modelClasses) { - transformers.produce(new BytecodeTransformerBuildItem(modelClass, entityEnhancer)); - - //register for reflection entity classes - reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, modelClass)); - - // Register for building the property mapping cache - propertyMappingClass.produce(new PropertyMappingClassBuildStep(modelClass)); - } - } -} diff --git a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinReactiveTypeBundle.java b/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinReactiveTypeBundle.java deleted file mode 100644 index e5d58c47549a2..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/KotlinReactiveTypeBundle.java +++ /dev/null @@ -1,66 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.deployment; - -import io.quarkus.mongodb.panache.deployment.ByteCodeType; -import io.quarkus.mongodb.panache.deployment.TypeBundle; -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoCompanion; -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoCompanionBase; -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoEntity; -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoEntityBase; -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoRepository; -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoRepositoryBase; -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheQuery; -import io.quarkus.mongodb.panache.kotlin.reactive.runtime.KotlinReactiveMongoOperations; -import io.quarkus.mongodb.panache.reactive.ReactivePanacheUpdate; - -class KotlinReactiveTypeBundle implements TypeBundle { - @Override - public ByteCodeType entity() { - return new ByteCodeType(ReactivePanacheMongoEntity.class); - } - - @Override - public ByteCodeType entityBase() { - return new ByteCodeType(ReactivePanacheMongoEntityBase.class); - } - - @Override - public ByteCodeType entityBaseCompanion() { - return new ByteCodeType(ReactivePanacheMongoEntityBase.Companion.class); - } - - @Override - public ByteCodeType entityCompanion() { - return new ByteCodeType(ReactivePanacheMongoCompanion.class); - } - - @Override - public ByteCodeType entityCompanionBase() { - return new ByteCodeType(ReactivePanacheMongoCompanionBase.class); - } - - @Override - public ByteCodeType operations() { - return new ByteCodeType(KotlinReactiveMongoOperations.class); - } - - @Override - public ByteCodeType queryType() { - return new ByteCodeType(ReactivePanacheQuery.class); - } - - @Override - public ByteCodeType repository() { - return new ByteCodeType(ReactivePanacheMongoRepository.class); - } - - @Override - public ByteCodeType repositoryBase() { - return new ByteCodeType(ReactivePanacheMongoRepositoryBase.class); - } - - @Override - public ByteCodeType updateType() { - return new ByteCodeType(ReactivePanacheUpdate.class); - } - -} diff --git a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/PanacheMongoCompanionEnhancer.java b/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/PanacheMongoCompanionEnhancer.java deleted file mode 100644 index 176d7cd5b328d..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/PanacheMongoCompanionEnhancer.java +++ /dev/null @@ -1,53 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.deployment; - -import static io.quarkus.mongodb.panache.deployment.BasePanacheMongoResourceProcessor.BSON_IGNORE; - -import java.lang.reflect.Modifier; -import java.util.List; - -import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.DotName; -import org.jboss.jandex.FieldInfo; -import org.jboss.jandex.IndexView; -import org.objectweb.asm.ClassVisitor; - -import io.quarkus.gizmo.DescriptorUtils; -import io.quarkus.mongodb.panache.deployment.TypeBundle; -import io.quarkus.mongodb.panache.kotlin.deployment.visitors.PanacheMongoCompanionClassVisitor; -import io.quarkus.panache.common.deployment.EntityField; -import io.quarkus.panache.common.deployment.EntityModel; -import io.quarkus.panache.common.deployment.MetamodelInfo; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; -import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; - -public class PanacheMongoCompanionEnhancer extends PanacheEntityEnhancer>> { - private TypeBundle types; - - public PanacheMongoCompanionEnhancer(IndexView index, List methodCustomizers, - TypeBundle types) { - super(index, methodCustomizers); - this.types = types; - modelInfo = new MetamodelInfo<>(); - } - - @Override - public ClassVisitor apply(String className, ClassVisitor outputClassVisitor) { - return new PanacheMongoCompanionClassVisitor(outputClassVisitor, - indexView.getClassByName(DotName.createSimple(className)), indexView, types); - } - - @Override - public void collectFields(ClassInfo classInfo) { - EntityModel entityModel = new EntityModel<>(classInfo); - for (FieldInfo fieldInfo : classInfo.fields()) { - String name = fieldInfo.name(); - if (Modifier.isPublic(fieldInfo.flags()) - && !Modifier.isStatic(fieldInfo.flags()) - && !fieldInfo.hasAnnotation(BSON_IGNORE)) { - entityModel.addField(new EntityField(name, DescriptorUtils.typeToString(fieldInfo.type()))); - } - } - modelInfo.addEntityModel(entityModel); - } - -} diff --git a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/visitors/KotlinPanacheMongoRepositoryClassVisitor.java b/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/visitors/KotlinPanacheMongoRepositoryClassVisitor.java deleted file mode 100644 index 6be6cd5574f47..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/visitors/KotlinPanacheMongoRepositoryClassVisitor.java +++ /dev/null @@ -1,107 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.deployment.visitors; - -import static io.quarkus.deployment.util.AsmUtil.getDescriptor; -import static io.quarkus.mongodb.panache.kotlin.deployment.KotlinGenerator.findEntityTypeArguments; - -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Map; -import java.util.TreeMap; - -import org.jboss.jandex.AnnotationValue; -import org.jboss.jandex.DotName; -import org.jboss.jandex.IndexView; -import org.jboss.jandex.MethodInfo; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; - -import io.quarkus.mongodb.panache.deployment.ByteCodeType; -import io.quarkus.mongodb.panache.deployment.TypeBundle; -import io.quarkus.mongodb.panache.kotlin.deployment.KotlinGenerator; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; -import io.quarkus.panache.common.deployment.visitors.PanacheRepositoryClassVisitor; - -public class KotlinPanacheMongoRepositoryClassVisitor extends PanacheRepositoryClassVisitor { - private final TypeBundle types; - private KotlinGenerator generator; - final Map toGenerate = new TreeMap<>(); - final Map toElide = new TreeMap<>(); - - public KotlinPanacheMongoRepositoryClassVisitor(IndexView indexView, ClassVisitor outputClassVisitor, String className, - TypeBundle types) { - super(className, outputClassVisitor, indexView); - this.types = types; - } - - @Override - protected final DotName getPanacheRepositoryDotName() { - return types.repository().dotName(); - } - - @Override - protected final DotName getPanacheRepositoryBaseDotName() { - return types.repositoryBase().dotName(); - } - - @Override - protected final String getPanacheOperationsInternalName() { - return types.operations().internalName(); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - final String repositoryClassName = name.replace('/', '.'); - - ByteCodeType[] foundTypeArguments = findEntityTypeArguments(indexView, repositoryClassName, - getPanacheRepositoryBaseDotName()); - - ByteCodeType idType = foundTypeArguments[1].unbox(); - typeArguments.put("Id", idType.descriptor()); - - Map typeParameters = new HashMap<>(); - typeParameters.put("Entity", foundTypeArguments[0]); - typeParameters.put("Id", idType); - - daoClassInfo - .methods() - .forEach(method -> { - String descriptor = getDescriptor(method, m -> null); - if (method.hasAnnotation(PanacheEntityEnhancer.DOTNAME_GENERATE_BRIDGE)) { - toGenerate.put(method.name() + descriptor, method); - toElide.put(method.name() + descriptor, method); - } - }); - generator = new KotlinGenerator(this.cv, typeParameters, typeArguments, types); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, - String[] exceptions) { - MethodInfo methodInfo = toGenerate.get(name + descriptor); - if (methodInfo == null) { - if (toElide.get(name + descriptor) == null) { - return super.visitMethod(access, name, descriptor, signature, exceptions); - } - } else { - if (Modifier.isAbstract(daoClassInfo.flags()) - && methodInfo.hasAnnotation(PanacheEntityEnhancer.DOTNAME_GENERATE_BRIDGE)) { - userMethods.add(name + "/" + descriptor); - } - } - - return null; - } - - @Override - protected void generateModelBridge(MethodInfo method, AnnotationValue targetReturnTypeErased) { - generator.generate(method); - } - - @Override - protected void generateJvmBridge(MethodInfo method) { - if (!Modifier.isAbstract(daoClassInfo.flags())) { - super.generateJvmBridge(method); - } - } -} diff --git a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/visitors/PanacheMongoCompanionClassVisitor.java b/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/visitors/PanacheMongoCompanionClassVisitor.java deleted file mode 100644 index 338476bb56d3a..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/deployment/src/main/java/io/quarkus/mongodb/panache/kotlin/deployment/visitors/PanacheMongoCompanionClassVisitor.java +++ /dev/null @@ -1,94 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.deployment.visitors; - -import static io.quarkus.gizmo.Gizmo.ASM_API_VERSION; -import static org.jboss.jandex.DotName.createSimple; - -import java.util.HashMap; -import java.util.Map; -import java.util.StringJoiner; -import java.util.TreeMap; - -import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.IndexView; -import org.jboss.jandex.MethodInfo; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; - -import io.quarkus.deployment.util.AsmUtil; -import io.quarkus.mongodb.panache.deployment.ByteCodeType; -import io.quarkus.mongodb.panache.deployment.TypeBundle; -import io.quarkus.mongodb.panache.kotlin.deployment.KotlinGenerator; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; - -public class PanacheMongoCompanionClassVisitor extends ClassVisitor { - private final Map bridgeMethods = new TreeMap<>(); - private final IndexView indexView; - private String entityBinaryType; - private String entitySignature; - private KotlinGenerator generator; - private TypeBundle types; - - public PanacheMongoCompanionClassVisitor(ClassVisitor outputClassVisitor, ClassInfo entityInfo, IndexView indexView, - TypeBundle types) { - super(ASM_API_VERSION, outputClassVisitor); - this.indexView = indexView; - this.types = types; - - entityInfo - .methods() - .forEach(method -> { - if (method.hasAnnotation(PanacheEntityEnhancer.DOTNAME_GENERATE_BRIDGE)) { - bridgeMethods.put(method.name() + AsmUtil.getDescriptor(method, m -> null), method); - } - }); - } - - @Override - public String toString() { - return new StringJoiner(", ", PanacheMongoCompanionClassVisitor.class.getSimpleName() + "[", "]") - .add(entityBinaryType) - .toString(); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - - String className = name.replace('.', '/'); - - ByteCodeType[] foundTypeArguments = KotlinGenerator.recursivelyFindEntityTypeArguments(indexView, - createSimple(name.replace('/', '.')), types.entityCompanionBase().dotName()); - - entityBinaryType = className.replace("$Companion", ""); - entitySignature = "L" + entityBinaryType + ";"; - - Map typeArguments = new HashMap<>(); - typeArguments.put("Entity", entitySignature); - typeArguments.put("Id", foundTypeArguments[1].descriptor()); - - Map typeParameters = new HashMap<>(); - typeParameters.put("Entity", foundTypeArguments[0]); - typeParameters.put("Id", foundTypeArguments[1]); - - generator = new KotlinGenerator(this.cv, typeParameters, typeArguments, types); - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodInfo methodInfo = bridgeMethods.get(name + descriptor); - if (methodInfo == null) { - return super.visitMethod(access, name, descriptor, signature, exceptions); - } else { - generator.add(methodInfo); - } - return null; - } - - @Override - public void visitEnd() { - generator.generate(); - if (cv != null) { - cv.visitEnd(); - } - } -} diff --git a/extensions/panache/mongodb-panache-kotlin/pom.xml b/extensions/panache/mongodb-panache-kotlin/pom.xml deleted file mode 100644 index 468ddbfb7de9d..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/pom.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - quarkus-build-parent - io.quarkus - 999-SNAPSHOT - ../../../build-parent/pom.xml - - 4.0.0 - - quarkus-mongodb-panache-kotlin-parent - Quarkus - MongoDB with Panache - Kotlin Parent - pom - - runtime - deployment - - \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/pom.xml b/extensions/panache/mongodb-panache-kotlin/runtime/pom.xml deleted file mode 100644 index 3002360e4ac20..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/pom.xml +++ /dev/null @@ -1,203 +0,0 @@ - - - - quarkus-mongodb-panache-kotlin-parent - io.quarkus - 999-SNAPSHOT - ../ - - 4.0.0 - - quarkus-mongodb-panache-kotlin - Quarkus - MongoDB with Panache - Kotlin Runtime - Simplify your persistence code for MongoDB via the active record or the repository pattern - - - io.quarkus - quarkus-core - - - io.quarkus - quarkus-panache-common - - - io.quarkus - quarkus-mongodb-panache-common - - - - - io.quarkus - quarkus-jsonb - true - - - - - io.quarkus - quarkus-jackson - true - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - - - org.junit.jupiter - junit-jupiter - test - - - org.junit.jupiter - junit-jupiter-api - test - - - org.jetbrains.kotlin - kotlin-reflect - ${kotlin.version} - test - - - org.ow2.asm - asm - test - - - io.quarkus - quarkus-mongodb-panache - test - - - io.quarkus - quarkus-mongodb-panache-common-deployment - test - - - io.quarkus.gizmo - gizmo - test - - - - - - jcenter - JCenter - https://jcenter.bintray.com/ - - - - - - - io.quarkus - quarkus-bootstrap-maven-plugin - - - - org.jboss.jandex - jandex-maven-plugin - - - make-index - - jandex - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - compile - compile - - compile - - - - src/main/java - src/main/kotlin - - - - - test-compile - test-compile - - test-compile - - - - - 1.8 - - - - org.apache.maven.plugins - maven-compiler-plugin - - -proc:none - - - - - default-compile - none - - - - default-testCompile - none - - - java-compile - compile - - compile - - - - java-test-compile - test-compile - testCompile - - - - - org.jetbrains.dokka - dokka-maven-plugin - 0.10.1 - - - javadoc - pre-site - - dokka - - - - - html - - src/main/java - src/main/kotlin - - - - - https://docs.oracle.com/javase/8/docs/api/ - https://docs.oracle.com/javase/8/docs/api/package-list - - - - - - - diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/java/io/quarkus/mongodb/panache/kotlin/reactive/runtime/ReactivePanacheQueryImpl.java b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/java/io/quarkus/mongodb/panache/kotlin/reactive/runtime/ReactivePanacheQueryImpl.java deleted file mode 100644 index c68131430b7c7..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/java/io/quarkus/mongodb/panache/kotlin/reactive/runtime/ReactivePanacheQueryImpl.java +++ /dev/null @@ -1,126 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.reactive.runtime; - -import java.util.List; - -import org.bson.conversions.Bson; - -import com.mongodb.client.model.Collation; - -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheQuery; -import io.quarkus.mongodb.panache.reactive.runtime.CommonReactivePanacheQueryImpl; -import io.quarkus.mongodb.reactive.ReactiveMongoCollection; -import io.quarkus.panache.common.Page; -import io.smallrye.mutiny.Multi; -import io.smallrye.mutiny.Uni; - -@SuppressWarnings("unchecked") -public class ReactivePanacheQueryImpl implements ReactivePanacheQuery { - private final CommonReactivePanacheQueryImpl delegate; - - ReactivePanacheQueryImpl(ReactiveMongoCollection collection, Bson mongoQuery, Bson sort) { - this.delegate = new CommonReactivePanacheQueryImpl<>(collection, mongoQuery, sort); - } - - private ReactivePanacheQueryImpl(CommonReactivePanacheQueryImpl delegate) { - this.delegate = delegate; - } - - @Override - public ReactivePanacheQuery project(Class type) { - return new ReactivePanacheQueryImpl<>(delegate.project(type)); - } - - @Override - @SuppressWarnings("unchecked") - public ReactivePanacheQuery page(Page page) { - delegate.page(page); - return this; - } - - @Override - public ReactivePanacheQuery page(int pageIndex, int pageSize) { - return page(Page.of(pageIndex, pageSize)); - } - - @Override - public ReactivePanacheQuery nextPage() { - delegate.nextPage(); - return this; - } - - @Override - public ReactivePanacheQuery previousPage() { - delegate.previousPage(); - return this; - } - - @Override - public ReactivePanacheQuery firstPage() { - delegate.firstPage(); - return this; - } - - @Override - public Uni> lastPage() { - Uni> uni = delegate.lastPage(); - return uni.map(q -> this); - } - - @Override - public Uni hasNextPage() { - return delegate.hasNextPage(); - } - - @Override - public boolean hasPreviousPage() { - return delegate.hasPreviousPage(); - } - - @Override - public Uni pageCount() { - return delegate.pageCount(); - } - - @Override - public Page page() { - return delegate.page(); - } - - @Override - public ReactivePanacheQuery range(int startIndex, int lastIndex) { - delegate.range(startIndex, lastIndex); - return this; - } - - @Override - public ReactivePanacheQuery withCollation(Collation collation) { - delegate.withCollation(collation); - return this; - } - - @Override - public Uni count() { - return delegate.count(); - } - - @Override - public Uni> list() { - return delegate.list(); - } - - @Override - public Multi stream() { - return delegate.stream(); - } - - @Override - public Uni firstResult() { - return delegate.firstResult(); - } - - @Override - @SuppressWarnings("unchecked") - public Uni singleResult() { - return delegate.singleResult(); - } -} diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/java/io/quarkus/mongodb/panache/kotlin/runtime/PanacheQueryImpl.java b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/java/io/quarkus/mongodb/panache/kotlin/runtime/PanacheQueryImpl.java deleted file mode 100644 index a1d326f9816bc..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/java/io/quarkus/mongodb/panache/kotlin/runtime/PanacheQueryImpl.java +++ /dev/null @@ -1,125 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.runtime; - -import java.util.List; -import java.util.stream.Stream; - -import org.bson.conversions.Bson; - -import com.mongodb.client.MongoCollection; -import com.mongodb.client.model.Collation; - -import io.quarkus.mongodb.panache.kotlin.PanacheQuery; -import io.quarkus.mongodb.panache.runtime.CommonPanacheQueryImpl; -import io.quarkus.panache.common.Page; - -public class PanacheQueryImpl implements PanacheQuery { - private final CommonPanacheQueryImpl delegate; - - PanacheQueryImpl(MongoCollection collection, Bson mongoQuery, Bson sort) { - this.delegate = new CommonPanacheQueryImpl<>(collection, mongoQuery, sort); - } - - private PanacheQueryImpl(CommonPanacheQueryImpl delegate) { - this.delegate = delegate; - } - - @Override - public PanacheQuery project(Class type) { - return new PanacheQueryImpl<>(delegate.project(type)); - } - - @Override - public PanacheQuery page(Page page) { - delegate.page(page); - return this; - } - - @Override - public PanacheQuery page(int pageIndex, int pageSize) { - return page(Page.of(pageIndex, pageSize)); - } - - @Override - public PanacheQuery nextPage() { - delegate.nextPage(); - return this; - } - - @Override - public PanacheQuery previousPage() { - delegate.previousPage(); - return this; - } - - @Override - public PanacheQuery firstPage() { - delegate.firstPage(); - return this; - } - - @Override - public PanacheQuery lastPage() { - delegate.lastPage(); - return this; - } - - @Override - public boolean hasNextPage() { - return delegate.hasNextPage(); - } - - @Override - public boolean hasPreviousPage() { - return delegate.hasPreviousPage(); - } - - @Override - public int pageCount() { - return delegate.pageCount(); - } - - @Override - public Page page() { - return delegate.page(); - } - - @Override - public PanacheQuery range(int startIndex, int lastIndex) { - delegate.range(startIndex, lastIndex); - return this; - } - - @Override - public PanacheQuery withCollation(Collation collation) { - delegate.withCollation(collation); - return this; - } - - // Results - - @Override - public long count() { - return delegate.count(); - } - - @Override - public List list() { - return delegate.list(); - } - - @Override - public Stream stream() { - return delegate.stream(); - } - - @Override - public Entity firstResult() { - return delegate.firstResult(); - } - - @Override - public Entity singleResult() { - return delegate.singleResult(); - } - -} diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoCompanion.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoCompanion.kt deleted file mode 100644 index ed893fd7cc9d5..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoCompanion.kt +++ /dev/null @@ -1,702 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin - -import com.mongodb.client.MongoCollection -import com.mongodb.client.MongoDatabase -import io.quarkus.mongodb.panache.kotlin.PanacheMongoEntityBase.Companion.operations -import io.quarkus.mongodb.panache.PanacheUpdate -import io.quarkus.panache.common.Parameters -import io.quarkus.panache.common.Sort -import io.quarkus.panache.common.impl.GenerateBridge -import org.bson.Document -import org.bson.types.ObjectId -import java.util.stream.Stream - -/** - * Define persistence and query methods for an Entity with a default ID type of [ObjectId] - * - * @param Entity the entity type - */ -interface PanacheMongoCompanion: PanacheMongoCompanionBase - -/** - * Define persistence and query methods for an Entity with a type of Id - * - * @param Entity the entity type - * @param Id the ID type - */ -interface PanacheMongoCompanionBase { - /** - * Find an entity of this type by ID. - * - * @param id the ID of the entity to find. - * @return the entity found, or `null` if not found. - */ - @GenerateBridge(targetReturnTypeErased = true) - fun findById(id: Id): Entity? = throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, vararg params: Any?): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options with optional indexed parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, sort: Sort, vararg params: Any?): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, params: Map): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options, with named parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, sort: Sort, params: Map): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with named parameters. - * - * @param query a query string - * @param params Parameters of named parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, params: Parameters): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options with named parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params Parameters of indexed parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, sort: Sort, params: Parameters): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * - * @param query a query string - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: Document): PanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * - * @param query a query string - * @param sort the sort strategy to use - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: Document, sort: Document): PanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * - * @return a new [PanacheQuery] instance to find all entities of this type. - * @see [findAll] - * @see [listAll] - * @see [streamAll] - */ - @GenerateBridge - fun findAll(): PanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * - * @param sort the sort order to use - * @return a new [PanacheQuery] instance to find all entities of this type. - * @see [findAll] - * @see [listAll] - * @see [streamAll] - */ - @GenerateBridge - fun findAll(sort: Sort): PanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with optional indexed parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, vararg params: Any?): List = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with optional indexed parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, sort: Sort, vararg params: Any?): List = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, params: Map): List = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, sort: Sort, params: Map): List = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params Parameters of named parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, params: Parameters): List = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params Parameters of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, sort: Sort, params: Parameters): List = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * This method is a shortcut for `find(query).list()`. - * - * @param query a query document - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: Document): List = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * This method is a shortcut for `find(query, sort).list()`. - * - * @param query a query document - * @param sort the sort document - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: Document, sort: Document): List = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * This method is a shortcut for `findAll().list()`. - * - * @return a [List] containing all results, without paging - * @see [listAll] - * @see [findAll] - * @see [streamAll] - */ - @GenerateBridge - fun listAll(): List = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * This method is a shortcut for `findAll(sort).list()`. - * - * @param sort the sort order to use - * @return a [List] containing all results, without paging - * @see [listAll] - * @see [findAll] - * @see [streamAll] - */ - @GenerateBridge - fun listAll(sort: Sort): List = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with optional indexed parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a Stream containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, vararg params: Any?): Stream = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with optional indexed parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a Stream containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, sort: Sort, vararg params: Any?): Stream = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a Stream containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, params: Map): Stream = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a Stream containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, sort: Sort, params: Map): Stream = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params Parameters of named parameters - * @return a Stream containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, params: Parameters): Stream = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params Parameters of indexed parameters - * @return a Stream containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, sort: Sort, params: Parameters): Stream = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * This method is a shortcut for `find(query).stream()`. - * - * @param query a query Document - * @return a Stream containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: Document): Stream = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * This method is a shortcut for `find(query, sort).stream()`. - * - * @param query a query Document - * @param sort the sort strategy to use - * @return a Stream containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: Document, sort: Document): Stream = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * This method is a shortcut for `findAll().stream()`. - * - * @return a Stream containing all results, without paging - * @see [streamAll] - * @see [findAll] - * @see [listAll] - */ - @GenerateBridge - fun streamAll(): Stream = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * This method is a shortcut for `findAll(sort).stream()`. - * - * @param sort the sort order to use - * @return a Stream containing all results, without paging - * @see [streamAll] - * @see [findAll] - * @see [listAll] - */ - @GenerateBridge - fun streamAll(sort: Sort): Stream = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity in the database. - * - * @return the number of this type of entity in the database. - * @see [count] - */ - @GenerateBridge - fun count(): Long = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return the number of entities counted. - * @see [count] - */ - @GenerateBridge - fun count(query: String, vararg params: Any?): Long = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return the number of entities counted. - * @see [count] - */ - @GenerateBridge - fun count(query: String, params: Map): Long = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query with named parameters. - * - * @param query a query string - * @param params Parameters of named parameters - * @return the number of entities counted. - * @see [count] - */ - @GenerateBridge - fun count(query: String, params: Parameters): Long = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query - * - * @param query a query document - * @return the number of entities counted. - * @see [count] - */ - @GenerateBridge - fun count(query: Document): Long = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type from the database. - * - * @return the number of entities deleted. - * @see [delete] - */ - @GenerateBridge - fun deleteAll(): Long = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return the number of entities deleted. - * @see [deleteAll] - * @see [delete] - */ - @GenerateBridge - fun delete(query: String, vararg params: Any?): Long = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return the number of entities deleted. - * @see [deleteAll] - * @see [delete] - */ - @GenerateBridge - fun delete(query: String, params: Map): Long = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with named parameters. - * - * @param query a query string - * @param params Parameters of named parameters - * @return the number of entities deleted. - * @see [deleteAll] - * @see [delete] - */ - @GenerateBridge - fun delete(query: String, params: Parameters): Long = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query - * - * @param query a query document - * @return the number of entities deleted. - * @see [deleteAll] - * @see [delete] - */ - @GenerateBridge - fun delete(query: Document): Long = throw operations.implementationInjectionMissing() - - /** - * Delete an entity of this type by ID. - * - * @param id the ID of the entity to delete. - * @return false if the entity was not deleted (not found). - */ - @GenerateBridge - fun deleteById(id: Id): Boolean = throw operations.implementationInjectionMissing() - - /** - * Insert all given entities. - * - * @param entities the entities to insert - * @see [persist] - */ - fun persist(entities: Iterable) = operations.persist(entities) - - /** - * Insert all given entities. - * - * @param entities the entities to insert - * @see [persist] - */ - fun persist(entities: Stream) = operations.persist(entities) - - /** - * Insert all given entities. - * - * @param entities the entities to insert - * @see [persist] - */ - fun persist(firstEntity: Entity, vararg entities: Entity) = operations.persist(firstEntity, *entities) - - /** - * Update all given entities. - * - * @param entities the entities to update - * @see [update] - */ - fun update(entities: Iterable) = operations.update(entities) - - /** - * Update all given entities. - * - * @param entities the entities to insert - * @see [update] - */ - fun update(entities: Stream) = operations.update(entities) - - /** - * Update all given entities. - * - * @param entities the entities to update - * @see [update] - */ - fun update(firstEntity: Entity, vararg entities: Entity) = operations.update(firstEntity, *entities) - - /** - * Persist all given entities or update them if they already exist. - * - * @param entities the entities to update - * @see [persistOrUpdate] - */ - fun persistOrUpdate(entities: Iterable) = operations.persistOrUpdate(entities) - - /** - * Persist all given entities. - * - * @param entities the entities to insert - * @see [persistOrUpdate] - */ - fun persistOrUpdate(entities: Stream) = operations.persistOrUpdate(entities) - - /** - * Persist all given entities. - * - * @param entities the entities to update - * @see [persistOrUpdate] - */ - fun persistOrUpdate(firstEntity: Entity, vararg entities: Entity) = operations.persistOrUpdate(firstEntity, *entities) - - /** - * Update all entities of this type using the given update document with optional indexed parameters. - * The returned [PanacheUpdate] object will allow to restrict on which document the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. It can also be expressed as a query string. - * @param params optional sequence of indexed parameters - * @return a new [PanacheUpdate] instance for the given update document - * @see [update] - */ - @GenerateBridge - fun update(update: String, vararg params: Any?): PanacheUpdate = throw operations.implementationInjectionMissing() - - /** - * Update all entities of this type by the given update document with named parameters. - * The returned [PanacheUpdate] object will allow to restrict on which document the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. - * It can also be expressed as a query string. - * - * @param params map of named parameters - * @return a new [PanacheUpdate] instance for the given update document - * @see [update] - */ - @GenerateBridge - fun update(update: String, params: Map): PanacheUpdate = - throw operations.implementationInjectionMissing() - - /** - * Update all entities of this type by the given update document, with named parameters. - * The returned [PanacheUpdate] object will allow to restrict on which document the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. It can also be expressed as a query - * string. - * - * @param params [Parameters] of named parameters - * @return a new [PanacheUpdate] instance for the given update document - * @see [update] - */ - @GenerateBridge - fun update(update: String, params: Parameters): PanacheUpdate = throw operations.implementationInjectionMissing() - - /** - * Allow to access the underlying Mongo Collection. - * - * @return the [MongoCollection] used by this entity - */ - @GenerateBridge - fun mongoCollection(): MongoCollection = throw operations.implementationInjectionMissing() - - /** - * Allow to access the underlying Mongo Database. - * - * @return the [MongoDatabase] used by this entity - */ - @GenerateBridge - fun mongoDatabase(): MongoDatabase = throw operations.implementationInjectionMissing() -} diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoEntity.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoEntity.kt deleted file mode 100755 index 3207db347a654..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoEntity.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin - -import org.bson.types.ObjectId - -/** - * Represents an entity with a generated ID field [id] of type [ObjectId]. If your - * Mongo entities extend this class they gain the ID field and auto-generated accessors - * to all their public fields, as well as all the useful methods from [PanacheMongoEntityBase]. - * - * If you want a custom ID type or strategy, you can directly extend [PanacheMongoEntityBase] - * instead, and write your own ID field. You will still get auto-generated accessors and - * all the useful methods. - * - * @see PanacheMongoEntityBase - */ -abstract class PanacheMongoEntity : PanacheMongoEntityBase() { - /** - * The auto-generated ID field. - * This field is set by Mongo when this entity is persisted. - * - * @see [PanacheMongoEntityBase.persist] - */ - var id: ObjectId? = null - - /** - * Default toString() implementation - * - * @return the class type and ID type - */ - override fun toString(): String = "${this.javaClass.simpleName}<$id>" -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoEntityBase.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoEntityBase.kt deleted file mode 100755 index 3935b0662b569..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoEntityBase.kt +++ /dev/null @@ -1,62 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin - -import io.quarkus.mongodb.panache.kotlin.runtime.KotlinMongoOperations - -/** - * Represents an entity. If your Mongo entities extend this class they gain auto-generated accessors - * to all their public fields, as well as a lot of useful methods. Unless you have a custom ID strategy, you - * should not extend this class directly but extend [PanacheMongoEntity] instead. - * - * @see PanacheMongoEntity - */ -@Suppress("unused") -abstract class PanacheMongoEntityBase { - /** - * Defines internal implementation details for use by quarkus. Use of these members is highly discouraged as the - * implementation may change without warning. - */ - companion object { - /** - * Provides the default implementations for quarkus to wire up. Should not be used by third party developers. - */ - @JvmStatic - val operations = KotlinMongoOperations() - } - - /** - * Persist this entity in the database. This will set its ID field if not already set. - * - * @see [persist] - */ - fun persist() { - operations.persist(this) - } - - /** - * Update this entity in the database. - * - * @see [update] - */ - fun update() { - operations.update(this) - } - - /** - * Persist this entity in the database or update it if it already exists. - * - * @see [persistOrUpdate] - */ - fun persistOrUpdate() { - operations.persistOrUpdate(this) - } - - /** - * Delete this entity from the database if it is already persisted. - * - * @see [delete] - * @see [PanacheMongoCompanionBase.deleteAll] - */ - fun delete() { - operations.delete(this) - } -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoRepository.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoRepository.kt deleted file mode 100755 index f4e044fc1fd9c..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoRepository.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin - -import org.bson.types.ObjectId - -/** - * Represents a Repository for a specific type of entity `Entity`, with an ID type - * of `ObjectId`. Implementing this repository will gain you the exact same useful methods - * that are on [PanacheMongoEntityBase]. If you have a custom ID strategy, you should - * implement [PanacheMongoRepositoryBase] instead. - * - * @param Entity The type of entity to operate on - */ -interface PanacheMongoRepository : PanacheMongoRepositoryBase \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoRepositoryBase.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoRepositoryBase.kt deleted file mode 100755 index 293355f253372..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheMongoRepositoryBase.kt +++ /dev/null @@ -1,728 +0,0 @@ -@file:Suppress("unused") - -package io.quarkus.mongodb.panache.kotlin - -import com.mongodb.client.MongoCollection -import com.mongodb.client.MongoDatabase -import io.quarkus.mongodb.panache.PanacheUpdate -import io.quarkus.mongodb.panache.kotlin.PanacheMongoEntityBase.Companion.operations -import io.quarkus.panache.common.Parameters -import io.quarkus.panache.common.Sort -import io.quarkus.panache.common.impl.GenerateBridge -import org.bson.Document -import java.util.stream.Stream - -/** - * Represents a Repository for a specific type of entity `Entity`, with an ID type - * of `Id`. Implementing this repository will gain you the exact same useful methods - * that are on [PanacheMongoEntityBase]. Unless you have a custom ID strategy, you should not - * implement this interface directly but implement [PanacheMongoRepository] instead. - * - * @param Entity The type of entity to operate on - * @param Id The ID type of the entity - * @see PanacheMongoRepository - */ -interface PanacheMongoRepositoryBase { - /** - * Persist the given entity in the database. - * This will set it's ID field if not already set. - * - * @param entity the entity to insert. - * @see [persist] - */ - fun persist(entity: Entity) = operations.persist(entity) - - /** - * Update the given entity in the database. - * - * @param entity the entity to update. - * @see [update] - */ - fun update(entity: Entity) = operations.update(entity) - - /** - * Persist the given entity in the database or update it if it already exist. - * - * @param entity the entity to update. - * @see [persistOrUpdate] - */ - fun persistOrUpdate(entity: Entity) = operations.persistOrUpdate(entity) - - /** - * Delete the given entity from the database, if it is already persisted. - * - * @param entity the entity to delete. - * @see [delete] - * @see [deleteAll] - */ - fun delete(entity: Entity) = operations.delete(entity) - - /** - * Find an entity of this type by ID. - * - * @param id the ID of the entity to find. - * @return the entity found, or `null` if not found. - */ - @GenerateBridge(targetReturnTypeErased = true) - fun findById(id: Id): Entity? = throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, vararg params: Any?): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options, with optional indexed parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, sort: Sort, vararg params: Any?): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, params: Map): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options, with named parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, sort: Sort, params: Map): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with named parameters. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, params: Parameters): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options, with named parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Parameters] of indexed parameters - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, sort: Sort, params: Parameters): PanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * - * @param query a [Document] query - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: Document): PanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * - * @param query a [Document] query - * @param sort the [Document] sort - * @return a new [PanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: Document, sort: Document): PanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * - * @return a new [PanacheQuery] instance to find all entities of this type. - * @see [findAll] - * @see [listAll] - * @see [streamAll] - */ - @GenerateBridge - fun findAll(): PanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * - * @param sort the sort order to use - * @return a new [PanacheQuery] instance to find all entities of this type. - * @see [findAll] - * @see [listAll] - * @see [streamAll] - */ - @GenerateBridge - fun findAll(sort: Sort): PanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with optional indexed parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, vararg params: Any?): List = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with optional indexed parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, sort: Sort, vararg params: Any?): List = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, params: Map): List = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, sort: Sort, params: Map): List = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, params: Parameters): List = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Parameters] of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, sort: Sort, params: Parameters): List = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * This method is a shortcut for `find(query).list()`. - * - * @param query a [Document] query - * @return a [List] containing all results, without paging - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun list(query: Document): List = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * This method is a shortcut for `find(query, sort).list()`. - * - * @param query a [Document] query - * @param sort the [Document] sort - * @return a [List] containing all results, without paging - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun list(query: Document, sort: Document): List = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * This method is a shortcut for `findAll().list()`. - * - * @return a [List] containing all results, without paging - * @see [listAll] - * @see [findAll] - * @see [streamAll] - */ - @GenerateBridge - fun listAll(): List = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * This method is a shortcut for `findAll(sort).list()`. - * - * @param sort the sort order to use - * @return a [List] containing all results, without paging - * @see [listAll] - * @see [findAll] - * @see [streamAll] - */ - @GenerateBridge - fun listAll(sort: Sort): List = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with optional indexed parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a [Stream] containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, vararg params: Any?): Stream = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with optional indexed parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a [Stream] containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, sort: Sort, vararg params: Any?): Stream = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a [Stream] containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, params: Map): Stream = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a [Stream] containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, sort: Sort, params: Map): Stream = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return a [Stream] containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, params: Parameters): Stream = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Parameters] of indexed parameters - * @return a [Stream] containing all results, without paging - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, sort: Sort, params: Parameters): Stream = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * This method is a shortcut for `find(query).stream()`. - * - * @param query a [Document] query - * @return a [Stream] containing all results, without paging - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun stream(query: Document): Stream = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * This method is a shortcut for `find(query, sort).stream()`. - * - * @param query a [Document] query - * @param sort the [Document] sort - * @return a [Stream] containing all results, without paging - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun stream(query: Document, sort: Document): Stream = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * This method is a shortcut for `findAll().stream()`. - * - * @return a [Stream] containing all results, without paging - * @see [streamAll] - * @see [findAll] - * @see [listAll] - */ - @GenerateBridge - fun streamAll(sort: Sort): Stream = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * This method is a shortcut for `findAll(sort).stream()`. - * - * @return a [Stream] containing all results, without paging - * @see [streamAll] - * @see [findAll] - * @see [listAll] - */ - @GenerateBridge - fun streamAll(): Stream = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity in the database. - * - * @return the number of this type of entity in the database. - * @see [count] - */ - @GenerateBridge - fun count(): Long = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return the number of entities counted. - * @see [count] - */ - @GenerateBridge - fun count(query: String, vararg params: Any?): Long = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return the number of entities counted. - * @see [count] - */ - @GenerateBridge - fun count(query: String, params: Map): Long = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query, with named parameters. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return the number of entities counted. - * @see [count] - */ - @GenerateBridge - fun count(query: String, params: Parameters): Long = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query - * - * @param query a [Document] query - * @return he number of entities counted. - * @see [count] - */ - @GenerateBridge - fun count(query: Document): Long = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type from the database. - * - * @return the number of entities deleted. - * @see [delete] - */ - @GenerateBridge - fun deleteAll(): Long = throw operations.implementationInjectionMissing() - - /** - * Delete an entity of this type by ID. - * - * @param id the ID of the entity to delete. - * @return false if the entity was not deleted (not found). - */ - @GenerateBridge - fun deleteById(id: Id): Boolean = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return the number of entities deleted. - * @see [deleteAll] - * @see [delete] - */ - @GenerateBridge - fun delete(query: String, vararg params: Any?): Long = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return the number of entities deleted. - * @see [deleteAll] - * @see [delete] - */ - @GenerateBridge - fun delete(query: String, params: Map): Long = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with named parameters. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return the number of entities deleted. - * @see [deleteAll] - * @see [delete] - */ - @GenerateBridge - fun delete(query: String, params: Parameters): Long = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query - * - * @param query a [Document] query - * @return he number of entities counted. - * @see [count] - */ - @GenerateBridge - fun delete(query: Document): Long = throw operations.implementationInjectionMissing() - - /** - * Persist all given entities. - * - * @param entities the entities to insert - * @see [persist] - */ - fun persist(entities: Iterable) = operations.persist(entities) - - /** - * Persist all given entities. - * - * @param entities the entities to insert - * @see [persist] - */ - fun persist(entities: Stream) = operations.persist(entities) - - /** - * Persist all given entities. - * - * @param entities the entities to insert - * @see [persist] - */ - fun persist(firstEntity: Entity, vararg entities: Entity) = operations.persist(firstEntity, *entities) - - /** - * Update all given entities. - * - * @param entities the entities to update - * @see [update] - */ - fun update(entities: Iterable) = operations.update(entities) - - /** - * Update all given entities. - * - * @param entities the entities to update - * @see [update] - */ - fun update(entities: Stream) = operations.update(entities) - - /** - * Update all given entities. - * - * @param entities the entities to update - * @see [update] - */ - fun update(firstEntity: Entity, vararg entities: Entity) = operations.update(firstEntity, *entities) - - /** - * Persist all given entities or update them if they already exist. - * - * @param entities the entities to update - * @see [persistOrUpdate] - */ - fun persistOrUpdate(entities: Iterable) = operations.persistOrUpdate(entities) - - /** - * Persist all given entities or update them if they already exist. - * - * @param entities the entities to update - * @see [persistOrUpdate] - */ - fun persistOrUpdate(entities: Stream) = operations.persistOrUpdate(entities) - - /** - * Persist all given entities or update them if they already exist. - * - * @param entities the entities to update - * @see [update] - */ - fun persistOrUpdate(firstEntity: Entity, vararg entities: Entity) = - operations.persistOrUpdate(firstEntity, *entities) - - /** - * Update all entities of this type by the given update document, with optional indexed parameters. - * The returned [PanacheUpdate] object will allow to restrict on which documents the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. - * It can also be expressed as a query string. - * @param params optional sequence of indexed parameters - * @return a new [PanacheUpdate] instance for the given update document - * @see [update] - */ - @GenerateBridge - fun update(update: String, vararg params: Any?): PanacheUpdate = throw operations.implementationInjectionMissing() - - /** - * Update all entities of this type by the given update document, with named parameters. - * The returned [PanacheUpdate] object will allow to restrict on which documents the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. - * It can also be expressed as a query string. - * @param params [Map] of named parameters - * @return a new [PanacheUpdate] instance for the given update document - * @see [update] - */ - @GenerateBridge - fun update(update: String, params: Map): PanacheUpdate = - throw operations.implementationInjectionMissing() - - /** - * Update all entities of this type by the given update document, with named parameters. - * The returned [PanacheUpdate] object will allow to restrict on which document the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. - * It can also be expressed as a query string. - * @param params [Parameters] of named parameters - * @return a new [PanacheUpdate] instance for the given update document - * @see [update] - */ - @GenerateBridge - fun update(update: String, params: Parameters): PanacheUpdate = throw operations.implementationInjectionMissing() - - /** - * Allow to access the underlying Mongo Collection - */ - @GenerateBridge - fun mongoCollection(): MongoCollection = throw operations.implementationInjectionMissing() - - /** - * Allow to access the underlying Mongo Database. - */ - @GenerateBridge - fun mongoDatabase(): MongoDatabase = throw operations.implementationInjectionMissing() -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheQuery.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheQuery.kt deleted file mode 100644 index 70d74a11e76bc..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/PanacheQuery.kt +++ /dev/null @@ -1,187 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin - -import com.mongodb.client.model.Collation -import io.quarkus.panache.common.Page -import io.quarkus.panache.common.exception.PanacheQueryException -import java.util.stream.Stream - -/** - * Interface representing an entity query, which abstracts the use of paging, getting the number of results, and - * operating on [List] or [Stream]. - * - * Instances of this interface cannot mutate the query itself or its parameters: only paging information can be - * modified, and instances of this interface can be reused to obtain multiple pages of results. - * - * @param Entity The entity type being queried - */ -interface PanacheQuery { - /** - * Defines a projection class: the getters, and the public fields, will be used to restrict which fields should be - * retrieved from the database. - * - * @return a new query with the same state as the previous one (params, page, range, ...). - */ - fun project(type: Class): PanacheQuery - - /** - * Sets the current page. - * - * @param page the new page - * @return this query, modified - * @see .page - * @see .page - */ - fun page(page: Page): PanacheQuery - - /** - * Sets the current page. - * - * @param pageIndex the page index - * @param pageSize the page size - * @return this query, modified - * @see .page - * @see .page - */ - fun page(pageIndex: Int, pageSize: Int): PanacheQuery - - /** - * Sets the current page to the next page - * - * @return this query, modified - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .previousPage - */ - fun nextPage(): PanacheQuery - - /** - * Sets the current page to the previous page (or the first page if there is no previous page) - * - * @return this query, modified - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .nextPage - */ - fun previousPage(): PanacheQuery - - /** - * Sets the current page to the first page - * - * @return this query, modified - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .lastPage - */ - fun firstPage(): PanacheQuery - - /** - * Sets the current page to the last page. This will cause reading of the entity count. - * - * @return this query, modified - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .firstPage - * @see .count - */ - fun lastPage(): PanacheQuery - - /** - * Returns true if there is another page to read after the current one. - * This will cause reading of the entity count. - * - * @return true if there is another page to read - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .hasPreviousPage - * @see .count - */ - fun hasNextPage(): Boolean - - /** - * Returns true if there is a page to read before the current one. - * - * @return true if there is a previous page to read - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .hasNextPage - */ - fun hasPreviousPage(): Boolean - - /** - * Returns the total number of pages to be read using the current page size. - * This will cause reading of the entity count. - * - * @return the total number of pages to be read using the current page size. - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - */ - fun pageCount(): Int - - /** - * Returns the current page. - * - * @return the current page - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .page - * @see .page - */ - fun page(): Page - - /** - * Switch the query to use a fixed range (start index - last index) instead of a page. - * As the range is fixed, subsequent pagination of the query is not possible. - * - * @param startIndex the index of the first element, starting at 0 - * @param lastIndex the index of the last element - * @return this query, modified - */ - fun range(startIndex: Int, lastIndex: Int): PanacheQuery - - /** - * Define the collation used for this query. - * - * @param collation the collation to be used for this query. - * @return this query, modified - */ - fun withCollation(collation: Collation): PanacheQuery - // Results - /** - * Reads and caches the total number of entities this query operates on. This causes a database - * query with `SELECT COUNT(*)` and a query equivalent to the current query, minus - * ordering. - * - * @return the total number of entities this query operates on, cached. - */ - fun count(): Long - - /** - * Returns the current page of results as a [List]. - * - * @return the current page of results as a [List]. - * @see .stream - * @see .page - * @see .page - */ - fun list(): List - - /** - * Returns the current page of results as a [Stream]. - * - * @return the current page of results as a [Stream]. - * @see .list - * @see .page - * @see .page - */ - fun stream(): Stream - - /** - * Returns the first result of the current page index. This ignores the current page size to fetch - * a single result. - * - * @return the first result of the current page index, or null if there are no results. - * @see .singleResult - */ - fun firstResult(): Entity? - - /** - * Executes this query for the current page and return a single result. - * - * @return the single result - * @throws PanacheQueryException if there is not exactly one result. - * @see .firstResult - */ - fun singleResult(): Entity? -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoCompanion.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoCompanion.kt deleted file mode 100644 index 86407a663eb52..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoCompanion.kt +++ /dev/null @@ -1,771 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.reactive - -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoEntityBase.Companion.operations -import io.quarkus.mongodb.panache.reactive.ReactivePanacheUpdate -import io.quarkus.mongodb.reactive.ReactiveMongoCollection -import io.quarkus.mongodb.reactive.ReactiveMongoDatabase -import io.quarkus.panache.common.Parameters -import io.quarkus.panache.common.Sort -import io.quarkus.panache.common.impl.GenerateBridge -import io.smallrye.mutiny.Multi -import io.smallrye.mutiny.Uni -import org.bson.Document -import org.bson.types.ObjectId -import java.util.stream.Stream - -/** - * Define persistence and query methods for an Entity with a default ID type of [ObjectId] - * - * @param Entity the entity type - */ -interface ReactivePanacheMongoCompanion - : ReactivePanacheMongoCompanionBase - -/** - * Define persistence and query methods for an Entity with a type of Id - * - * @param Entity the entity type - * @param Id the ID type - */ -interface ReactivePanacheMongoCompanionBase { - /** - * Find an entity of this type by ID. - * - * @param id the ID of the entity to find. - * @return the entity found, or `null` if not found. - */ - @GenerateBridge - fun findById(id: Id): Uni = throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see [find] - * @see [find] - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, vararg params: Any?): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options, with optional indexed parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see [find] - * @see [find] - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, sort: Sort, vararg params: Any?): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see [find] - * @see [find] - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, params: Map): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options, with named parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see [find] - * @see [find] - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, sort: Sort, params: Map): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with named parameters. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see [find] - * @see [find] - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, params: Parameters): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options, with named parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Parameters] of indexed parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see [find] - * @see [find] - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun find(query: String, sort: Sort, params: Parameters): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * - * @param query a [Document] query - * @return a new [ReactivePanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [list] - * @see [stream] - * @see [stream] - */ - @GenerateBridge - fun find(query: Document): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * - * @param query a [Document] query - * @param sort the [Document] sort - * @return a new [ReactivePanacheQuery] instance for the given query - * @see [find] - * @see [list] - * @see [list] - * @see [stream] - * @see [stream] - */ - @GenerateBridge - fun find(query: Document, sort: Document): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * - * @return a new [ReactivePanacheQuery] instance to find all entities of this type. - * @see [findAll] - * @see [listAll] - * @see [streamAll] - */ - @GenerateBridge - fun findAll(): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * - * @param sort the sort order to use - * @return a new [ReactivePanacheQuery] instance to find all entities of this type. - * @see [findAll] - * @see [listAll] - * @see [streamAll] - */ - @GenerateBridge - fun findAll(sort: Sort): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with optional indexed parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [list] - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, vararg params: Any?): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with optional indexed parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [list] - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, sort: Sort, vararg params: Any?): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [list] - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, params: Map): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [list] - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, sort: Sort, params: Map): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [list] - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, params: Parameters): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Parameters] of indexed parameters - * @return a [List] containing all results, without paging - * @see [list] - * @see [list] - * @see [list] - * @see [find] - * @see [stream] - */ - @GenerateBridge - fun list(query: String, sort: Sort, params: Parameters): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * This method is a shortcut for `find(query).list()`. - * - * @param query a [Document] query - * @return a [List] containing all results, without paging - * @see [find] - * @see [find] - * @see [list] - * @see [stream] - * @see [stream] - */ - @GenerateBridge - fun list(query: Document): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * This method is a shortcut for `find(query, sort).list()`. - * - * @param query a [Document] query - * @param sort the [Document] sort - * @return a [List] containing all results, without paging - * @see [find] - * @see [find] - * @see [list] - * @see [stream] - * @see [stream] - */ - @GenerateBridge - fun list(query: Document, sort: Document): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * This method is a shortcut for `findAll().list()`. - * - * @return a [List] containing all results, without paging - * @see [listAll] - * @see [findAll] - * @see [streamAll] - */ - @GenerateBridge - fun listAll(): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * This method is a shortcut for `findAll(sort).list()`. - * - * @param sort the sort order to use - * @return a [List] containing all results, without paging - * @see [listAll] - * @see [findAll] - * @see [streamAll] - */ - @GenerateBridge - fun listAll(sort: Sort): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with optional indexed parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a [Multi] containing all results, without paging - * @see [stream] - * @see [stream] - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, vararg params: Any?): Multi = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with optional indexed parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a [Multi] containing all results, without paging - * @see [stream] - * @see [stream] - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, sort: Sort, vararg params: Any?): Multi = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a [Multi] containing all results, without paging - * @see [stream] - * @see [stream] - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, params: Map): Multi = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a [Multi] containing all results, without paging - * @see [stream] - * @see [stream] - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, sort: Sort, params: Map): Multi = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return a [Multi] containing all results, without paging - * @see [stream] - * @see [stream] - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, params: Parameters): Multi = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Parameters] of indexed parameters - * @return a [Multi] containing all results, without paging - * @see [stream] - * @see [stream] - * @see [stream] - * @see [find] - * @see [list] - */ - @GenerateBridge - fun stream(query: String, sort: Sort, params: Parameters): Multi = throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * This method is a shortcut for `find(query).stream()`. - * - * @param query a [Document] query - * @return a [Multi] containing all results, without paging - * @see [find] - * @see [find] - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun stream(query: Document): Multi = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * This method is a shortcut for `find(query, sort).stream()`. - * - * @param query a [Document] query - * @param sort the [Document] sort - * @return a [Multi] containing all results, without paging - * @see [find] - * @see [find] - * @see [find] - * @see [list] - * @see [stream] - */ - @GenerateBridge - fun stream(query: Document, sort: Document): Multi = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * This method is a shortcut for `findAll().stream()`. - * - * @return a [Multi] containing all results, without paging - * @see [streamAll] - * @see [findAll] - * @see [listAll] - */ - @GenerateBridge - fun streamAll(): Multi = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * This method is a shortcut for `findAll(sort).stream()`. - * - * @param sort the sort order to use - * @return a [Multi] containing all results, without paging - * @see [streamAll] - * @see [findAll] - * @see [listAll] - */ - @GenerateBridge - fun streamAll(sort: Sort): Multi = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity in the database. - * - * @return the number of this type of entity in the database. - * @see [count] - * @see [count] - * @see [count] - */ - @GenerateBridge - fun count(): Uni = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return the number of entities counted. - * @see [count] - * @see [count] - * @see [count] - */ - @GenerateBridge - fun count(query: String, vararg params: Any?): Uni = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return the number of entities counted. - * @see [count] - * @see [count] - * @see [count] - */ - @GenerateBridge - fun count(query: String, params: Map): Uni = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query, with named parameters. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return the number of entities counted. - * @see [count] - * @see [count] - * @see [count] - */ - @GenerateBridge - fun count(query: String, params: Parameters): Uni = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query - * - * @param query a [Document] query - * @return he number of entities counted. - * @see [count] - * @see [count] - * @see [count] - */ - @GenerateBridge - fun count(query: Document): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type from the database. - * - * @return the number of entities deleted. - * @see [delete] - * @see [delete] - * @see [delete] - */ - @GenerateBridge - fun deleteAll(): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete an entity of this type by ID. - * - * @param id the ID of the entity to delete. - * @return false if the entity was not deleted (not found). - */ - @GenerateBridge - fun deleteById(id: Id): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return the number of entities deleted. - * @see [deleteAll] - * @see [delete] - * @see [delete] - */ - @GenerateBridge - fun delete(query: String, vararg params: Any?): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return the number of entities deleted. - * @see [deleteAll] - * @see [delete] - * @see [delete] - */ - @GenerateBridge - fun delete(query: String, params: Map): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with named parameters. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return the number of entities deleted. - * @see [deleteAll] - * @see [delete] - * @see [delete] - */ - @GenerateBridge - fun delete(query: String, params: Parameters): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query - * - * @param query a [Document] query - * @return he number of entities counted. - * @see [count] - * @see [count] - * @see [count] - */ - @GenerateBridge - fun delete(query: Document): Uni = throw operations.implementationInjectionMissing() - - /** - * Insert all given entities. - * - * @param entities the entities to insert - * @see [persist] - * @see [persist] - * @see [persist] - */ - fun persist(entities: Iterable): Uni = operations.persist(entities) - - /** - * Insert all given entities. - * - * @param entities the entities to insert - * @see [persist] - * @see [persist] - * @see [persist] - */ - fun persist(entities: Stream): Uni = operations.persist(entities) - - /** - * Insert all given entities. - * - * @param entities the entities to update - * @see [persist] - * @see [persist] - * @see [persist] - */ - fun persist(firstEntity: Entity, vararg entities: Entity): Uni = operations.persist(firstEntity, *entities) - - /** - * Update all given entities. - * - * @param entities the entities to update - * @see [update] - * @see [update] - * @see [update] - */ - fun update(entities: Iterable): Uni = operations.update(entities) - - /** - * Update all given entities. - * - * @param entities the entities to insert - * @see [update] - * @see [update] - * @see [update] - */ - fun update(entities: Stream): Uni = operations.update(entities) - - /** - * Update all given entities. - * - * @param entities the entities to update - * @see [update] - * @see [update] - * @see [update] - */ - fun update(firstEntity: Entity, vararg entities: Entity): Uni = operations.update(firstEntity, *entities) - - /** - * Persist all given entities or update them if they already exist. - * - * @param entities the entities to update - * @see [persistOrUpdate] - * @see [persistOrUpdate] - * @see [persistOrUpdate] - */ - fun persistOrUpdate(entities: Iterable): Uni = operations.persistOrUpdate(entities) - - /** - * Persist all given entities. - * - * @param entities the entities to insert - * @see [persistOrUpdate] - * @see [persistOrUpdate] - * @see [persistOrUpdate] - */ - fun persistOrUpdate(entities: Stream): Uni = operations.persistOrUpdate(entities) - - /** - * Persist all given entities. - * - * @param entities the entities to update - * @see [persistOrUpdate] - * @see [persistOrUpdate] - * @see [persistOrUpdate] - */ - fun persistOrUpdate(firstEntity: Entity, vararg entities: Entity): Uni = - operations.persistOrUpdate(firstEntity, *entities) - - /** - * Update all entities of this type by the given update document, with optional indexed parameters. - * The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. - * It can also be expressed as a query string. - * @param params optional sequence of indexed parameters - * @return a new [ReactivePanacheUpdate] instance for the given update document - * @see [update] - * @see [update] - */ - @GenerateBridge - fun update(update: String, vararg params: Any?): ReactivePanacheUpdate = throw operations.implementationInjectionMissing() - - /** - * Update all entities of this type by the given update document, with named parameters. - * The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. - * It can also be expressed as a query string. - * @param params [Map] of named parameters - * @return a new [ReactivePanacheUpdate] instance for the given update document - * @see [update] - */ - @GenerateBridge - fun update(update: String, params: Map): ReactivePanacheUpdate = throw operations.implementationInjectionMissing() - - /** - * Update all entities of this type by the given update document, with named parameters. - * The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. - * It can also be expressed as a query string. - * @param params [Parameters] of named parameters - * @return a new [ReactivePanacheUpdate] instance for the given update document - * @see [update] - */ - @GenerateBridge - fun update(update: String, params: Parameters): ReactivePanacheUpdate = throw operations.implementationInjectionMissing() - - /** - * Allow to access the underlying Mongo Collection. - */ - @GenerateBridge - fun mongoCollection(): ReactiveMongoCollection = throw operations.implementationInjectionMissing() - - /** - * Allow to access the underlying Mongo Database. - */ - @GenerateBridge - fun mongoDatabase(): ReactiveMongoDatabase = throw operations.implementationInjectionMissing() - -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoEntity.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoEntity.kt deleted file mode 100644 index 2c886d900a7e7..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoEntity.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.reactive - -import org.bson.types.ObjectId - -/** - * Represents an entity with a generated ID field [id] of type [ObjectId]. If your - * Mongo entities extend this class they gain the ID field and auto-generated accessors - * to all their public fields, as well as all the useful methods from [ReactivePanacheMongoEntityBase]. - * - * If you want a custom ID type or strategy, you can directly extend [ReactivePanacheMongoEntityBase] - * instead, and write your own ID field. You will still get auto-generated accessors and - * all the useful methods. - * - * @see ReactivePanacheMongoEntityBase - */ -abstract class ReactivePanacheMongoEntity : ReactivePanacheMongoEntityBase() { - /** - * The auto-generated ID field. - * This field is set by Mongo when this entity is persisted. - * - * @see [persist] - */ - var id: ObjectId? = null - - /** - * Default toString() implementation - * - * @return the class type and ID type - */ - override fun toString(): String = "${javaClass.simpleName}<$id>" -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoEntityBase.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoEntityBase.kt deleted file mode 100644 index 1fe00ef0556dd..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoEntityBase.kt +++ /dev/null @@ -1,64 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.reactive - -import io.quarkus.mongodb.panache.kotlin.reactive.runtime.KotlinReactiveMongoOperations -import io.smallrye.mutiny.Uni - -/** - * Represents an entity. If your Mongo entities extend this class they gain auto-generated accessors - * to all their public fields, as well as a lot of useful - * methods. Unless you have a custom ID strategy, you should not extend this class directly but extend - * [ReactivePanacheMongoEntity] instead. - * - * @see ReactivePanacheMongoEntity - */ -abstract class ReactivePanacheMongoEntityBase { - /** - * Defines internal implementation details for use by quarkus. Use of these members is highly discouraged as the - * implementation may change without warning. - */ - companion object { - /** - * Provides the default implementations for quarkus to wire up. Should not be used by third party developers. - */ - @JvmStatic - val operations = KotlinReactiveMongoOperations() - } - - /** - * Persist this entity in the database. - * This will set it's ID field if not already set. - * - * @see .persist - * @see .persist - * @see .persist - */ - fun persist(): Uni = operations.persist(this) - - /** - * Update this entity in the database. - * - * @see .update - * @see .update - * @see .update - */ - fun update(): Uni = operations.update(this) - - /** - * Persist this entity in the database or update it if it already exist. - * - * @see .persistOrUpdate - * @see .persistOrUpdate - * @see .persistOrUpdate - */ - fun persistOrUpdate(): Uni = operations.persistOrUpdate(this) - - /** - * Delete this entity from the database, if it is already persisted. - * - * @see .delete - * @see .delete - * @see .delete - * @see .deleteAll - */ - fun delete(): Uni = operations.delete(this) -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoRepository.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoRepository.kt deleted file mode 100644 index 6d02e9db4fea5..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoRepository.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.reactive - -import org.bson.types.ObjectId - -/** - * Represents a Repository for a specific type of entity `Entity`, with an ID type - * of `ObjectId`. Implementing this repository will gain you the exact same useful methods - * that are on [ReactivePanacheMongoEntityBase]. If you have a custom ID strategy, you should - * implement [ReactivePanacheMongoRepositoryBase] instead. - * - * @param Entity The type of entity to operate on - */ -interface ReactivePanacheMongoRepository : ReactivePanacheMongoRepositoryBase \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoRepositoryBase.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoRepositoryBase.kt deleted file mode 100644 index 13aabded7c0dd..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheMongoRepositoryBase.kt +++ /dev/null @@ -1,833 +0,0 @@ -@file:Suppress("unused") - -package io.quarkus.mongodb.panache.kotlin.reactive - -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoEntityBase.Companion.operations -import io.quarkus.mongodb.panache.reactive.ReactivePanacheUpdate -import io.quarkus.mongodb.reactive.ReactiveMongoCollection -import io.quarkus.mongodb.reactive.ReactiveMongoDatabase -import io.quarkus.panache.common.Parameters -import io.quarkus.panache.common.Sort -import io.quarkus.panache.common.impl.GenerateBridge -import io.smallrye.mutiny.Multi -import io.smallrye.mutiny.Uni -import org.bson.Document -import java.util.stream.Stream - -/** - * Represents a Repository for a specific type of entity `Entity`, with an ID type - * of `Id`. Implementing this repository will gain you the exact same useful methods - * that are on [ReactivePanacheMongoEntityBase]. Unless you have a custom ID strategy, you should not - * implement this interface directly but implement [ReactivePanacheMongoRepository] instead. - * - * @param Entity The type of entity to operate on - * @param Id The ID type of the entity - * @see ReactivePanacheMongoRepository - */ -interface ReactivePanacheMongoRepositoryBase { - /** - * Persist the given entity in the database. - * This will set it's ID field if not already set. - * - * @param entity the entity to insert. - * @see .persist - * @see .persist - * @see .persist - */ - fun persist(entity: Entity): Uni = operations.persist(entity) - - /** - * Update the given entity in the database. - * - * @param entity the entity to update. - * @see .update - * @see .update - * @see .update - */ - fun update(entity: Entity): Uni = operations.update(entity) - - /** - * Persist the given entity in the database or update it if it already exist. - * - * @param entity the entity to update. - * @see .persistOrUpdate - * @see .persistOrUpdate - * @see .persistOrUpdate - */ - fun persistOrUpdate(entity: Entity): Uni = operations.persistOrUpdate(entity) - - /** - * Delete the given entity from the database, if it is already persisted. - * - * @param entity the entity to delete. - * @see .delete - * @see .delete - * @see .delete - * @see .deleteAll - */ - fun delete(entity: Entity): Uni = operations.delete(entity) - - /** - * Find an entity of this type by ID. - * - * @param id the ID of the entity to find. - * @return the entity found, or `null` if not found. - */ - @GenerateBridge - fun findById(id: Id): Uni = throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see .find - * @see .find - * @see .find - * @see .list - * @see .stream - */ - @GenerateBridge - fun find(query: String, vararg params: Any?): ReactivePanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options, with optional indexed parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see .find - * @see .find - * @see .find - * @see .list - * @see .stream - */ - @GenerateBridge - fun find(query: String, sort: Sort, vararg params: Any?): ReactivePanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see .find - * @see .find - * @see .find - * @see .list - * @see .stream - */ - @GenerateBridge - fun find(query: String, params: Map): ReactivePanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options, with named parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see .find - * @see .find - * @see .find - * @see .list - * @see .stream - */ - @GenerateBridge - fun find(query: String, sort: Sort, params: Map): ReactivePanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query, with named parameters. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see .find - * @see .find - * @see .find - * @see .list - * @see .stream - */ - @GenerateBridge - fun find(query: String, params: Parameters): ReactivePanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a query and the given sort options, with named parameters. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Parameters] of indexed parameters - * @return a new [ReactivePanacheQuery] instance for the given query - * @see .find - * @see .find - * @see .find - * @see .list - * @see .stream - */ - @GenerateBridge - fun find(query: String, sort: Sort, params: Parameters): ReactivePanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * - * @param query a [Document] query - * @return a new [ReactivePanacheQuery] instance for the given query - * @see .find - * @see .list - * @see .list - * @see .stream - * @see .stream - */ - @GenerateBridge - fun find(query: Document): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * - * @param query a [Document] query - * @param sort the [Document] sort - * @return a new [ReactivePanacheQuery] instance for the given query - * @see .find - * @see .list - * @see .list - * @see .stream - * @see .stream - */ - @GenerateBridge - fun find(query: Document, sort: Document): ReactivePanacheQuery = - throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * - * @return a new [ReactivePanacheQuery] instance to find all entities of this type. - * @see .findAll - * @see .listAll - * @see .streamAll - */ - @GenerateBridge - fun findAll(): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * - * @param sort the sort order to use - * @return a new [ReactivePanacheQuery] instance to find all entities of this type. - * @see .findAll - * @see .listAll - * @see .streamAll - */ - @GenerateBridge - fun findAll(sort: Sort): ReactivePanacheQuery = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with optional indexed parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a [List] containing all results, without paging - * @see .list - * @see .list - * @see .list - * @see .find - * @see .stream - */ - @GenerateBridge - fun list(query: String, vararg params: Any?): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with optional indexed parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a [List] containing all results, without paging - * @see .list - * @see .list - * @see .list - * @see .find - * @see .stream - */ - @GenerateBridge - fun list(query: String, sort: Sort, vararg params: Any?): Uni> = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a [List] containing all results, without paging - * @see .list - * @see .list - * @see .list - * @see .find - * @see .stream - */ - @GenerateBridge - fun list(query: String, params: Map): Uni> = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a [List] containing all results, without paging - * @see .list - * @see .list - * @see .list - * @see .find - * @see .stream - */ - @GenerateBridge - fun list(query: String, sort: Sort, params: Map): Uni> = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).list()`. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return a [List] containing all results, without paging - * @see .list - * @see .list - * @see .list - * @see .find - * @see .stream - */ - @GenerateBridge - fun list(query: String, params: Parameters): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).list()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Parameters] of indexed parameters - * @return a [List] containing all results, without paging - * @see .list - * @see .list - * @see .list - * @see .find - * @see .stream - */ - @GenerateBridge - fun list(query: String, sort: Sort, params: Parameters): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * This method is a shortcut for `find(query).list()`. - * - * @param query a [Document] query - * @return a [List] containing all results, without paging - * @see .find - * @see .find - * @see .list - * @see .stream - * @see .stream - */ - @GenerateBridge - fun list(query: Document): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * This method is a shortcut for `find(query, sort).list()`. - * - * @param query a [Document] query - * @param sort the [Document] sort - * @return a [List] containing all results, without paging - * @see .find - * @see .find - * @see .list - * @see .stream - * @see .stream - */ - @GenerateBridge - fun list(query: Document, sort: Document): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * This method is a shortcut for `findAll().list()`. - * - * @return a [List] containing all results, without paging - * @see .listAll - * @see .findAll - * @see .streamAll - */ - @GenerateBridge - fun listAll(): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * This method is a shortcut for `findAll(sort).list()`. - * - * @param sort the sort order to use - * @return a [List] containing all results, without paging - * @see .listAll - * @see .findAll - * @see .streamAll - */ - @GenerateBridge - fun listAll(sort: Sort): Uni> = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with optional indexed parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return a [Multi] containing all results, without paging - * @see .stream - * @see .stream - * @see .stream - * @see .find - * @see .list - */ - @GenerateBridge - fun stream(query: String, vararg params: Any?): Multi = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with optional indexed parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params optional sequence of indexed parameters - * @return a [Multi] containing all results, without paging - * @see .stream - * @see .stream - * @see .stream - * @see .find - * @see .list - */ - @GenerateBridge - fun stream(query: String, sort: Sort, vararg params: Any?): Multi = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params [Map] of named parameters - * @return a [Multi] containing all results, without paging - * @see .stream - * @see .stream - * @see .stream - * @see .find - * @see .list - */ - @GenerateBridge - fun stream(query: String, params: Map): Multi = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Map] of indexed parameters - * @return a [Multi] containing all results, without paging - * @see .stream - * @see .stream - * @see .stream - * @see .find - * @see .list - */ - @GenerateBridge - fun stream(query: String, sort: Sort, params: Map): Multi = - throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query, with named parameters. - * This method is a shortcut for `find(query, params).stream()`. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return a [Multi] containing all results, without paging - * @see .stream - * @see .stream - * @see .stream - * @see .find - * @see .list - */ - @GenerateBridge - fun stream(query: String, params: Parameters): Multi = throw operations.implementationInjectionMissing() - - /** - * Find entities matching a query and the given sort options, with named parameters. - * This method is a shortcut for `find(query, sort, params).stream()`. - * - * @param query a query string - * @param sort the sort strategy to use - * @param params [Parameters] of indexed parameters - * @return a [Multi] containing all results, without paging - * @see .stream - * @see .stream - * @see .stream - * @see .find - * @see .list - */ - @GenerateBridge - fun stream(query: String, sort: Sort, params: Parameters): Multi = - throw operations.implementationInjectionMissing() - - /** - * Find entities using a BSON query. - * This method is a shortcut for `find(query).stream()`. - * - * @param query a [Document] query - * @return a [Multi] containing all results, without paging - * @see .find - * @see .find - * @see .list - * @see .list - * @see .stream - * @see .stream - */ - @GenerateBridge - fun stream(query: Document): Multi = throw operations.implementationInjectionMissing() - - /** - * Find entities using a a BSON query and a BSON sort. - * This method is a shortcut for `find(query, sort).stream()`. - * - * @param query a [Document] query - * @param sort the [Document] sort - * @return a [Multi] containing all results, without paging - * @see .find - * @see .find - * @see .list - * @see .list - * @see .stream - * @see .stream - */ - @GenerateBridge - fun stream(query: Document, sort: Document): Multi = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type. - * This method is a shortcut for `findAll().stream()`. - * - * @return a [Multi] containing all results, without paging - * @see .streamAll - * @see .findAll - * @see .listAll - */ - @GenerateBridge - fun streamAll(sort: Sort): Multi = throw operations.implementationInjectionMissing() - - /** - * Find all entities of this type, in the given order. - * This method is a shortcut for `findAll(sort).stream()`. - * - * @return a [Multi] containing all results, without paging - * @see .streamAll - * @see .findAll - * @see .listAll - */ - @GenerateBridge - fun streamAll(): Multi = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity in the database. - * - * @return the number of this type of entity in the database. - * @see .count - * @see .count - * @see .count - */ - @GenerateBridge - fun count(): Uni = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return the number of entities counted. - * @see .count - * @see .count - * @see .count - */ - @GenerateBridge - fun count(query: String, vararg params: Any?): Uni = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return the number of entities counted. - * @see .count - * @see .count - * @see .count - */ - @GenerateBridge - fun count(query: String, params: Map): Uni = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query, with named parameters. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return the number of entities counted. - * @see .count - * @see .count - * @see .count - */ - @GenerateBridge - fun count(query: String, params: Parameters): Uni = throw operations.implementationInjectionMissing() - - /** - * Counts the number of this type of entity matching the given query - * - * @param query a [Document] query - * @return he number of entities counted. - * @see .count - * @see .count - * @see .count - */ - @GenerateBridge - fun count(query: Document): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type from the database. - * - * @return the number of entities deleted. - * @see .delete - * @see .delete - * @see .delete - */ - @GenerateBridge - fun deleteAll(): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete an entity of this type by ID. - * - * @param id the ID of the entity to delete. - * @return false if the entity was not deleted (not found). - */ - @GenerateBridge - fun deleteById(id: Id): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with optional indexed parameters. - * - * @param query a query string - * @param params optional sequence of indexed parameters - * @return the number of entities deleted. - * @see .deleteAll - * @see .delete - * @see .delete - */ - @GenerateBridge - fun delete(query: String, vararg params: Any?): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with named parameters. - * - * @param query a query string - * @param params [Map] of named parameters - * @return the number of entities deleted. - * @see .deleteAll - * @see .delete - * @see .delete - */ - @GenerateBridge - fun delete(query: String, params: Map): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query, with named parameters. - * - * @param query a query string - * @param params [Parameters] of named parameters - * @return the number of entities deleted. - * @see .deleteAll - * @see .delete - * @see .delete - */ - @GenerateBridge - fun delete(query: String, params: Parameters): Uni = throw operations.implementationInjectionMissing() - - /** - * Delete all entities of this type matching the given query - * - * @param query a [Document] query - * @return he number of entities counted. - * @see .count - * @see .count - * @see .count - */ - @GenerateBridge - fun delete(query: Document): Uni = throw operations.implementationInjectionMissing() - - /** - * Persist all given entities. - * - * @param entities the entities to insert - * @see .persist - * @see .persist - * @see .persist - */ - fun persist(entities: Iterable): Uni = operations.persist(entities) - - /** - * Persist all given entities. - * - * @param entities the entities to insert - * @see .persist - * @see .persist - * @see .persist - */ - fun persist(entities: Stream): Uni = operations.persist(entities) - - /** - * Persist all given entities. - * - * @param entities the entities to insert - * @see .persist - * @see .persist - * @see .persist - */ - fun persist(firstEntity: Entity, vararg entities: Entity): Uni = - operations.persist(firstEntity, *entities) - - /** - * Update all given entities. - * - * @param entities the entities to update - * @see .update - * @see .update - * @see .update - */ - fun update(entities: Iterable): Uni = operations.update(entities) - - /** - * Update all given entities. - * - * @param entities the entities to update - * @see .update - * @see .update - * @see .update - */ - fun update(entities: Stream): Uni = operations.update(entities) - - /** - * Update all given entities. - * - * @param entities the entities to update - * @see .update - * @see .update - * @see .update - */ - fun update(firstEntity: Entity, vararg entities: Entity): Uni = - operations.update(firstEntity, *entities) - - /** - * Persist all given entities or update them if they already exist. - * - * @param entities the entities to update - * @see .persistOrUpdate - * @see .persistOrUpdate - * @see .persistOrUpdate - */ - fun persistOrUpdate(entities: Iterable): Uni = - operations.persistOrUpdate(entities) - - /** - * Persist all given entities or update them if they already exist. - * - * @param entities the entities to update - * @see .persistOrUpdate - * @see .persistOrUpdate - * @see .persistOrUpdate - */ - fun persistOrUpdate(entities: Stream): Uni = - operations.persistOrUpdate(entities) - - /** - * Persist all given entities or update them if they already exist. - * - * @param entities the entities to update - * @see .update - * @see .update - * @see .update - */ - fun persistOrUpdate(firstEntity: Entity, vararg entities: Entity): Uni = - operations.persistOrUpdate(firstEntity, *entities) - - /** - * Update all entities of this type by the given update document, with optional indexed parameters. - * The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. - * It can also be expressed as a query string. - * @param params optional sequence of indexed parameters - * @return a new [ReactivePanacheUpdate] instance for the given update document - * @see .update - * @see .update - */ - @GenerateBridge - fun update(update: String, vararg params: Any?): ReactivePanacheUpdate = - throw operations.implementationInjectionMissing() - - /** - * Update all entities of this type by the given update document, with named parameters. - * The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. - * It can also be expressed as a query string. - * @param params [Map] of named parameters - * @return a new [ReactivePanacheUpdate] instance for the given update document - * @see .update - * @see .update - */ - @GenerateBridge - fun update(update: String, params: Map): ReactivePanacheUpdate = - throw operations.implementationInjectionMissing() - - /** - * Update all entities of this type by the given update document, with named parameters. - * The returned [ReactivePanacheUpdate] object will allow to restrict on which document the update should be applied. - * - * @param update the update document, if it didn't contain `$set` we add it. - * It can also be expressed as a query string. - * @param params [Parameters] of named parameters - * @return a new [ReactivePanacheUpdate] instance for the given update document - * @see .update - * @see .update - */ - @GenerateBridge - fun update(update: String, params: Parameters): ReactivePanacheUpdate = - throw operations.implementationInjectionMissing() - - /** - * Allow to access the underlying Mongo Collection - */ - @GenerateBridge - fun mongoCollection(): ReactiveMongoCollection = throw operations.implementationInjectionMissing() - - /** - * Allow to access the underlying Mongo Database. - */ - @GenerateBridge - fun mongoDatabase(): ReactiveMongoDatabase = throw operations.implementationInjectionMissing() -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheQuery.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheQuery.kt deleted file mode 100644 index 737c9d2e855cf..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/ReactivePanacheQuery.kt +++ /dev/null @@ -1,186 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.reactive - -import com.mongodb.client.model.Collation -import io.quarkus.panache.common.Page -import io.smallrye.mutiny.Multi -import io.smallrye.mutiny.Uni - -/** - * Interface representing an entity query, which abstracts the use of paging, getting the number of results, and - * operating on [List] or [Stream]. - * - * Instances of this interface cannot mutate the query itself or its parameters: only paging information can be - * modified, and instances of this interface can be reused to obtain multiple pages of results. - * - * @param Entity The entity type being queried - */ -interface ReactivePanacheQuery { - /** - * Defines a projection class: the getters, and the public fields, will be used to restrict which fields should be - * retrieved from the database. - * - * @return @return a new query with the same state as the previous one (params, page, range, ...). - */ - fun project(type: Class): ReactivePanacheQuery - - /** - * Sets the current page. - * - * @param page the new page - * @return this query, modified - * @see .page - * @see .page - */ - fun page(page: Page): ReactivePanacheQuery - - /** - * Sets the current page. - * - * @param pageIndex the page index - * @param pageSize the page size - * @return this query, modified - * @see .page - * @see .page - */ - fun page(pageIndex: Int, pageSize: Int): ReactivePanacheQuery - - /** - * Sets the current page to the next page - * - * @return this query, modified - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .previousPage - */ - fun nextPage(): ReactivePanacheQuery - - /** - * Sets the current page to the previous page (or the first page if there is no previous page) - * - * @return this query, modified - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .nextPage - */ - fun previousPage(): ReactivePanacheQuery - - /** - * Sets the current page to the first page - * - * @return this query, modified - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .lastPage - */ - fun firstPage(): ReactivePanacheQuery - - /** - * Sets the current page to the last page. This will cause reading of the entity count. - * - * @return this query, modified - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .firstPage - * @see .count - */ - fun lastPage(): Uni> - - /** - * Returns true if there is another page to read after the current one. - * This will cause reading of the entity count. - * - * @return true if there is another page to read - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .hasPreviousPage - * @see .count - */ - fun hasNextPage(): Uni - - /** - * Returns true if there is a page to read before the current one. - * - * @return true if there is a previous page to read - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .hasNextPage - */ - fun hasPreviousPage(): Boolean - - /** - * Returns the total number of pages to be read using the current page size. - * This will cause reading of the entity count. - * - * @return the total number of pages to be read using the current page size. - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - */ - fun pageCount(): Uni - - /** - * Returns the current page. - * - * @return the current page - * @throws UnsupportedOperationException if a page hasn't been set or if a range is already set - * @see .page - * @see .page - */ - fun page(): Page - - /** - * Switch the query to use a fixed range (start index - last index) instead of a page. - * As the range is fixed, subsequent pagination of the query is not possible. - * - * @param startIndex the index of the first element, starting at 0 - * @param lastIndex the index of the last element - * @return this query, modified - */ - fun range(startIndex: Int, lastIndex: Int): ReactivePanacheQuery - - /** - * Define the collation used for this query. - * - * @param collation the collation to be used for this query. - * @return this query, modified - */ - fun withCollation(collation: Collation): ReactivePanacheQuery - - /** - * Reads and caches the total number of entities this query operates on. This causes a database - * query with `SELECT COUNT(*)` and a query equivalent to the current query, minus - * ordering. - * - * @return the total number of entities this query operates on, cached. - */ - fun count(): Uni - - /** - * Returns the current page of results as a [List]. - * - * @return the current page of results as a [List]. - * @see .page - * @see .page - */ - fun list(): Uni> - - /** - * Returns the current page of results as a [Stream]. - * - * @return the current page of results as a [Stream]. - * @see .list - * @see .page - * @see .page - */ - fun stream(): Multi - - /** - * Returns the first result of the current page index. This ignores the current page size to fetch - * a single result. - * - * @return the first result of the current page index, or null if there are no results. - * @see .singleResult - */ - fun firstResult(): Uni - - /** - * Executes this query for the current page and return a single result. - * - * @return the single result. - * @throws io.quarkus.panache.common.exception.PanacheQueryException if there are more than one result. - * @see .firstResult - */ - fun singleResult(): Uni -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/runtime/KotlinReactiveMongoOperations.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/runtime/KotlinReactiveMongoOperations.kt deleted file mode 100644 index 6bd6d4dceb2d1..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/reactive/runtime/KotlinReactiveMongoOperations.kt +++ /dev/null @@ -1,59 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.reactive.runtime - -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheQuery -import io.quarkus.mongodb.panache.reactive.ReactivePanacheUpdate -import io.quarkus.mongodb.panache.reactive.runtime.ReactiveMongoOperations -import io.quarkus.mongodb.panache.reactive.runtime.ReactivePanacheUpdateImpl -import io.quarkus.mongodb.panache.runtime.MongoOperations -import io.quarkus.mongodb.reactive.ReactiveMongoCollection -import io.smallrye.mutiny.Multi -import io.smallrye.mutiny.Uni -import org.bson.Document -import java.util.stream.Stream - -/** - * Defines kotlin specific implementations of methods needed by [ReactiveMongoOperations]. - */ -class KotlinReactiveMongoOperations : ReactiveMongoOperations, ReactivePanacheUpdate>() { - /** - * Creates the query implementation - * - * @param collection the collection to query - * @param query the query to base the new query off of - * @param sortDoc the sort document to use - * - * @return the new query implementation - */ - override fun createQuery(collection: ReactiveMongoCollection<*>, query: Document?, sortDoc: Document?) = - ReactivePanacheQueryImpl(collection, query, sortDoc) - - /** - * Creates the update implementation - * - * @param collection the collection to query - * @param entityClass the type to update - * @param docUpdate the update document to start with - * - * @return the new query implementation - */ - override fun createUpdate(collection: ReactiveMongoCollection<*>, entityClass: Class<*>, docUpdate: Document) = - ReactivePanacheUpdateImpl(this, entityClass, docUpdate, collection) - - /** - * Extracts the query results in to a List. - * - * @param query the query to list - * - * @return the query results - */ - override fun list(query: ReactivePanacheQuery<*>): Uni> = query.list() as Uni> - - /** - * Extracts the query results in to a Stream. - * - * @param query the query to stream - * - * @return the query results - */ - override fun stream(query: ReactivePanacheQuery<*>): Multi<*> = query.stream() -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/runtime/KotlinMongoOperations.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/runtime/KotlinMongoOperations.kt deleted file mode 100644 index 71c345b34e998..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/main/kotlin/io/quarkus/mongodb/panache/kotlin/runtime/KotlinMongoOperations.kt +++ /dev/null @@ -1,57 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin.runtime - -import com.mongodb.client.MongoCollection -import io.quarkus.mongodb.panache.PanacheUpdate -import io.quarkus.mongodb.panache.kotlin.PanacheQuery -import io.quarkus.mongodb.panache.runtime.MongoOperations -import io.quarkus.mongodb.panache.runtime.PanacheUpdateImpl -import org.bson.Document -import java.util.stream.Stream - -/** - * Defines kotlin specific implementations of methods needed by [MongoOperations]. - */ -class KotlinMongoOperations : MongoOperations, PanacheUpdate>() { - - /** - * Creates the query implementation - * - * @param collection the collection to query - * @param query the query to base the new query off of - * @param sortDoc the sort document to use - * - * @return the new query implementation - */ - override fun createQuery(collection: MongoCollection<*>, query: Document?, sortDoc: Document?) = - PanacheQueryImpl(collection, query, sortDoc) - - /** - * Creates the update implementation - * - * @param collection the collection to query - * @param entityClass the type to update - * @param docUpdate the update document to start with - * - * @return the new query implementation - */ - override fun createUpdate(collection: MongoCollection<*>, entityClass: Class<*>, docUpdate: Document) = - PanacheUpdateImpl(this, entityClass, docUpdate, collection) - - /** - * Extracts the query results in to a List. - * - * @param query the query to list - * - * @return a [List] of the results - */ - override fun list(query: PanacheQuery<*>): List<*> = query.list() - - /** - * Extracts the query results in to a Stream. - * - * @param query the query to stream - * - * @return a [Stream] of the results - */ - override fun stream(query: PanacheQuery<*>): Stream<*> = query.stream() -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache-kotlin/runtime/src/test/kotlin/io/quarkus/mongodb/panache/kotlin/TestAnalogs.kt b/extensions/panache/mongodb-panache-kotlin/runtime/src/test/kotlin/io/quarkus/mongodb/panache/kotlin/TestAnalogs.kt deleted file mode 100644 index abc3c44cf15f6..0000000000000 --- a/extensions/panache/mongodb-panache-kotlin/runtime/src/test/kotlin/io/quarkus/mongodb/panache/kotlin/TestAnalogs.kt +++ /dev/null @@ -1,224 +0,0 @@ -package io.quarkus.mongodb.panache.kotlin - -import io.quarkus.gizmo.Gizmo -import io.quarkus.mongodb.panache.deployment.ByteCodeType -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoCompanionBase -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoEntityBase -import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepository -import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepositoryBase -import io.quarkus.mongodb.panache.reactive.ReactivePanacheQuery -import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.api.Test -import org.objectweb.asm.ClassReader -import org.objectweb.asm.ClassReader.SKIP_CODE -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.MethodVisitor -import org.objectweb.asm.Opcodes -import org.objectweb.asm.Type -import org.objectweb.asm.Type.getArgumentTypes -import org.objectweb.asm.Type.getReturnType -import org.objectweb.asm.Type.getType -import java.util.Optional -import java.util.function.Consumer -import kotlin.reflect.KClass -import io.quarkus.mongodb.panache.PanacheMongoEntity as JavaPanacheMongoEntity -import io.quarkus.mongodb.panache.PanacheMongoEntityBase as JavaPanacheMongoEntityBase -import io.quarkus.mongodb.panache.PanacheMongoRepository as JavaPanacheMongoRepository -import io.quarkus.mongodb.panache.PanacheMongoRepositoryBase as JavaPanacheMongoRepositoryBase -import io.quarkus.mongodb.panache.PanacheQuery as JavaPanacheQuery - -import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoEntity as ReactiveJavaPanacheMongoEntity -import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoEntityBase as ReactiveJavaPanacheMongoEntityBase -import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepository as ReactiveJavaPanacheMongoRepository -import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepositoryBase as ReactiveJavaPanacheMongoRepositoryBase -import io.quarkus.mongodb.panache.reactive.ReactivePanacheQuery as ReactiveJavaPanacheQuery - -class TestAnalogs { - @Test - fun testPanacheQuery() { - compare(map(JavaPanacheQuery::class), map(PanacheQuery::class)) - compare(map(ReactiveJavaPanacheQuery::class), map(ReactivePanacheQuery::class)) - } - - @Test - fun testPanacheRepository() { - compare(map(JavaPanacheMongoRepository::class), map(PanacheMongoRepository::class)) - compare(map(ReactiveJavaPanacheMongoRepository::class), map(ReactivePanacheMongoRepository::class)) - } - - @Test - fun testPanacheRepositoryBase() { - compare(map(JavaPanacheMongoRepositoryBase::class), map(PanacheMongoRepositoryBase::class), listOf("findByIdOptional")) - compare(map(ReactiveJavaPanacheMongoRepositoryBase::class), map(ReactivePanacheMongoRepositoryBase::class), listOf("findByIdOptional")) - } - - @Test - fun testPanacheEntity() { - compare(JavaPanacheMongoEntity::class, PanacheMongoEntity::class, PanacheMongoCompanion::class) - compare(JavaPanacheMongoEntityBase::class, PanacheMongoEntityBase::class, PanacheMongoCompanionBase::class) - compare(ReactiveJavaPanacheMongoEntity::class, PanacheMongoEntity::class, PanacheMongoCompanion::class) - compare(ReactiveJavaPanacheMongoEntityBase::class, ReactivePanacheMongoEntityBase::class, ReactivePanacheMongoCompanionBase::class) - } - - private fun compare(javaEntity: KClass<*>, - kotlinEntity: KClass<*>, - companion: KClass<*>) { - val javaMethods = map(javaEntity).methods - val kotlinMethods = map(kotlinEntity).methods - .filterNot { - it.name.contains("getId") - || it.name.contains("setId") - || it.name.contains("getOperations") - } - .toMutableList() - val companionMethods = map(companion).methods - val implemented = mutableListOf() - - javaMethods - .forEach { - if (!it.isStatic()) { - if (it in kotlinMethods) { - kotlinMethods -= it - implemented += it - } - } else { - if (it in companionMethods) { - companionMethods -= it - implemented += it - } - } - } - javaMethods.removeIf { - it.name == "findByIdOptional" || - it in implemented - } - - methods("javaMethods", javaMethods) - methods("kotlinMethods", kotlinMethods) - methods("companionMethods", companionMethods) - - assertTrue(javaMethods.isEmpty(), "New methods not implemented: ${javaMethods}") - assertTrue(kotlinMethods.isEmpty(), "Old methods not removed: ${kotlinMethods}") - assertTrue(companionMethods.isEmpty(), "Old methods not removed: ${companionMethods}") - } - - private fun map(type: KClass<*>): AnalogVisitor { - return AnalogVisitor().also { node -> - ClassReader(type.bytes()).accept(node, SKIP_CODE) - } - } - - - private fun KClass<*>.bytes() = - java.classLoader.getResourceAsStream(qualifiedName.toString().replace(".", "/") + ".class") - - private fun compare(javaClass: AnalogVisitor, kotlinClass: AnalogVisitor, whiteList: List = listOf()) { - val javaMethods = javaClass.methods - val kotlinMethods = kotlinClass.methods - val implemented = mutableListOf() - - javaMethods - .forEach { - if (it in kotlinMethods) { - kotlinMethods -= it - implemented += it - } - } - - javaMethods.removeIf { - it.name in whiteList || - it in implemented - } - - assertTrue(javaMethods.isEmpty(), "New methods not implemented: ${javaMethods}") - assertTrue(kotlinMethods.isEmpty(), "Old methods not removed: ${kotlinMethods}") - } - - @Suppress("unused") - private fun methods(label: String, methods: List) { - if (methods.isNotEmpty()) { - println("$label: ") - methods - .forEach { - println(it) - } - println() - } - } -} - -class AnalogVisitor : ClassVisitor(Gizmo.ASM_API_VERSION) { - val erasures = mapOf( - getType(PanacheMongoEntityBase::class.java).descriptor to getType(Object::class.java).descriptor, - getType(ReactivePanacheMongoEntityBase::class.java).descriptor to getType(Object::class.java).descriptor - ) - - val methods = mutableListOf() - override fun visitMethod(access: Int, name: String, descriptor: String, signature: String?, - exceptions: Array?): MethodVisitor? { - if (name != "" && name != "" && !descriptor.endsWith(ByteCodeType(Optional::class.java).descriptor())) { - val method = Method(access, name, erase(getReturnType(descriptor)), erase(getArgumentTypes(descriptor))) - methods += method - } - return super.visitMethod(access, name, descriptor, signature, exceptions) - } - - private fun erase(type: Type): String { - var value = type.descriptor - erasures.entries.forEach(Consumer { - value = value.replace(it.key, it.value) - }) - return value - } - - private fun erase(types: Array): List = types.map { erase(it) } -} - -class Method(val access: Int, val name: String, val type: String, val parameters: List) { - fun isStatic() = access.matches(Opcodes.ACC_STATIC) - - override fun toString(): String { - return (if (isStatic()) "static " else "") + "fun ${name}(${parameters.joinToString(", ")})" + - (if (type != Unit::class.qualifiedName) ": $type" else "") - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is Method) return false - - if (name != other.name) return false - if (parameters != other.parameters) return false - - return true - } - - override fun hashCode(): Int { - var result = name.hashCode() - result = 31 * result + type.hashCode() - result = 31 * result + parameters.hashCode() - return result - } - -} - -fun Int.matches(mask: Int) = (this and mask) == mask - -fun Int.accDecode(): List { - val decode: MutableList = ArrayList() - val values: MutableMap = LinkedHashMap() - try { - for (f in Opcodes::class.java.declaredFields) { - if (f.name.startsWith("ACC_")) { - values[f.name] = f.getInt(Opcodes::class.java) - } - } - } catch (e: IllegalAccessException) { - throw RuntimeException(e.message, e) - } - for ((key, value) in values) { - if (this.matches(value)) { - decode.add(key) - } - } - return decode -} \ No newline at end of file diff --git a/extensions/panache/mongodb-panache/deployment/pom.xml b/extensions/panache/mongodb-panache/deployment/pom.xml index b6d8093f7286c..00d4134365b65 100644 --- a/extensions/panache/mongodb-panache/deployment/pom.xml +++ b/extensions/panache/mongodb-panache/deployment/pom.xml @@ -16,7 +16,7 @@ io.quarkus - quarkus-mongodb-panache-common-deployment + quarkus-core-deployment io.quarkus diff --git a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ImperativeTypeBundle.java b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ImperativeTypeBundle.java deleted file mode 100644 index 9de8c13a00216..0000000000000 --- a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ImperativeTypeBundle.java +++ /dev/null @@ -1,61 +0,0 @@ -package io.quarkus.mongodb.panache.deployment; - -import io.quarkus.mongodb.panache.PanacheMongoEntity; -import io.quarkus.mongodb.panache.PanacheMongoEntityBase; -import io.quarkus.mongodb.panache.PanacheMongoRepository; -import io.quarkus.mongodb.panache.PanacheMongoRepositoryBase; -import io.quarkus.mongodb.panache.PanacheQuery; -import io.quarkus.mongodb.panache.PanacheUpdate; -import io.quarkus.mongodb.panache.runtime.MongoOperations; - -public class ImperativeTypeBundle implements TypeBundle { - @Override - public ByteCodeType entity() { - return new ByteCodeType(PanacheMongoEntity.class); - } - - @Override - public ByteCodeType entityBase() { - return new ByteCodeType(PanacheMongoEntityBase.class); - } - - @Override - public ByteCodeType entityBaseCompanion() { - throw new UnsupportedOperationException("Companions are not supported in Java."); - } - - @Override - public ByteCodeType entityCompanion() { - throw new UnsupportedOperationException("Companions are not supported in Java."); - } - - @Override - public ByteCodeType entityCompanionBase() { - throw new UnsupportedOperationException("Companions are not supported in Java."); - } - - @Override - public ByteCodeType operations() { - return new ByteCodeType(MongoOperations.class); - } - - @Override - public ByteCodeType queryType() { - return new ByteCodeType(PanacheQuery.class); - } - - @Override - public ByteCodeType repository() { - return new ByteCodeType(PanacheMongoRepository.class); - } - - @Override - public ByteCodeType repositoryBase() { - return new ByteCodeType(PanacheMongoRepositoryBase.class); - } - - @Override - public ByteCodeType updateType() { - return new ByteCodeType(PanacheUpdate.class); - } -} diff --git a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoEntityClassBuildItem.java b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoEntityClassBuildItem.java similarity index 100% rename from extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoEntityClassBuildItem.java rename to extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoEntityClassBuildItem.java diff --git a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoEntityEnhancer.java b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoEntityEnhancer.java index 37f4c83ab31e8..78cf0614bea9d 100644 --- a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoEntityEnhancer.java +++ b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoEntityEnhancer.java @@ -1,18 +1,21 @@ package io.quarkus.mongodb.panache.deployment; -import static io.quarkus.mongodb.panache.deployment.BasePanacheMongoResourceProcessor.BSON_IGNORE; - import java.lang.reflect.Modifier; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import org.bson.codecs.pojo.annotations.BsonIgnore; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.FieldInfo; import org.jboss.jandex.IndexView; import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; import io.quarkus.gizmo.DescriptorUtils; -import io.quarkus.mongodb.panache.deployment.visitors.PanacheMongoEntityClassVisitor; +import io.quarkus.mongodb.panache.runtime.MongoOperations; import io.quarkus.panache.common.deployment.EntityField; import io.quarkus.panache.common.deployment.EntityModel; import io.quarkus.panache.common.deployment.MetamodelInfo; @@ -20,30 +23,63 @@ import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; public class PanacheMongoEntityEnhancer extends PanacheEntityEnhancer>> { + public final static String MONGO_OPERATIONS_NAME = MongoOperations.class.getName(); + public final static String MONGO_OPERATIONS_BINARY_NAME = MONGO_OPERATIONS_NAME.replace('.', '/'); + + private static final DotName DOTNAME_BSON_IGNORE = DotName.createSimple(BsonIgnore.class.getName()); - private final TypeBundle typeBundle; + final Map entities = new HashMap<>(); - public PanacheMongoEntityEnhancer(IndexView index, List methodCustomizers, - TypeBundle typeBundle) { - super(index, methodCustomizers); - this.typeBundle = typeBundle; + public PanacheMongoEntityEnhancer(IndexView index, List methodCustomizers) { + super(index, PanacheMongoResourceProcessor.DOTNAME_PANACHE_ENTITY_BASE, methodCustomizers); modelInfo = new MetamodelInfo<>(); } @Override public ClassVisitor apply(String className, ClassVisitor outputClassVisitor) { - return new PanacheMongoEntityClassVisitor(className, outputClassVisitor, modelInfo, - indexView.getClassByName(typeBundle.entityBase().dotName()), - indexView.getClassByName(DotName.createSimple(className)), methodCustomizers, - typeBundle); + return new PanacheMongoEntityClassVisitor(className, outputClassVisitor, modelInfo, panacheEntityBaseClassInfo, + indexView.getClassByName(DotName.createSimple(className)), methodCustomizers); + } + + static class PanacheMongoEntityClassVisitor extends PanacheEntityClassVisitor { + + public PanacheMongoEntityClassVisitor(String className, ClassVisitor outputClassVisitor, + MetamodelInfo> modelInfo, ClassInfo panacheEntityBaseClassInfo, + ClassInfo entityInfo, List methodCustomizers) { + super(className, outputClassVisitor, modelInfo, panacheEntityBaseClassInfo, entityInfo, methodCustomizers); + } + + @Override + protected void injectModel(MethodVisitor mv) { + mv.visitLdcInsn(thisClass); + } + + @Override + protected String getModelDescriptor() { + return "Ljava/lang/Class;"; + } + + @Override + protected String getPanacheOperationsBinaryName() { + return MONGO_OPERATIONS_BINARY_NAME; + } + + @Override + protected void generateAccessorSetField(MethodVisitor mv, EntityField field) { + mv.visitFieldInsn(Opcodes.PUTFIELD, thisClass.getInternalName(), field.name, field.descriptor); + } + + @Override + protected void generateAccessorGetField(MethodVisitor mv, EntityField field) { + mv.visitFieldInsn(Opcodes.GETFIELD, thisClass.getInternalName(), field.name, field.descriptor); + } } - @Override public void collectFields(ClassInfo classInfo) { EntityModel entityModel = new EntityModel<>(classInfo); for (FieldInfo fieldInfo : classInfo.fields()) { String name = fieldInfo.name(); - if (Modifier.isPublic(fieldInfo.flags()) && !fieldInfo.hasAnnotation(BSON_IGNORE)) { + if (Modifier.isPublic(fieldInfo.flags()) && !fieldInfo.hasAnnotation(DOTNAME_BSON_IGNORE)) { entityModel.addField(new EntityField(name, DescriptorUtils.typeToString(fieldInfo.type()))); } } diff --git a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoRepositoryEnhancer.java b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoRepositoryEnhancer.java index 7ca22195bf3af..3bb6919d4c618 100644 --- a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoRepositoryEnhancer.java +++ b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoRepositoryEnhancer.java @@ -1,23 +1,61 @@ package io.quarkus.mongodb.panache.deployment; +import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.DotName; import org.jboss.jandex.IndexView; import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; -import io.quarkus.mongodb.panache.deployment.visitors.PanacheMongoRepositoryClassVisitor; +import io.quarkus.mongodb.panache.PanacheMongoRepository; +import io.quarkus.mongodb.panache.PanacheMongoRepositoryBase; import io.quarkus.panache.common.deployment.PanacheRepositoryEnhancer; public class PanacheMongoRepositoryEnhancer extends PanacheRepositoryEnhancer { - private final TypeBundle typeBundle; + public final static DotName PANACHE_REPOSITORY_BASE_NAME = DotName.createSimple(PanacheMongoRepositoryBase.class.getName()); - public PanacheMongoRepositoryEnhancer(IndexView index, TypeBundle typeBundle) { - super(index, typeBundle.repositoryBase().dotName()); - this.typeBundle = typeBundle; + public final static DotName PANACHE_REPOSITORY_NAME = DotName.createSimple(PanacheMongoRepository.class.getName()); + + public PanacheMongoRepositoryEnhancer(IndexView index) { + super(index, PanacheMongoResourceProcessor.DOTNAME_PANACHE_REPOSITORY_BASE); } @Override public ClassVisitor apply(String className, ClassVisitor outputClassVisitor) { - return new PanacheMongoRepositoryClassVisitor(className, outputClassVisitor, - this.indexView, typeBundle); + return new PanacheMongoRepositoryClassVisitor(className, outputClassVisitor, panacheRepositoryBaseClassInfo, + this.indexView); } + static class PanacheMongoRepositoryClassVisitor extends PanacheRepositoryClassVisitor { + + public PanacheMongoRepositoryClassVisitor(String className, ClassVisitor outputClassVisitor, + ClassInfo panacheRepositoryBaseClassInfo, IndexView indexView) { + super(className, outputClassVisitor, panacheRepositoryBaseClassInfo, indexView); + } + + @Override + protected DotName getPanacheRepositoryDotName() { + return PANACHE_REPOSITORY_NAME; + } + + @Override + protected DotName getPanacheRepositoryBaseDotName() { + return PANACHE_REPOSITORY_BASE_NAME; + } + + @Override + protected String getPanacheOperationsBinaryName() { + return PanacheMongoEntityEnhancer.MONGO_OPERATIONS_BINARY_NAME; + } + + @Override + protected void injectModel(MethodVisitor mv) { + // inject Class + mv.visitLdcInsn(entityType); + } + + @Override + protected String getModelDescriptor() { + return "Ljava/lang/Class;"; + } + } } diff --git a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoResourceProcessor.java b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoResourceProcessor.java index 0ec2566b51181..ef59d5ded6f82 100644 --- a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoResourceProcessor.java +++ b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PanacheMongoResourceProcessor.java @@ -1,58 +1,464 @@ package io.quarkus.mongodb.panache.deployment; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import org.bson.codecs.pojo.annotations.BsonId; +import org.bson.codecs.pojo.annotations.BsonProperty; +import org.bson.types.ObjectId; +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationValue; +import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.DotName; +import org.jboss.jandex.FieldInfo; +import org.jboss.jandex.IndexView; +import org.jboss.jandex.MethodInfo; +import org.jboss.jandex.Type; + +import io.quarkus.arc.deployment.ValidationPhaseBuildItem; +import io.quarkus.bootstrap.classloading.ClassPathElement; +import io.quarkus.bootstrap.classloading.QuarkusClassLoader; +import io.quarkus.builder.BuildException; import io.quarkus.deployment.Capability; import io.quarkus.deployment.Feature; +import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.annotations.ExecutionTime; +import io.quarkus.deployment.annotations.Record; +import io.quarkus.deployment.bean.JavaBeanUtil; +import io.quarkus.deployment.builditem.AdditionalIndexedClassesBuildItem; +import io.quarkus.deployment.builditem.ApplicationArchivesBuildItem; +import io.quarkus.deployment.builditem.ApplicationIndexBuildItem; +import io.quarkus.deployment.builditem.BytecodeTransformerBuildItem; import io.quarkus.deployment.builditem.CapabilityBuildItem; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; import io.quarkus.deployment.builditem.FeatureBuildItem; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; +import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; +import io.quarkus.deployment.builditem.nativeimage.ReflectiveHierarchyBuildItem; +import io.quarkus.deployment.util.JandexUtil; +import io.quarkus.jackson.spi.JacksonModuleBuildItem; +import io.quarkus.jsonb.spi.JsonbDeserializerBuildItem; +import io.quarkus.jsonb.spi.JsonbSerializerBuildItem; +import io.quarkus.mongodb.deployment.MongoClientNameBuildItem; +import io.quarkus.mongodb.deployment.MongoUnremovableClientsBuildItem; +import io.quarkus.mongodb.panache.MongoEntity; +import io.quarkus.mongodb.panache.PanacheMongoEntity; +import io.quarkus.mongodb.panache.PanacheMongoEntityBase; +import io.quarkus.mongodb.panache.PanacheMongoRecorder; +import io.quarkus.mongodb.panache.PanacheMongoRepository; +import io.quarkus.mongodb.panache.PanacheMongoRepositoryBase; +import io.quarkus.mongodb.panache.ProjectionFor; +import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoEntity; +import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoEntityBase; +import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepository; +import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepositoryBase; +import io.quarkus.panache.common.deployment.PanacheEntityClassesBuildItem; +import io.quarkus.panache.common.deployment.PanacheFieldAccessEnhancer; import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; +import io.quarkus.panache.common.deployment.PanacheMethodCustomizerBuildItem; import io.quarkus.panache.common.deployment.PanacheRepositoryEnhancer; -public class PanacheMongoResourceProcessor extends BasePanacheMongoResourceProcessor { - public static final ImperativeTypeBundle IMPERATIVE_TYPE_BUNDLE = new ImperativeTypeBundle(); - public static final ReactiveTypeBundle REACTIVE_TYPE_BUNDLE = new ReactiveTypeBundle(); +public class PanacheMongoResourceProcessor { + // blocking types + static final DotName DOTNAME_PANACHE_REPOSITORY_BASE = DotName.createSimple(PanacheMongoRepositoryBase.class.getName()); + private static final DotName DOTNAME_PANACHE_REPOSITORY = DotName.createSimple(PanacheMongoRepository.class.getName()); + static final DotName DOTNAME_PANACHE_ENTITY_BASE = DotName.createSimple(PanacheMongoEntityBase.class.getName()); + private static final DotName DOTNAME_PANACHE_ENTITY = DotName.createSimple(PanacheMongoEntity.class.getName()); + + private static final DotName DOTNAME_PROJECTION_FOR = DotName.createSimple(ProjectionFor.class.getName()); + private static final DotName DOTNAME_BSON_PROPERTY = DotName.createSimple(BsonProperty.class.getName()); + private static final DotName DOTNAME_BSON_ID = DotName.createSimple(BsonId.class.getName()); + + private static final DotName DOTNAME_MONGO_ENTITY = DotName.createSimple(MongoEntity.class.getName()); + + // reactive types (Mutiny) + static final DotName DOTNAME_MUTINY_PANACHE_REPOSITORY_BASE = DotName + .createSimple(ReactivePanacheMongoRepositoryBase.class.getName()); + private static final DotName DOTNAME_MUTINY_PANACHE_REPOSITORY = DotName + .createSimple(ReactivePanacheMongoRepository.class.getName()); + static final DotName DOTNAME_MUTINY_PANACHE_ENTITY_BASE = DotName + .createSimple(ReactivePanacheMongoEntityBase.class.getName()); + private static final DotName DOTNAME_MUTINY_PANACHE_ENTITY = DotName + .createSimple(ReactivePanacheMongoEntity.class.getName()); - protected ReactiveTypeBundle getReactiveTypeBundle() { - return REACTIVE_TYPE_BUNDLE; + private static final DotName DOTNAME_OBJECT_ID = DotName.createSimple(ObjectId.class.getName()); + protected static final String META_INF_PANACHE_ARCHIVE_MARKER = "META-INF/panache-archive.marker"; + + @BuildStep + CapabilityBuildItem capability() { + return new CapabilityBuildItem(Capability.MONGODB_PANACHE); } - protected ImperativeTypeBundle getImperativeTypeBundle() { - return IMPERATIVE_TYPE_BUNDLE; + @BuildStep + FeatureBuildItem featureBuildItem() { + return new FeatureBuildItem(Feature.MONGODB_PANACHE); } - @Override - public PanacheMongoEntityEnhancer createEntityEnhancer(CombinedIndexBuildItem index, - List methodCustomizers) { - return new PanacheMongoEntityEnhancer(index.getIndex(), methodCustomizers, getImperativeTypeBundle()); + @BuildStep + void contributeClassesToIndex(BuildProducer additionalIndexedClasses) { + additionalIndexedClasses.produce(new AdditionalIndexedClassesBuildItem( + DOTNAME_OBJECT_ID.toString())); } - @Override - public PanacheEntityEnhancer createReactiveEntityEnhancer(CombinedIndexBuildItem index, - List methodCustomizers) { - return new PanacheMongoEntityEnhancer(index.getIndex(), methodCustomizers, getReactiveTypeBundle()); + @BuildStep + void registerJsonbSerDeser(BuildProducer jsonbSerializers, + BuildProducer jsonbDeserializers) { + jsonbSerializers + .produce(new JsonbSerializerBuildItem(io.quarkus.mongodb.panache.jsonb.ObjectIdSerializer.class.getName())); + jsonbDeserializers + .produce(new JsonbDeserializerBuildItem(io.quarkus.mongodb.panache.jsonb.ObjectIdDeserializer.class.getName())); } - @Override - public PanacheMongoRepositoryEnhancer createReactiveRepositoryEnhancer(CombinedIndexBuildItem index) { - return new PanacheMongoRepositoryEnhancer(index.getIndex(), getReactiveTypeBundle()); + @BuildStep + void registerJacksonSerDeser(BuildProducer customSerDeser) { + customSerDeser.produce( + new JacksonModuleBuildItem.Builder("ObjectIdModule") + .add(io.quarkus.mongodb.panache.jackson.ObjectIdSerializer.class.getName(), + io.quarkus.mongodb.panache.jackson.ObjectIdDeserializer.class.getName(), + ObjectId.class.getName()) + .build()); } - @Override - public PanacheRepositoryEnhancer createRepositoryEnhancer(CombinedIndexBuildItem index) { - return new PanacheMongoRepositoryEnhancer(index.getIndex(), getImperativeTypeBundle()); + @BuildStep + ReflectiveHierarchyBuildItem registerForReflection(CombinedIndexBuildItem index) { + Type type = Type.create(DOTNAME_OBJECT_ID, Type.Kind.CLASS); + return new ReflectiveHierarchyBuildItem(type, index.getIndex()); } @BuildStep - protected CapabilityBuildItem capability() { - return new CapabilityBuildItem(Capability.MONGODB_PANACHE); + void unremoveableClients(BuildProducer unremovable) { + unremovable.produce(new MongoUnremovableClientsBuildItem()); } @BuildStep - protected FeatureBuildItem featureBuildItem() { - return new FeatureBuildItem(Feature.MONGODB_PANACHE); + public void mongoClientNames(ApplicationArchivesBuildItem applicationArchivesBuildItem, + BuildProducer mongoClientName) { + Set values = new HashSet<>(); + IndexView indexView = applicationArchivesBuildItem.getRootArchive().getIndex(); + Collection instances = indexView.getAnnotations(DOTNAME_MONGO_ENTITY); + for (AnnotationInstance annotation : instances) { + AnnotationValue clientName = annotation.value("clientName"); + if ((clientName != null) && !clientName.asString().isEmpty()) { + values.add(clientName.asString()); + } + } + for (String value : values) { + // we don't want the qualifier @MongoClientName qualifier added + // as these clients will only be looked up programmatically via name + // see MongoOperations#mongoClient + mongoClientName.produce(new MongoClientNameBuildItem(value, false)); + } } + + @BuildStep + void collectEntityClasses(CombinedIndexBuildItem index, BuildProducer entityClasses) { + // NOTE: we don't skip abstract/generic entities because they still need accessors + for (ClassInfo panacheEntityBaseSubclass : index.getIndex().getAllKnownSubclasses(DOTNAME_PANACHE_ENTITY_BASE)) { + // FIXME: should we really skip PanacheEntity or all MappedSuperClass? + if (!panacheEntityBaseSubclass.name().equals(DOTNAME_PANACHE_ENTITY)) { + entityClasses.produce(new PanacheMongoEntityClassBuildItem(panacheEntityBaseSubclass)); + } + } + } + + @BuildStep + PanacheEntityClassesBuildItem findEntityClasses(List entityClasses) { + if (!entityClasses.isEmpty()) { + Set ret = new HashSet<>(); + for (PanacheMongoEntityClassBuildItem entityClass : entityClasses) { + ret.add(entityClass.get().name().toString()); + } + return new PanacheEntityClassesBuildItem(ret); + } + return null; + } + + @BuildStep + void buildImperative(CombinedIndexBuildItem index, + ApplicationIndexBuildItem applicationIndex, + BuildProducer transformers, + BuildProducer reflectiveClass, + BuildProducer propertyMappingClass, + List entityClasses, + List methodCustomizersBuildItems) { + + List methodCustomizers = methodCustomizersBuildItems.stream() + .map(bi -> bi.getMethodCustomizer()).collect(Collectors.toList()); + + PanacheMongoRepositoryEnhancer daoEnhancer = new PanacheMongoRepositoryEnhancer(index.getIndex()); + Set daoClasses = new HashSet<>(); + Set daoTypeParameters = new HashSet<>(); + for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(DOTNAME_PANACHE_REPOSITORY_BASE)) { + // Skip PanacheMongoRepository and abstract repositories + if (classInfo.name().equals(DOTNAME_PANACHE_REPOSITORY) || PanacheRepositoryEnhancer.skipRepository(classInfo)) { + continue; + } + daoClasses.add(classInfo.name().toString()); + daoTypeParameters.addAll( + JandexUtil.resolveTypeParameters(classInfo.name(), DOTNAME_PANACHE_REPOSITORY_BASE, index.getIndex())); + } + for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(DOTNAME_PANACHE_REPOSITORY)) { + if (PanacheRepositoryEnhancer.skipRepository(classInfo)) { + continue; + } + daoClasses.add(classInfo.name().toString()); + daoTypeParameters.addAll( + JandexUtil.resolveTypeParameters(classInfo.name(), DOTNAME_PANACHE_REPOSITORY_BASE, index.getIndex())); + } + for (String daoClass : daoClasses) { + transformers.produce(new BytecodeTransformerBuildItem(daoClass, daoEnhancer)); + } + + for (Type parameterType : daoTypeParameters) { + // Register for reflection the type parameters of the repository: this should be the entity class and the ID class + reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, parameterType.name().toString())); + + // Register for building the property mapping cache + propertyMappingClass.produce(new PropertyMappingClassBuildStep(parameterType.name().toString())); + } + + PanacheMongoEntityEnhancer modelEnhancer = new PanacheMongoEntityEnhancer(index.getIndex(), methodCustomizers); + Set modelClasses = new HashSet<>(); + Set modelClassNamesInternal = new HashSet<>(); + + for (PanacheMongoEntityClassBuildItem entityClass : entityClasses) { + String entityClassName = entityClass.get().name().toString(); + modelClasses.add(entityClassName); + modelEnhancer.collectFields(entityClass.get()); + modelClassNamesInternal.add(entityClassName.replace(".", "/")); + transformers.produce(new BytecodeTransformerBuildItem(entityClassName, modelEnhancer)); + //register for reflection entity classes + reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, entityClassName)); + // Register for building the property mapping cache + propertyMappingClass.produce(new PropertyMappingClassBuildStep(entityClassName)); + } + + if (!modelEnhancer.entities.isEmpty()) { + PanacheFieldAccessEnhancer panacheFieldAccessEnhancer = new PanacheFieldAccessEnhancer( + modelEnhancer.getModelInfo()); + QuarkusClassLoader tccl = (QuarkusClassLoader) Thread.currentThread().getContextClassLoader(); + List archives = tccl.getElementsWithResource(META_INF_PANACHE_ARCHIVE_MARKER); + for (ClassPathElement i : archives) { + for (String res : i.getProvidedResources()) { + if (res.endsWith(".class")) { + String cn = res.replace("/", ".").substring(0, res.length() - 6); + if (!modelClasses.contains(cn)) { + transformers.produce( + new BytecodeTransformerBuildItem(cn, panacheFieldAccessEnhancer, modelClassNamesInternal)); + } + } + } + } + } + } + + @BuildStep + void buildMutiny(CombinedIndexBuildItem index, + ApplicationIndexBuildItem applicationIndex, + BuildProducer reflectiveClass, + BuildProducer propertyMappingClass, + BuildProducer transformers, + List methodCustomizersBuildItems) { + + List methodCustomizers = methodCustomizersBuildItems.stream() + .map(bi -> bi.getMethodCustomizer()).collect(Collectors.toList()); + ReactivePanacheMongoRepositoryEnhancer daoEnhancer = new ReactivePanacheMongoRepositoryEnhancer(index.getIndex()); + Set daoClasses = new HashSet<>(); + Set daoTypeParameters = new HashSet<>(); + for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(DOTNAME_MUTINY_PANACHE_REPOSITORY_BASE)) { + // Skip ReactivePanacheMongoRepository and abstract repositories + if (classInfo.name().equals(DOTNAME_MUTINY_PANACHE_REPOSITORY) + || PanacheRepositoryEnhancer.skipRepository(classInfo)) { + continue; + } + daoClasses.add(classInfo.name().toString()); + daoTypeParameters.addAll( + JandexUtil.resolveTypeParameters(classInfo.name(), DOTNAME_PANACHE_REPOSITORY_BASE, index.getIndex())); + } + for (ClassInfo classInfo : index.getIndex().getAllKnownImplementors(DOTNAME_MUTINY_PANACHE_REPOSITORY)) { + if (PanacheRepositoryEnhancer.skipRepository(classInfo)) { + continue; + } + daoClasses.add(classInfo.name().toString()); + daoTypeParameters.addAll( + JandexUtil.resolveTypeParameters(classInfo.name(), DOTNAME_PANACHE_REPOSITORY_BASE, index.getIndex())); + } + for (String daoClass : daoClasses) { + transformers.produce(new BytecodeTransformerBuildItem(daoClass, daoEnhancer)); + } + + for (Type parameterType : daoTypeParameters) { + // Register for reflection the type parameters of the repository: this should be the entity class and the ID class + reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, parameterType.name().toString())); + + // Register for building the property mapping cache + propertyMappingClass.produce(new PropertyMappingClassBuildStep(parameterType.name().toString())); + } + + ReactivePanacheMongoEntityEnhancer modelEnhancer = new ReactivePanacheMongoEntityEnhancer(index.getIndex(), + methodCustomizers); + Set modelClasses = new HashSet<>(); + // Note that we do this in two passes because for some reason Jandex does not give us subtypes + // of PanacheMongoEntity if we ask for subtypes of PanacheMongoEntityBase + for (ClassInfo classInfo : index.getIndex().getAllKnownSubclasses(DOTNAME_MUTINY_PANACHE_ENTITY_BASE)) { + if (classInfo.name().equals(DOTNAME_MUTINY_PANACHE_ENTITY)) { + continue; + } + if (modelClasses.add(classInfo.name().toString())) + modelEnhancer.collectFields(classInfo); + } + for (ClassInfo classInfo : index.getIndex().getAllKnownSubclasses(DOTNAME_MUTINY_PANACHE_ENTITY)) { + if (modelClasses.add(classInfo.name().toString())) + modelEnhancer.collectFields(classInfo); + } + + // iterate over all the entity classes + for (String modelClass : modelClasses) { + transformers.produce(new BytecodeTransformerBuildItem(modelClass, modelEnhancer)); + + //register for reflection entity classes + reflectiveClass.produce(new ReflectiveClassBuildItem(true, true, modelClass)); + + // Register for building the property mapping cache + propertyMappingClass.produce(new PropertyMappingClassBuildStep(modelClass)); + } + + if (!modelEnhancer.entities.isEmpty()) { + PanacheFieldAccessEnhancer panacheFieldAccessEnhancer = new PanacheFieldAccessEnhancer( + modelEnhancer.getModelInfo()); + for (ClassInfo classInfo : applicationIndex.getIndex().getKnownClasses()) { + String className = classInfo.name().toString(); + if (!modelClasses.contains(className)) { + transformers.produce(new BytecodeTransformerBuildItem(className, panacheFieldAccessEnhancer)); + } + } + } + } + + @BuildStep + ValidationPhaseBuildItem.ValidationErrorBuildItem validate(ValidationPhaseBuildItem validationPhase, + CombinedIndexBuildItem index) throws BuildException { + // we verify that no ID fields are defined (via @BsonId) when extending PanacheMongoEntity or ReactivePanacheMongoEntity + for (AnnotationInstance annotationInstance : index.getIndex().getAnnotations(DOTNAME_BSON_ID)) { + ClassInfo info = JandexUtil.getEnclosingClass(annotationInstance); + if (JandexUtil.isSubclassOf(index.getIndex(), info, + DOTNAME_PANACHE_ENTITY)) { + BuildException be = new BuildException("You provide a MongoDB identifier via @BsonId inside '" + info.name() + + "' but one is already provided by PanacheMongoEntity, " + + "your class should extend PanacheMongoEntityBase instead, or use the id provided by PanacheMongoEntity", + Collections.emptyList()); + return new ValidationPhaseBuildItem.ValidationErrorBuildItem(be); + } else if (JandexUtil.isSubclassOf(index.getIndex(), info, + DOTNAME_MUTINY_PANACHE_ENTITY)) { + BuildException be = new BuildException("You provide a MongoDB identifier via @BsonId inside '" + info.name() + + "' but one is already provided by ReactivePanacheMongoEntity, " + + "your class should extend ReactivePanacheMongoEntityBase instead, or use the id provided by ReactivePanacheMongoEntity", + Collections.emptyList()); + return new ValidationPhaseBuildItem.ValidationErrorBuildItem(be); + } + } + return null; + } + + @BuildStep + void handleProjectionFor(CombinedIndexBuildItem index, + BuildProducer propertyMappingClass, + BuildProducer transformers) { + // manage @BsonProperty for the @ProjectionFor annotation + Map> propertyMapping = new HashMap<>(); + for (AnnotationInstance annotationInstance : index.getIndex().getAnnotations(DOTNAME_PROJECTION_FOR)) { + Type targetClass = annotationInstance.value().asClass(); + ClassInfo target = index.getIndex().getClassByName(targetClass.name()); + Map classPropertyMapping = new HashMap<>(); + extractMappings(classPropertyMapping, target, index); + propertyMapping.put(targetClass.name(), classPropertyMapping); + } + for (AnnotationInstance annotationInstance : index.getIndex().getAnnotations(DOTNAME_PROJECTION_FOR)) { + Type targetClass = annotationInstance.value().asClass(); + Map targetPropertyMapping = propertyMapping.get(targetClass.name()); + if (targetPropertyMapping != null && !targetPropertyMapping.isEmpty()) { + ClassInfo info = annotationInstance.target().asClass(); + ProjectionForEnhancer fieldEnhancer = new ProjectionForEnhancer(targetPropertyMapping); + transformers.produce(new BytecodeTransformerBuildItem(info.name().toString(), fieldEnhancer)); + } + + // Register for building the property mapping cache + propertyMappingClass + .produce(new PropertyMappingClassBuildStep(targetClass.name().toString(), + annotationInstance.target().asClass().name().toString())); + } + } + + private void extractMappings(Map classPropertyMapping, ClassInfo target, CombinedIndexBuildItem index) { + for (FieldInfo fieldInfo : target.fields()) { + if (fieldInfo.hasAnnotation(DOTNAME_BSON_PROPERTY)) { + AnnotationInstance bsonProperty = fieldInfo.annotation(DOTNAME_BSON_PROPERTY); + classPropertyMapping.put(fieldInfo.name(), bsonProperty.value().asString()); + } + } + for (MethodInfo methodInfo : target.methods()) { + if (methodInfo.hasAnnotation(DOTNAME_BSON_PROPERTY)) { + AnnotationInstance bsonProperty = methodInfo.annotation(DOTNAME_BSON_PROPERTY); + classPropertyMapping.put(methodInfo.name(), bsonProperty.value().asString()); + } + } + + // climb up the hierarchy of types + if (!target.superClassType().name().equals(JandexUtil.DOTNAME_OBJECT)) { + Type superType = target.superClassType(); + ClassInfo superClass = index.getIndex().getClassByName(superType.name()); + extractMappings(classPropertyMapping, superClass, index); + } + } + + @BuildStep + @Record(ExecutionTime.STATIC_INIT) + void buildReplacementMap(List propertyMappingClasses, CombinedIndexBuildItem index, + PanacheMongoRecorder recorder) { + Map> replacementMap = new ConcurrentHashMap<>(); + for (PropertyMappingClassBuildStep classToMap : propertyMappingClasses) { + DotName dotName = DotName.createSimple(classToMap.getClassName()); + ClassInfo classInfo = index.getIndex().getClassByName(dotName); + if (classInfo != null) { + // only compute field replacement for types inside the index + Map classReplacementMap = replacementMap.computeIfAbsent(classToMap.getClassName(), + className -> computeReplacement(classInfo)); + if (classToMap.getAliasClassName() != null) { + // also register the replacement map for the projection classes + replacementMap.put(classToMap.getAliasClassName(), classReplacementMap); + } + } + } + + recorder.setReplacementCache(replacementMap); + } + + private Map computeReplacement(ClassInfo classInfo) { + Map replacementMap = new HashMap<>(); + for (FieldInfo field : classInfo.fields()) { + AnnotationInstance bsonProperty = field.annotation(DOTNAME_BSON_PROPERTY); + if (bsonProperty != null) { + replacementMap.put(field.name(), bsonProperty.value().asString()); + } + } + for (MethodInfo method : classInfo.methods()) { + if (method.name().startsWith("get")) { + // we try to replace also for getter + AnnotationInstance bsonProperty = method.annotation(DOTNAME_BSON_PROPERTY); + if (bsonProperty != null) { + String fieldName = JavaBeanUtil.decapitalize(method.name().substring(3)); + replacementMap.put(fieldName, bsonProperty.value().asString()); + } + } + } + return replacementMap.isEmpty() ? Collections.emptyMap() : replacementMap; + } + } diff --git a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ProjectionForEnhancer.java b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ProjectionForEnhancer.java similarity index 100% rename from extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ProjectionForEnhancer.java rename to extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ProjectionForEnhancer.java diff --git a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PropertyMappingClassBuildStep.java b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PropertyMappingClassBuildStep.java similarity index 88% rename from extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PropertyMappingClassBuildStep.java rename to extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PropertyMappingClassBuildStep.java index a3a178f786c80..dd75677c27f79 100644 --- a/extensions/panache/mongodb-panache-common/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PropertyMappingClassBuildStep.java +++ b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/PropertyMappingClassBuildStep.java @@ -2,7 +2,7 @@ import io.quarkus.builder.item.MultiBuildItem; -public final class PropertyMappingClassBuildStep extends MultiBuildItem { +final class PropertyMappingClassBuildStep extends MultiBuildItem { private String className; private String aliasClassName; diff --git a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactivePanacheMongoEntityEnhancer.java b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactivePanacheMongoEntityEnhancer.java new file mode 100644 index 0000000000000..739d898fd5aa7 --- /dev/null +++ b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactivePanacheMongoEntityEnhancer.java @@ -0,0 +1,88 @@ +package io.quarkus.mongodb.panache.deployment; + +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bson.codecs.pojo.annotations.BsonIgnore; +import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.DotName; +import org.jboss.jandex.FieldInfo; +import org.jboss.jandex.IndexView; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import io.quarkus.gizmo.DescriptorUtils; +import io.quarkus.mongodb.panache.reactive.runtime.ReactiveMongoOperations; +import io.quarkus.panache.common.deployment.EntityField; +import io.quarkus.panache.common.deployment.EntityModel; +import io.quarkus.panache.common.deployment.MetamodelInfo; +import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; +import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; + +public class ReactivePanacheMongoEntityEnhancer extends PanacheEntityEnhancer>> { + public final static String MONGO_OPERATIONS_NAME = ReactiveMongoOperations.class.getName(); + public final static String MONGO_OPERATIONS_BINARY_NAME = MONGO_OPERATIONS_NAME.replace('.', '/'); + + private static final DotName DOTNAME_BSON_IGNORE = DotName.createSimple(BsonIgnore.class.getName()); + + final Map entities = new HashMap<>(); + + public ReactivePanacheMongoEntityEnhancer(IndexView index, List methodCustomizers) { + super(index, PanacheMongoResourceProcessor.DOTNAME_MUTINY_PANACHE_ENTITY_BASE, methodCustomizers); + modelInfo = new MetamodelInfo<>(); + } + + @Override + public ClassVisitor apply(String className, ClassVisitor outputClassVisitor) { + return new PanacheMongoEntityClassVisitor(className, outputClassVisitor, modelInfo, panacheEntityBaseClassInfo, + indexView.getClassByName(DotName.createSimple(className)), methodCustomizers); + } + + static class PanacheMongoEntityClassVisitor extends PanacheEntityClassVisitor { + + public PanacheMongoEntityClassVisitor(String className, ClassVisitor outputClassVisitor, + MetamodelInfo> modelInfo, ClassInfo panacheEntityBaseClassInfo, + ClassInfo entityInfo, List methodCustomizers) { + super(className, outputClassVisitor, modelInfo, panacheEntityBaseClassInfo, entityInfo, methodCustomizers); + } + + @Override + protected void injectModel(MethodVisitor mv) { + mv.visitLdcInsn(thisClass); + } + + @Override + protected String getModelDescriptor() { + return "Ljava/lang/Class;"; + } + + @Override + protected String getPanacheOperationsBinaryName() { + return MONGO_OPERATIONS_BINARY_NAME; + } + + @Override + protected void generateAccessorSetField(MethodVisitor mv, EntityField field) { + mv.visitFieldInsn(Opcodes.PUTFIELD, thisClass.getInternalName(), field.name, field.descriptor); + } + + @Override + protected void generateAccessorGetField(MethodVisitor mv, EntityField field) { + mv.visitFieldInsn(Opcodes.GETFIELD, thisClass.getInternalName(), field.name, field.descriptor); + } + } + + public void collectFields(ClassInfo classInfo) { + EntityModel entityModel = new EntityModel<>(classInfo); + for (FieldInfo fieldInfo : classInfo.fields()) { + String name = fieldInfo.name(); + if (Modifier.isPublic(fieldInfo.flags()) && !fieldInfo.hasAnnotation(DOTNAME_BSON_IGNORE)) { + entityModel.addField(new EntityField(name, DescriptorUtils.typeToString(fieldInfo.type()))); + } + } + modelInfo.addEntityModel(entityModel); + } +} diff --git a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactivePanacheMongoRepositoryEnhancer.java b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactivePanacheMongoRepositoryEnhancer.java new file mode 100644 index 0000000000000..4cc24f7903381 --- /dev/null +++ b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactivePanacheMongoRepositoryEnhancer.java @@ -0,0 +1,62 @@ +package io.quarkus.mongodb.panache.deployment; + +import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.DotName; +import org.jboss.jandex.IndexView; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; + +import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepository; +import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepositoryBase; +import io.quarkus.panache.common.deployment.PanacheRepositoryEnhancer; + +public class ReactivePanacheMongoRepositoryEnhancer extends PanacheRepositoryEnhancer { + public final static DotName PANACHE_REPOSITORY_BASE_NAME = DotName + .createSimple(ReactivePanacheMongoRepositoryBase.class.getName()); + + public final static DotName PANACHE_REPOSITORY_NAME = DotName.createSimple(ReactivePanacheMongoRepository.class.getName()); + + public ReactivePanacheMongoRepositoryEnhancer(IndexView index) { + super(index, PanacheMongoResourceProcessor.DOTNAME_MUTINY_PANACHE_REPOSITORY_BASE); + } + + @Override + public ClassVisitor apply(String className, ClassVisitor outputClassVisitor) { + return new PanacheMongoRepositoryClassVisitor(className, outputClassVisitor, panacheRepositoryBaseClassInfo, + this.indexView); + } + + static class PanacheMongoRepositoryClassVisitor extends PanacheRepositoryClassVisitor { + + public PanacheMongoRepositoryClassVisitor(String className, ClassVisitor outputClassVisitor, + ClassInfo panacheRepositoryBaseClassInfo, IndexView indexView) { + super(className, outputClassVisitor, panacheRepositoryBaseClassInfo, indexView); + } + + @Override + protected DotName getPanacheRepositoryDotName() { + return PANACHE_REPOSITORY_NAME; + } + + @Override + protected DotName getPanacheRepositoryBaseDotName() { + return PANACHE_REPOSITORY_BASE_NAME; + } + + @Override + protected String getPanacheOperationsBinaryName() { + return ReactivePanacheMongoEntityEnhancer.MONGO_OPERATIONS_BINARY_NAME; + } + + @Override + protected void injectModel(MethodVisitor mv) { + // inject Class + mv.visitLdcInsn(entityType); + } + + @Override + protected String getModelDescriptor() { + return "Ljava/lang/Class;"; + } + } +} diff --git a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactiveTypeBundle.java b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactiveTypeBundle.java deleted file mode 100644 index bf6b7a32f5746..0000000000000 --- a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/ReactiveTypeBundle.java +++ /dev/null @@ -1,61 +0,0 @@ -package io.quarkus.mongodb.panache.deployment; - -import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoEntity; -import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoEntityBase; -import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepository; -import io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoRepositoryBase; -import io.quarkus.mongodb.panache.reactive.ReactivePanacheQuery; -import io.quarkus.mongodb.panache.reactive.ReactivePanacheUpdate; -import io.quarkus.mongodb.panache.reactive.runtime.ReactiveMongoOperations; - -public class ReactiveTypeBundle implements TypeBundle { - @Override - public ByteCodeType entity() { - return new ByteCodeType(ReactivePanacheMongoEntity.class); - } - - @Override - public ByteCodeType entityBase() { - return new ByteCodeType(ReactivePanacheMongoEntityBase.class); - } - - @Override - public ByteCodeType entityBaseCompanion() { - throw new UnsupportedOperationException("Companions are not supported in Java."); - } - - @Override - public ByteCodeType entityCompanion() { - throw new UnsupportedOperationException("Companions are not supported in Java."); - } - - @Override - public ByteCodeType entityCompanionBase() { - throw new UnsupportedOperationException("Companions are not supported in Java."); - } - - @Override - public ByteCodeType operations() { - return new ByteCodeType(ReactiveMongoOperations.class); - } - - @Override - public ByteCodeType queryType() { - return new ByteCodeType(ReactivePanacheQuery.class); - } - - @Override - public ByteCodeType repository() { - return new ByteCodeType(ReactivePanacheMongoRepository.class); - } - - @Override - public ByteCodeType repositoryBase() { - return new ByteCodeType(ReactivePanacheMongoRepositoryBase.class); - } - - @Override - public ByteCodeType updateType() { - return new ByteCodeType(ReactivePanacheUpdate.class); - } -} diff --git a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/visitors/PanacheMongoRepositoryClassVisitor.java b/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/visitors/PanacheMongoRepositoryClassVisitor.java deleted file mode 100644 index 59892656e0cc1..0000000000000 --- a/extensions/panache/mongodb-panache/deployment/src/main/java/io/quarkus/mongodb/panache/deployment/visitors/PanacheMongoRepositoryClassVisitor.java +++ /dev/null @@ -1,120 +0,0 @@ -package io.quarkus.mongodb.panache.deployment.visitors; - -import static io.quarkus.deployment.util.AsmUtil.getDescriptor; -import static io.quarkus.mongodb.panache.deployment.BasePanacheMongoResourceProcessor.OBJECT_SIGNATURE; -import static java.util.Arrays.asList; -import static org.objectweb.asm.Opcodes.CHECKCAST; -import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; - -import java.util.List; -import java.util.StringJoiner; -import java.util.function.Function; - -import org.jboss.jandex.AnnotationInstance; -import org.jboss.jandex.AnnotationValue; -import org.jboss.jandex.DotName; -import org.jboss.jandex.IndexView; -import org.jboss.jandex.MethodInfo; -import org.jboss.jandex.Type; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; - -import io.quarkus.deployment.util.AsmUtil; -import io.quarkus.mongodb.panache.deployment.ByteCodeType; -import io.quarkus.mongodb.panache.deployment.TypeBundle; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; -import io.quarkus.panache.common.deployment.visitors.PanacheRepositoryClassVisitor; - -public class PanacheMongoRepositoryClassVisitor extends PanacheRepositoryClassVisitor { - private static final ByteCodeType CLASS = new ByteCodeType(Class.class); - - private final TypeBundle typeBundle; - - public PanacheMongoRepositoryClassVisitor(String className, ClassVisitor outputClassVisitor, - IndexView indexView, TypeBundle typeBundle) { - super(className, outputClassVisitor, indexView); - this.typeBundle = typeBundle; - } - - @Override - protected void generateModelBridge(MethodInfo method, AnnotationValue targetReturnTypeErased) { - String descriptor = AsmUtil.getDescriptor(method, name -> typeArguments.get(name)); - // JpaOperations erases the Id type to Object - String descriptorForJpaOperations = AsmUtil.getDescriptor(method, - name -> name.equals("Entity") ? entitySignature : null); - String signature = AsmUtil.getSignature(method, name -> typeArguments.get(name)); - List parameters = method.parameters(); - - // Note: we can't use SYNTHETIC here because otherwise Mockito will never mock these methods - MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC, - method.name(), - descriptor, - signature, - null); - for (int i = 0; i < parameters.size(); i++) { - mv.visitParameter(method.parameterName(i), 0 /* modifiers */); - } - mv.visitFieldInsn(Opcodes.GETSTATIC, daoBinaryName, "operations", - typeBundle.operations().descriptor()); - mv.visitCode(); - injectModel(mv); - for (int i = 0; i < parameters.size(); i++) { - mv.visitIntInsn(Opcodes.ALOAD, i + 1); - } - invokeOperation(mv, method); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private void invokeOperation(MethodVisitor mv, MethodInfo method) { - String operationDescriptor; - Function argMapper = type -> null; - - AnnotationInstance bridge = method.annotation(PanacheEntityEnhancer.DOTNAME_GENERATE_BRIDGE); - AnnotationValue targetReturnTypeErased = bridge.value("targetReturnTypeErased"); - boolean erased = targetReturnTypeErased != null && targetReturnTypeErased.asBoolean(); - - StringJoiner joiner = new StringJoiner("", "(", ")"); - joiner.add(CLASS.descriptor()); - for (Type parameter : method.parameters()) { - joiner.add(getDescriptor(parameter, argMapper)); - } - - List names = asList(typeBundle.queryType().dotName().toString(), - typeBundle.updateType().dotName().toString()); - operationDescriptor = joiner + - (erased || names.contains(method.returnType().name().toString()) - ? OBJECT_SIGNATURE - : getDescriptor(method.returnType(), argMapper)); - - mv.visitMethodInsn(INVOKEVIRTUAL, typeBundle.operations().internalName(), method.name(), - operationDescriptor, false); - if (method.returnType().kind() != Type.Kind.PRIMITIVE) { - Type type = method.returnType(); - String cast; - if (erased) { - cast = entityBinaryType; - } else { - cast = type.name().toString().replace('.', '/'); - } - mv.visitTypeInsn(CHECKCAST, cast); - } - mv.visitInsn(AsmUtil.getReturnInstruction(method.returnType())); - } - - @Override - protected DotName getPanacheRepositoryDotName() { - return typeBundle.repository().dotName(); - } - - @Override - protected DotName getPanacheRepositoryBaseDotName() { - return typeBundle.repositoryBase().dotName(); - } - - @Override - protected String getPanacheOperationsInternalName() { - return typeBundle.operations().internalName(); - } -} diff --git a/extensions/panache/mongodb-panache/runtime/pom.xml b/extensions/panache/mongodb-panache/runtime/pom.xml index 001df22a8dcac..773e2dff4bca3 100644 --- a/extensions/panache/mongodb-panache/runtime/pom.xml +++ b/extensions/panache/mongodb-panache/runtime/pom.xml @@ -24,7 +24,11 @@ io.quarkus - quarkus-mongodb-panache-common + quarkus-mongodb-client + + + io.quarkus + quarkus-panacheql diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/MongoEntity.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/MongoEntity.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/MongoEntity.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/MongoEntity.java diff --git a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoEntityBase.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoEntityBase.java index f9e42ea6c3e2d..b057466896d0d 100755 --- a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoEntityBase.java +++ b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoEntityBase.java @@ -10,7 +10,6 @@ import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; -import io.quarkus.mongodb.panache.runtime.JavaMongoOperations; import io.quarkus.mongodb.panache.runtime.MongoOperations; import io.quarkus.panache.common.Parameters; import io.quarkus.panache.common.Sort; @@ -18,24 +17,26 @@ /** * Represents an entity. If your Mongo entities extend this class they gain auto-generated accessors - * to all their public fields, as well as a lot of useful methods. Unless you have a custom ID strategy, you - * should not extend this class directly but extend {@link PanacheMongoEntity} instead. + * to all their public fields, as well as a lot of useful + * methods. Unless you have a custom ID strategy, you should not extend this class directly but extend + * {@link PanacheMongoEntity} instead. * * @see PanacheMongoEntity */ public abstract class PanacheMongoEntityBase { - protected static final MongoOperations operations = new JavaMongoOperations(); + + // Operations /** * Persist this entity in the database. - * This will set its ID field if not already set. + * This will set it's ID field if not already set. * * @see #persist(Iterable) * @see #persist(Stream) * @see #persist(Object, Object...) */ public void persist() { - operations.persist(this); + MongoOperations.persist(this); } /** @@ -46,7 +47,7 @@ public void persist() { * @see #update(Object, Object...) */ public void update() { - operations.update(this); + MongoOperations.update(this); } /** @@ -57,7 +58,7 @@ public void update() { * @see #persistOrUpdate(Object, Object...) */ public void persistOrUpdate() { - operations.persistOrUpdate(this); + MongoOperations.persistOrUpdate(this); } /** @@ -69,7 +70,7 @@ public void persistOrUpdate() { * @see #deleteAll() */ public void delete() { - operations.delete(this); + MongoOperations.delete(this); } // Queries @@ -82,7 +83,7 @@ public void delete() { */ @GenerateBridge(targetReturnTypeErased = true) public static T findById(Object id) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -93,7 +94,7 @@ public static T findById(Object id) { */ @GenerateBridge public static Optional findByIdOptional(Object id) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -110,7 +111,7 @@ public static Optional findByIdOptional(Ob */ @GenerateBridge public static PanacheQuery find(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -128,7 +129,7 @@ public static PanacheQuery find(String que */ @GenerateBridge public static PanacheQuery find(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -145,7 +146,7 @@ public static PanacheQuery find(String que */ @GenerateBridge public static PanacheQuery find(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -163,7 +164,7 @@ public static PanacheQuery find(String que */ @GenerateBridge public static PanacheQuery find(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -180,7 +181,7 @@ public static PanacheQuery find(String que */ @GenerateBridge public static PanacheQuery find(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -198,7 +199,7 @@ public static PanacheQuery find(String que */ @GenerateBridge public static PanacheQuery find(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -214,7 +215,7 @@ public static PanacheQuery find(String que */ @GenerateBridge public static PanacheQuery find(Document query) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -231,7 +232,7 @@ public static PanacheQuery find(Document q */ @GenerateBridge public static PanacheQuery find(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -244,7 +245,7 @@ public static PanacheQuery find(Document q */ @GenerateBridge public static PanacheQuery findAll() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -258,7 +259,7 @@ public static PanacheQuery findAll() { */ @GenerateBridge public static PanacheQuery findAll(Sort sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -276,7 +277,7 @@ public static PanacheQuery findAll(Sort so */ @GenerateBridge public static List list(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -295,7 +296,7 @@ public static List list(String query, Obje */ @GenerateBridge public static List list(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -313,7 +314,7 @@ public static List list(String query, Sort */ @GenerateBridge public static List list(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -332,7 +333,7 @@ public static List list(String query, Map< */ @GenerateBridge public static List list(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -350,7 +351,7 @@ public static List list(String query, Sort */ @GenerateBridge public static List list(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -369,7 +370,7 @@ public static List list(String query, Para */ @GenerateBridge public static List list(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -386,7 +387,7 @@ public static List list(String query, Sort */ @GenerateBridge public static List list(Document query) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -404,7 +405,7 @@ public static List list(Document query) { */ @GenerateBridge public static List list(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -418,7 +419,7 @@ public static List list(Document query, Do */ @GenerateBridge public static List listAll() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -433,7 +434,7 @@ public static List listAll() { */ @GenerateBridge public static List listAll(Sort sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -451,7 +452,7 @@ public static List listAll(Sort sort) { */ @GenerateBridge public static Stream stream(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -470,7 +471,7 @@ public static Stream stream(String query, */ @GenerateBridge public static Stream stream(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -488,7 +489,7 @@ public static Stream stream(String query, */ @GenerateBridge public static Stream stream(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -507,7 +508,7 @@ public static Stream stream(String query, */ @GenerateBridge public static Stream stream(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -525,7 +526,7 @@ public static Stream stream(String query, */ @GenerateBridge public static Stream stream(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -544,7 +545,7 @@ public static Stream stream(String query, */ @GenerateBridge public static Stream stream(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -561,7 +562,7 @@ public static Stream stream(String query, */ @GenerateBridge public static Stream stream(Document query) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -579,7 +580,7 @@ public static Stream stream(Document query */ @GenerateBridge public static Stream stream(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -593,7 +594,7 @@ public static Stream stream(Document query */ @GenerateBridge public static Stream streamAll() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -608,7 +609,7 @@ public static Stream streamAll() { */ @GenerateBridge public static Stream streamAll(Sort sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -621,7 +622,7 @@ public static Stream streamAll(Sort sort) */ @GenerateBridge public static long count() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -636,7 +637,7 @@ public static long count() { */ @GenerateBridge public static long count(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -651,7 +652,7 @@ public static long count(String query, Object... params) { */ @GenerateBridge public static long count(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -666,7 +667,7 @@ public static long count(String query, Map params) { */ @GenerateBridge public static long count(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -680,7 +681,7 @@ public static long count(String query, Parameters params) { */ @GenerateBridge public static long count(Document query) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -693,7 +694,7 @@ public static long count(Document query) { */ @GenerateBridge public static long deleteAll() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -704,7 +705,7 @@ public static long deleteAll() { */ @GenerateBridge public static boolean deleteById(Object id) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -719,7 +720,7 @@ public static boolean deleteById(Object id) { */ @GenerateBridge public static long delete(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -734,7 +735,7 @@ public static long delete(String query, Object... params) { */ @GenerateBridge public static long delete(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -749,7 +750,7 @@ public static long delete(String query, Map params) { */ @GenerateBridge public static long delete(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -763,7 +764,7 @@ public static long delete(String query, Parameters params) { */ @GenerateBridge public static long delete(Document query) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -775,7 +776,7 @@ public static long delete(Document query) { * @see #persist(Object,Object...) */ public static void persist(Iterable entities) { - operations.persist(entities); + MongoOperations.persist(entities); } /** @@ -787,7 +788,7 @@ public static void persist(Iterable entities) { * @see #persist(Object,Object...) */ public static void persist(Stream entities) { - operations.persist(entities); + MongoOperations.persist(entities); } /** @@ -799,7 +800,7 @@ public static void persist(Stream entities) { * @see #persist(Iterable) */ public static void persist(Object firstEntity, Object... entities) { - operations.persist(firstEntity, entities); + MongoOperations.persist(firstEntity, entities); } /** @@ -811,7 +812,7 @@ public static void persist(Object firstEntity, Object... entities) { * @see #update(Object,Object...) */ public static void update(Iterable entities) { - operations.update(entities); + MongoOperations.update(entities); } /** @@ -823,7 +824,7 @@ public static void update(Iterable entities) { * @see #update(Object,Object...) */ public static void update(Stream entities) { - operations.update(entities); + MongoOperations.update(entities); } /** @@ -835,7 +836,7 @@ public static void update(Stream entities) { * @see #update(Iterable) */ public static void update(Object firstEntity, Object... entities) { - operations.update(firstEntity, entities); + MongoOperations.update(firstEntity, entities); } /** @@ -847,7 +848,7 @@ public static void update(Object firstEntity, Object... entities) { * @see #persistOrUpdate(Object,Object...) */ public static void persistOrUpdate(Iterable entities) { - operations.persistOrUpdate(entities); + MongoOperations.persistOrUpdate(entities); } /** @@ -859,7 +860,7 @@ public static void persistOrUpdate(Iterable entities) { * @see #persistOrUpdate(Object,Object...) */ public static void persistOrUpdate(Stream entities) { - operations.persistOrUpdate(entities); + MongoOperations.persistOrUpdate(entities); } /** @@ -871,7 +872,7 @@ public static void persistOrUpdate(Stream entities) { * @see #persistOrUpdate(Iterable) */ public static void persistOrUpdate(Object firstEntity, Object... entities) { - operations.persistOrUpdate(firstEntity, entities); + MongoOperations.persistOrUpdate(firstEntity, entities); } /** @@ -887,7 +888,7 @@ public static void persistOrUpdate(Object firstEntity, Object... entities) { */ @GenerateBridge public static PanacheUpdate update(String update, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -904,7 +905,7 @@ public static PanacheUpdate update(String update, Object... params) { */ @GenerateBridge public static PanacheUpdate update(String update, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -920,7 +921,7 @@ public static PanacheUpdate update(String update, Map params) { */ @GenerateBridge public static PanacheUpdate update(String update, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -928,7 +929,7 @@ public static PanacheUpdate update(String update, Parameters params) { */ @GenerateBridge public static MongoCollection mongoCollection() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -936,6 +937,6 @@ public static MongoCollection mongoCollect */ @GenerateBridge public static MongoDatabase mongoDatabase() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } } diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoRecorder.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoRecorder.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoRecorder.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoRecorder.java diff --git a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoRepositoryBase.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoRepositoryBase.java index 2465f5f8971a2..7c2f7d1ebe58d 100755 --- a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoRepositoryBase.java +++ b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheMongoRepositoryBase.java @@ -10,7 +10,6 @@ import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; -import io.quarkus.mongodb.panache.runtime.JavaMongoOperations; import io.quarkus.mongodb.panache.runtime.MongoOperations; import io.quarkus.panache.common.Parameters; import io.quarkus.panache.common.Sort; @@ -27,7 +26,8 @@ * @see PanacheMongoRepository */ public interface PanacheMongoRepositoryBase { - MongoOperations operations = new JavaMongoOperations(); + + // Operations /** * Persist the given entity in the database. @@ -39,7 +39,7 @@ public interface PanacheMongoRepositoryBase { * @see #persist(Object, Object...) */ public default void persist(Entity entity) { - operations.persist(entity); + MongoOperations.persist(entity); } /** @@ -51,7 +51,7 @@ public default void persist(Entity entity) { * @see #update(Object, Object...) */ public default void update(Entity entity) { - operations.update(entity); + MongoOperations.update(entity); } /** @@ -63,7 +63,7 @@ public default void update(Entity entity) { * @see #persistOrUpdate(Object, Object...) */ public default void persistOrUpdate(Entity entity) { - operations.persistOrUpdate(entity); + MongoOperations.persistOrUpdate(entity); } /** @@ -76,7 +76,7 @@ public default void persistOrUpdate(Entity entity) { * @see #deleteAll() */ public default void delete(Entity entity) { - operations.delete(entity); + MongoOperations.delete(entity); } // Queries @@ -89,7 +89,7 @@ public default void delete(Entity entity) { */ @GenerateBridge(targetReturnTypeErased = true) public default Entity findById(Id id) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -100,7 +100,7 @@ public default Entity findById(Id id) { */ @GenerateBridge public default Optional findByIdOptional(Id id) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -117,7 +117,7 @@ public default Optional findByIdOptional(Id id) { */ @GenerateBridge public default PanacheQuery find(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -135,7 +135,7 @@ public default PanacheQuery find(String query, Object... params) { */ @GenerateBridge public default PanacheQuery find(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -152,7 +152,7 @@ public default PanacheQuery find(String query, Sort sort, Object... para */ @GenerateBridge public default PanacheQuery find(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -170,7 +170,7 @@ public default PanacheQuery find(String query, Map param */ @GenerateBridge public default PanacheQuery find(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -187,7 +187,7 @@ public default PanacheQuery find(String query, Sort sort, Map find(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -205,7 +205,7 @@ public default PanacheQuery find(String query, Parameters params) { */ @GenerateBridge public default PanacheQuery find(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -221,7 +221,7 @@ public default PanacheQuery find(String query, Sort sort, Parameters par */ @GenerateBridge public default PanacheQuery find(Document query) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -238,7 +238,7 @@ public default PanacheQuery find(Document query) { */ @GenerateBridge public default PanacheQuery find(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -251,7 +251,7 @@ public default PanacheQuery find(Document query, Document sort) { */ @GenerateBridge public default PanacheQuery findAll() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -265,7 +265,7 @@ public default PanacheQuery findAll() { */ @GenerateBridge public default PanacheQuery findAll(Sort sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -283,7 +283,7 @@ public default PanacheQuery findAll(Sort sort) { */ @GenerateBridge public default List list(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -302,7 +302,7 @@ public default List list(String query, Object... params) { */ @GenerateBridge public default List list(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -320,7 +320,7 @@ public default List list(String query, Sort sort, Object... params) { */ @GenerateBridge public default List list(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -339,7 +339,7 @@ public default List list(String query, Map params) { */ @GenerateBridge public default List list(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -357,7 +357,7 @@ public default List list(String query, Sort sort, Map pa */ @GenerateBridge public default List list(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -376,7 +376,7 @@ public default List list(String query, Parameters params) { */ @GenerateBridge public default List list(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -393,7 +393,7 @@ public default List list(String query, Sort sort, Parameters params) { */ @GenerateBridge public default List list(Document query) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -411,7 +411,7 @@ public default List list(Document query) { */ @GenerateBridge public default List list(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -425,7 +425,7 @@ public default List list(Document query, Document sort) { */ @GenerateBridge public default List listAll() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -440,7 +440,7 @@ public default List listAll() { */ @GenerateBridge public default List listAll(Sort sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -458,7 +458,7 @@ public default List listAll(Sort sort) { */ @GenerateBridge public default Stream stream(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -477,7 +477,7 @@ public default Stream stream(String query, Object... params) { */ @GenerateBridge public default Stream stream(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -495,7 +495,7 @@ public default Stream stream(String query, Sort sort, Object... params) */ @GenerateBridge public default Stream stream(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -514,7 +514,7 @@ public default Stream stream(String query, Map params) { */ @GenerateBridge public default Stream stream(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -532,7 +532,7 @@ public default Stream stream(String query, Sort sort, Map stream(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -551,7 +551,7 @@ public default Stream stream(String query, Parameters params) { */ @GenerateBridge public default Stream stream(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -568,7 +568,7 @@ public default Stream stream(String query, Sort sort, Parameters params) */ @GenerateBridge public default Stream stream(Document query) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -586,7 +586,7 @@ public default Stream stream(Document query) { */ @GenerateBridge public default Stream stream(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -600,7 +600,7 @@ public default Stream stream(Document query, Document sort) { */ @GenerateBridge public default Stream streamAll(Sort sort) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -614,7 +614,7 @@ public default Stream streamAll(Sort sort) { */ @GenerateBridge public default Stream streamAll() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -627,7 +627,7 @@ public default Stream streamAll() { */ @GenerateBridge public default long count() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -642,7 +642,7 @@ public default long count() { */ @GenerateBridge public default long count(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -657,7 +657,7 @@ public default long count(String query, Object... params) { */ @GenerateBridge public default long count(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -672,7 +672,7 @@ public default long count(String query, Map params) { */ @GenerateBridge public default long count(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -686,7 +686,7 @@ public default long count(String query, Parameters params) { */ @GenerateBridge public default long count(Document query) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -699,7 +699,7 @@ public default long count(Document query) { */ @GenerateBridge public default long deleteAll() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -710,7 +710,7 @@ public default long deleteAll() { */ @GenerateBridge public default boolean deleteById(Id id) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -725,7 +725,7 @@ public default boolean deleteById(Id id) { */ @GenerateBridge public default long delete(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -740,7 +740,7 @@ public default long delete(String query, Object... params) { */ @GenerateBridge public default long delete(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -755,7 +755,7 @@ public default long delete(String query, Map params) { */ @GenerateBridge public default long delete(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -769,7 +769,7 @@ public default long delete(String query, Parameters params) { */ @GenerateBridge public default long delete(Document query) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -781,7 +781,7 @@ public default long delete(Document query) { * @see #persist(Object,Object...) */ public default void persist(Iterable entities) { - operations.persist(entities); + MongoOperations.persist(entities); } /** @@ -793,7 +793,7 @@ public default void persist(Iterable entities) { * @see #persist(Object,Object...) */ public default void persist(Stream entities) { - operations.persist(entities); + MongoOperations.persist(entities); } /** @@ -804,8 +804,8 @@ public default void persist(Stream entities) { * @see #persist(Stream) * @see #persist(Iterable) */ - public default void persist(Entity firstEntity, Entity... entities) { - operations.persist(firstEntity, entities); + public default void persist(Entity firstEntity, @SuppressWarnings("unchecked") Entity... entities) { + MongoOperations.persist(firstEntity, entities); } /** @@ -817,7 +817,7 @@ public default void persist(Entity firstEntity, Entity... entities) { * @see #update(Object,Object...) */ public default void update(Iterable entities) { - operations.update(entities); + MongoOperations.update(entities); } /** @@ -829,7 +829,7 @@ public default void update(Iterable entities) { * @see #update(Object,Object...) */ public default void update(Stream entities) { - operations.update(entities); + MongoOperations.update(entities); } /** @@ -841,7 +841,7 @@ public default void update(Stream entities) { * @see #update(Iterable) */ public default void update(Entity firstEntity, @SuppressWarnings("unchecked") Entity... entities) { - operations.update(firstEntity, entities); + MongoOperations.update(firstEntity, entities); } /** @@ -853,7 +853,7 @@ public default void update(Entity firstEntity, @SuppressWarnings("unchecked") En * @see #persistOrUpdate(Object,Object...) */ public default void persistOrUpdate(Iterable entities) { - operations.persistOrUpdate(entities); + MongoOperations.persistOrUpdate(entities); } /** @@ -865,7 +865,7 @@ public default void persistOrUpdate(Iterable entities) { * @see #persistOrUpdate(Object,Object...) */ public default void persistOrUpdate(Stream entities) { - operations.persistOrUpdate(entities); + MongoOperations.persistOrUpdate(entities); } /** @@ -877,7 +877,7 @@ public default void persistOrUpdate(Stream entities) { * @see #update(Iterable) */ public default void persistOrUpdate(Entity firstEntity, @SuppressWarnings("unchecked") Entity... entities) { - operations.persistOrUpdate(firstEntity, entities); + MongoOperations.persistOrUpdate(firstEntity, entities); } /** @@ -893,7 +893,7 @@ public default void persistOrUpdate(Entity firstEntity, @SuppressWarnings("unche */ @GenerateBridge public default PanacheUpdate update(String update, Object... params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -910,7 +910,7 @@ public default PanacheUpdate update(String update, Object... params) { */ @GenerateBridge public default PanacheUpdate update(String update, Map params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -926,7 +926,7 @@ public default PanacheUpdate update(String update, Map params) { */ @GenerateBridge public default PanacheUpdate update(String update, Parameters params) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -934,7 +934,7 @@ public default PanacheUpdate update(String update, Parameters params) { */ @GenerateBridge public default MongoCollection mongoCollection() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -942,6 +942,6 @@ public default MongoCollection mongoCollection() { */ @GenerateBridge public default MongoDatabase mongoDatabase() { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } } diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheUpdate.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheUpdate.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheUpdate.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/PanacheUpdate.java diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/ProjectionFor.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/ProjectionFor.java similarity index 92% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/ProjectionFor.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/ProjectionFor.java index 260267b716cb5..6f74d7aab4a48 100644 --- a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/ProjectionFor.java +++ b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/ProjectionFor.java @@ -10,5 +10,5 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ProjectionFor { - Class value(); + public Class value(); } diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/binder/CommonQueryBinder.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/binder/CommonQueryBinder.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/binder/CommonQueryBinder.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/binder/CommonQueryBinder.java diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/binder/MongoParserVisitor.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/binder/MongoParserVisitor.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/binder/MongoParserVisitor.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/binder/MongoParserVisitor.java diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/binder/NativeQueryBinder.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/binder/NativeQueryBinder.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/binder/NativeQueryBinder.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/binder/NativeQueryBinder.java diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/binder/PanacheQlQueryBinder.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/binder/PanacheQlQueryBinder.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/binder/PanacheQlQueryBinder.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/binder/PanacheQlQueryBinder.java diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/jackson/ObjectIdDeserializer.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/jackson/ObjectIdDeserializer.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/jackson/ObjectIdDeserializer.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/jackson/ObjectIdDeserializer.java diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/jackson/ObjectIdSerializer.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/jackson/ObjectIdSerializer.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/jackson/ObjectIdSerializer.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/jackson/ObjectIdSerializer.java diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/jsonb/ObjectIdDeserializer.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/jsonb/ObjectIdDeserializer.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/jsonb/ObjectIdDeserializer.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/jsonb/ObjectIdDeserializer.java diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/jsonb/ObjectIdSerializer.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/jsonb/ObjectIdSerializer.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/jsonb/ObjectIdSerializer.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/jsonb/ObjectIdSerializer.java diff --git a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheMongoEntityBase.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheMongoEntityBase.java index e24eb454403ce..b4f95eecb8101 100644 --- a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheMongoEntityBase.java +++ b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheMongoEntityBase.java @@ -8,8 +8,8 @@ import org.bson.Document; import io.quarkus.mongodb.panache.PanacheUpdate; -import io.quarkus.mongodb.panache.reactive.runtime.JavaReactiveMongoOperations; import io.quarkus.mongodb.panache.reactive.runtime.ReactiveMongoOperations; +import io.quarkus.mongodb.panache.runtime.MongoOperations; import io.quarkus.mongodb.reactive.ReactiveMongoCollection; import io.quarkus.mongodb.reactive.ReactiveMongoDatabase; import io.quarkus.panache.common.Parameters; @@ -26,20 +26,20 @@ * * @see ReactivePanacheMongoEntity */ -@SuppressWarnings({ "rawtypes", "unchecked" }) public abstract class ReactivePanacheMongoEntityBase { - protected static final ReactiveMongoOperations operations = new JavaReactiveMongoOperations(); + + // Operations /** * Persist this entity in the database. - * This will set its ID field if not already set. + * This will set it's ID field if not already set. * * @see #persist(Iterable) * @see #persist(Stream) * @see #persist(Object, Object...) */ public Uni persist() { - return operations.persist(this); + return ReactiveMongoOperations.persist(this); } /** @@ -50,7 +50,7 @@ public Uni persist() { * @see #update(Object, Object...) */ public Uni update() { - return operations.update(this); + return ReactiveMongoOperations.update(this); } /** @@ -61,7 +61,7 @@ public Uni update() { * @see #persistOrUpdate(Object, Object...) */ public Uni persistOrUpdate() { - return operations.persistOrUpdate(this); + return ReactiveMongoOperations.persistOrUpdate(this); } /** @@ -73,7 +73,7 @@ public Uni persistOrUpdate() { * @see #deleteAll() */ public Uni delete() { - return operations.delete(this); + return ReactiveMongoOperations.delete(this); } // Queries @@ -86,7 +86,7 @@ public Uni delete() { */ @GenerateBridge public static Uni findById(Object id) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -97,7 +97,7 @@ public static Uni findById(Object */ @GenerateBridge public static Uni> findByIdOptional(Object id) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -114,7 +114,7 @@ public static Uni> findBy */ @GenerateBridge public static ReactivePanacheQuery find(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -133,7 +133,7 @@ public static ReactivePanacheQuery @GenerateBridge public static ReactivePanacheQuery find(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -151,7 +151,7 @@ public static ReactivePanacheQuery @GenerateBridge public static ReactivePanacheQuery find(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -170,7 +170,7 @@ public static ReactivePanacheQuery @GenerateBridge public static ReactivePanacheQuery find(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -187,7 +187,7 @@ public static ReactivePanacheQuery */ @GenerateBridge public static ReactivePanacheQuery find(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -206,7 +206,7 @@ public static ReactivePanacheQuery @GenerateBridge public static ReactivePanacheQuery find(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -222,7 +222,7 @@ public static ReactivePanacheQuery */ @GenerateBridge public static ReactivePanacheQuery find(Document query) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -239,7 +239,7 @@ public static ReactivePanacheQuery */ @GenerateBridge public static ReactivePanacheQuery find(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -252,7 +252,7 @@ public static ReactivePanacheQuery */ @GenerateBridge public static ReactivePanacheQuery findAll() { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -266,7 +266,7 @@ public static ReactivePanacheQuery */ @GenerateBridge public static ReactivePanacheQuery findAll(Sort sort) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -284,7 +284,7 @@ public static ReactivePanacheQuery */ @GenerateBridge public static Uni> list(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -304,7 +304,7 @@ public static Uni> list(Strin @GenerateBridge public static Uni> list(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -323,7 +323,7 @@ public static Uni> list(Strin @GenerateBridge public static Uni> list(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -343,7 +343,7 @@ public static Uni> list(Strin @GenerateBridge public static Uni> list(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -361,7 +361,7 @@ public static Uni> list(Strin */ @GenerateBridge public static Uni> list(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -381,7 +381,7 @@ public static Uni> list(Strin @GenerateBridge public static Uni> list(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -398,7 +398,7 @@ public static Uni> list(Strin */ @GenerateBridge public static Uni> list(Document query) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -416,7 +416,7 @@ public static Uni> list(Docum */ @GenerateBridge public static Uni> list(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -430,7 +430,7 @@ public static Uni> list(Docum */ @GenerateBridge public static Uni> listAll() { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -445,7 +445,7 @@ public static Uni> listAll() */ @GenerateBridge public static Uni> listAll(Sort sort) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -463,7 +463,7 @@ public static Uni> listAll(So */ @GenerateBridge public static Multi stream(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -482,7 +482,7 @@ public static Multi stream(String */ @GenerateBridge public static Multi stream(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -500,7 +500,7 @@ public static Multi stream(String */ @GenerateBridge public static Multi stream(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -520,7 +520,7 @@ public static Multi stream(String @GenerateBridge public static Multi stream(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -538,7 +538,7 @@ public static Multi stream(String */ @GenerateBridge public static Multi stream(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -557,7 +557,7 @@ public static Multi stream(String */ @GenerateBridge public static Multi stream(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -574,7 +574,7 @@ public static Multi stream(String */ @GenerateBridge public static Multi stream(Document query) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -592,7 +592,7 @@ public static Multi stream(Documen */ @GenerateBridge public static Multi stream(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -606,7 +606,7 @@ public static Multi stream(Documen */ @GenerateBridge public static Multi streamAll() { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -621,7 +621,7 @@ public static Multi streamAll() { */ @GenerateBridge public static Multi streamAll(Sort sort) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -634,7 +634,7 @@ public static Multi streamAll(Sort */ @GenerateBridge public static Uni count() { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -649,7 +649,7 @@ public static Uni count() { */ @GenerateBridge public static Uni count(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -664,7 +664,7 @@ public static Uni count(String query, Object... params) { */ @GenerateBridge public static Uni count(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -679,7 +679,7 @@ public static Uni count(String query, Map params) { */ @GenerateBridge public static Uni count(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -693,7 +693,7 @@ public static Uni count(String query, Parameters params) { */ @GenerateBridge public static Uni count(Document query) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -706,7 +706,7 @@ public static Uni count(Document query) { */ @GenerateBridge public static Uni deleteAll() { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -717,7 +717,7 @@ public static Uni deleteAll() { */ @GenerateBridge public static Uni deleteById(Object id) { - throw operations.implementationInjectionMissing(); + throw MongoOperations.implementationInjectionMissing(); } /** @@ -732,7 +732,7 @@ public static Uni deleteById(Object id) { */ @GenerateBridge public static Uni delete(String query, Object... params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -747,7 +747,7 @@ public static Uni delete(String query, Object... params) { */ @GenerateBridge public static Uni delete(String query, Map params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -762,7 +762,7 @@ public static Uni delete(String query, Map params) { */ @GenerateBridge public static Uni delete(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -776,7 +776,7 @@ public static Uni delete(String query, Parameters params) { */ @GenerateBridge public static Uni delete(Document query) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -788,7 +788,7 @@ public static Uni delete(Document query) { * @see #persist(Object,Object...) */ public static Uni persist(Iterable entities) { - return operations.persist(entities); + return ReactiveMongoOperations.persist(entities); } /** @@ -800,7 +800,7 @@ public static Uni persist(Iterable entities) { * @see #persist(Object,Object...) */ public static Uni persist(Stream entities) { - return operations.persist(entities); + return ReactiveMongoOperations.persist(entities); } /** @@ -812,7 +812,7 @@ public static Uni persist(Stream entities) { * @see #persist(Iterable) */ public static Uni persist(Object firstEntity, Object... entities) { - return operations.persist(firstEntity, entities); + return ReactiveMongoOperations.persist(firstEntity, entities); } /** @@ -824,7 +824,7 @@ public static Uni persist(Object firstEntity, Object... entities) { * @see #update(Object,Object...) */ public static Uni update(Iterable entities) { - return operations.update(entities); + return ReactiveMongoOperations.update(entities); } /** @@ -836,7 +836,7 @@ public static Uni update(Iterable entities) { * @see #update(Object,Object...) */ public static Uni update(Stream entities) { - return operations.update(entities); + return ReactiveMongoOperations.update(entities); } /** @@ -848,7 +848,7 @@ public static Uni update(Stream entities) { * @see #update(Iterable) */ public static Uni update(Object firstEntity, Object... entities) { - return operations.update(firstEntity, entities); + return ReactiveMongoOperations.update(firstEntity, entities); } /** @@ -860,7 +860,7 @@ public static Uni update(Object firstEntity, Object... entities) { * @see #persistOrUpdate(Object,Object...) */ public static Uni persistOrUpdate(Iterable entities) { - return operations.persistOrUpdate(entities); + return ReactiveMongoOperations.persistOrUpdate(entities); } /** @@ -872,7 +872,7 @@ public static Uni persistOrUpdate(Iterable entities) { * @see #persistOrUpdate(Object,Object...) */ public static Uni persistOrUpdate(Stream entities) { - return operations.persistOrUpdate(entities); + return ReactiveMongoOperations.persistOrUpdate(entities); } /** @@ -884,7 +884,7 @@ public static Uni persistOrUpdate(Stream entities) { * @see #persistOrUpdate(Iterable) */ public static Uni persistOrUpdate(Object firstEntity, Object... entities) { - return operations.persistOrUpdate(firstEntity, entities); + return ReactiveMongoOperations.persistOrUpdate(firstEntity, entities); } /** @@ -900,7 +900,7 @@ public static Uni persistOrUpdate(Object firstEntity, Object... entities) */ @GenerateBridge public static ReactivePanacheUpdate update(String update, Object... params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -917,7 +917,7 @@ public static ReactivePanacheUpdate update(String update, Object... params) { */ @GenerateBridge public static ReactivePanacheUpdate update(String update, Map params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -933,7 +933,7 @@ public static ReactivePanacheUpdate update(String update, Map pa */ @GenerateBridge public static ReactivePanacheUpdate update(String update, Parameters params) { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -941,7 +941,7 @@ public static ReactivePanacheUpdate update(String update, Parameters params) { */ @GenerateBridge public static ReactiveMongoCollection mongoCollection() { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -949,6 +949,6 @@ public static ReactiveMongoCollection */ @GenerateBridge public static ReactiveMongoDatabase mongoDatabase() { - throw operations.implementationInjectionMissing(); + throw ReactiveMongoOperations.implementationInjectionMissing(); } } diff --git a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheMongoRepositoryBase.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheMongoRepositoryBase.java index 69cb331218e1c..5f6e3fadafb51 100644 --- a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheMongoRepositoryBase.java +++ b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheMongoRepositoryBase.java @@ -1,7 +1,5 @@ package io.quarkus.mongodb.panache.reactive; -import static io.quarkus.mongodb.panache.reactive.ReactivePanacheMongoEntityBase.operations; - import java.util.List; import java.util.Map; import java.util.Optional; @@ -10,8 +8,8 @@ import org.bson.Document; import io.quarkus.mongodb.panache.PanacheUpdate; -import io.quarkus.mongodb.panache.reactive.runtime.JavaReactiveMongoOperations; import io.quarkus.mongodb.panache.reactive.runtime.ReactiveMongoOperations; +import io.quarkus.mongodb.panache.runtime.MongoOperations; import io.quarkus.mongodb.reactive.ReactiveMongoCollection; import io.quarkus.mongodb.reactive.ReactiveMongoDatabase; import io.quarkus.panache.common.Parameters; @@ -30,9 +28,9 @@ * @param The ID type of the entity * @see ReactivePanacheMongoRepository */ -@SuppressWarnings("unchecked") public interface ReactivePanacheMongoRepositoryBase { - ReactiveMongoOperations operations = new JavaReactiveMongoOperations(); + + // Operations /** * Persist the given entity in the database. @@ -43,8 +41,8 @@ public interface ReactivePanacheMongoRepositoryBase { * @see #persist(Stream) * @see #persist(Object, Object...) */ - default Uni persist(Entity entity) { - return operations.persist(entity); + public default Uni persist(Entity entity) { + return ReactiveMongoOperations.persist(entity); } /** @@ -55,8 +53,8 @@ default Uni persist(Entity entity) { * @see #update(Stream) * @see #update(Object, Object...) */ - default Uni update(Entity entity) { - return operations.update(entity); + public default Uni update(Entity entity) { + return ReactiveMongoOperations.update(entity); } /** @@ -67,8 +65,8 @@ default Uni update(Entity entity) { * @see #persistOrUpdate(Stream) * @see #persistOrUpdate(Object, Object...) */ - default Uni persistOrUpdate(Entity entity) { - return operations.persistOrUpdate(entity); + public default Uni persistOrUpdate(Entity entity) { + return ReactiveMongoOperations.persistOrUpdate(entity); } /** @@ -80,8 +78,8 @@ default Uni persistOrUpdate(Entity entity) { * @see #delete(String, Parameters) * @see #deleteAll() */ - default Uni delete(Entity entity) { - return operations.delete(entity); + public default Uni delete(Entity entity) { + return ReactiveMongoOperations.delete(entity); } // Queries @@ -93,8 +91,8 @@ default Uni delete(Entity entity) { * @return the entity found, or null if not found. */ @GenerateBridge - default Uni findById(Id id) { - throw operations.implementationInjectionMissing(); + public default Uni findById(Id id) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -104,8 +102,8 @@ default Uni findById(Id id) { * @return if found, an optional containing the entity, else Optional.empty(). */ @GenerateBridge - default Uni> findByIdOptional(Object id) { - throw operations.implementationInjectionMissing(); + public default Uni> findByIdOptional(Object id) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -121,8 +119,8 @@ default Uni> findByIdOptional(Object id) { * @see #stream(String, Object...) */ @GenerateBridge - default ReactivePanacheQuery find(String query, Object... params) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheQuery find(String query, Object... params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -139,8 +137,8 @@ default ReactivePanacheQuery find(String query, Object... params) { * @see #stream(String, Sort, Object...) */ @GenerateBridge - default ReactivePanacheQuery find(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheQuery find(String query, Sort sort, Object... params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -156,8 +154,8 @@ default ReactivePanacheQuery find(String query, Sort sort, Object... par * @see #stream(String, Map) */ @GenerateBridge - default ReactivePanacheQuery find(String query, Map params) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheQuery find(String query, Map params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -174,8 +172,8 @@ default ReactivePanacheQuery find(String query, Map para * @see #stream(String, Sort, Map) */ @GenerateBridge - default ReactivePanacheQuery find(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheQuery find(String query, Sort sort, Map params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -191,8 +189,8 @@ default ReactivePanacheQuery find(String query, Sort sort, Map find(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheQuery find(String query, Parameters params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -209,8 +207,8 @@ default ReactivePanacheQuery find(String query, Parameters params) { * @see #stream(String, Sort, Parameters) */ @GenerateBridge - default ReactivePanacheQuery find(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheQuery find(String query, Sort sort, Parameters params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -225,8 +223,8 @@ default ReactivePanacheQuery find(String query, Sort sort, Parameters pa * @see #stream(Document, Document) */ @GenerateBridge - default ReactivePanacheQuery find(Document query) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheQuery find(Document query) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -242,8 +240,8 @@ default ReactivePanacheQuery find(Document query) { * @see #stream(Document, Document) */ @GenerateBridge - default ReactivePanacheQuery find(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheQuery find(Document query, Document sort) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -255,8 +253,8 @@ default ReactivePanacheQuery find(Document query, Document sort) { * @see #streamAll() */ @GenerateBridge - default ReactivePanacheQuery findAll() { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheQuery findAll() { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -269,8 +267,8 @@ default ReactivePanacheQuery findAll() { * @see #streamAll(Sort) */ @GenerateBridge - default ReactivePanacheQuery findAll(Sort sort) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheQuery findAll(Sort sort) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -287,8 +285,8 @@ default ReactivePanacheQuery findAll(Sort sort) { * @see #stream(String, Object...) */ @GenerateBridge - default Uni> list(String query, Object... params) { - throw operations.implementationInjectionMissing(); + public default Uni> list(String query, Object... params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -306,8 +304,8 @@ default Uni> list(String query, Object... params) { * @see #stream(String, Sort, Object...) */ @GenerateBridge - default Uni> list(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + public default Uni> list(String query, Sort sort, Object... params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -324,8 +322,8 @@ default Uni> list(String query, Sort sort, Object... params) { * @see #stream(String, Map) */ @GenerateBridge - default Uni> list(String query, Map params) { - throw operations.implementationInjectionMissing(); + public default Uni> list(String query, Map params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -343,8 +341,8 @@ default Uni> list(String query, Map params) { * @see #stream(String, Sort, Map) */ @GenerateBridge - default Uni> list(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + public default Uni> list(String query, Sort sort, Map params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -361,8 +359,8 @@ default Uni> list(String query, Sort sort, Map para * @see #stream(String, Parameters) */ @GenerateBridge - default Uni> list(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + public default Uni> list(String query, Parameters params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -380,8 +378,8 @@ default Uni> list(String query, Parameters params) { * @see #stream(String, Sort, Parameters) */ @GenerateBridge - default Uni> list(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + public default Uni> list(String query, Sort sort, Parameters params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -397,8 +395,8 @@ default Uni> list(String query, Sort sort, Parameters params) { * @see #stream(Document, Document) */ @GenerateBridge - default Uni> list(Document query) { - throw operations.implementationInjectionMissing(); + public default Uni> list(Document query) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -415,8 +413,8 @@ default Uni> list(Document query) { * @see #stream(Document, Document) */ @GenerateBridge - default Uni> list(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + public default Uni> list(Document query, Document sort) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -429,8 +427,8 @@ default Uni> list(Document query, Document sort) { * @see #streamAll() */ @GenerateBridge - default Uni> listAll() { - throw operations.implementationInjectionMissing(); + public default Uni> listAll() { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -444,8 +442,8 @@ default Uni> listAll() { * @see #streamAll(Sort) */ @GenerateBridge - default Uni> listAll(Sort sort) { - throw operations.implementationInjectionMissing(); + public default Uni> listAll(Sort sort) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -462,8 +460,8 @@ default Uni> listAll(Sort sort) { * @see #list(String, Object...) */ @GenerateBridge - default Multi stream(String query, Object... params) { - throw operations.implementationInjectionMissing(); + public default Multi stream(String query, Object... params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -481,8 +479,8 @@ default Multi stream(String query, Object... params) { * @see #list(String, Sort, Object...) */ @GenerateBridge - default Multi stream(String query, Sort sort, Object... params) { - throw operations.implementationInjectionMissing(); + public default Multi stream(String query, Sort sort, Object... params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -499,8 +497,8 @@ default Multi stream(String query, Sort sort, Object... params) { * @see #list(String, Map) */ @GenerateBridge - default Multi stream(String query, Map params) { - throw operations.implementationInjectionMissing(); + public default Multi stream(String query, Map params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -518,8 +516,8 @@ default Multi stream(String query, Map params) { * @see #list(String, Sort, Map) */ @GenerateBridge - default Multi stream(String query, Sort sort, Map params) { - throw operations.implementationInjectionMissing(); + public default Multi stream(String query, Sort sort, Map params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -536,8 +534,8 @@ default Multi stream(String query, Sort sort, Map params * @see #list(String, Parameters) */ @GenerateBridge - default Multi stream(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + public default Multi stream(String query, Parameters params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -555,8 +553,8 @@ default Multi stream(String query, Parameters params) { * @see #list(String, Sort, Parameters) */ @GenerateBridge - default Multi stream(String query, Sort sort, Parameters params) { - throw operations.implementationInjectionMissing(); + public default Multi stream(String query, Sort sort, Parameters params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -573,8 +571,8 @@ default Multi stream(String query, Sort sort, Parameters params) { * @see #stream(Document, Document) */ @GenerateBridge - default Multi stream(Document query) { - throw operations.implementationInjectionMissing(); + public default Multi stream(Document query) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -592,8 +590,8 @@ default Multi stream(Document query) { * @see #stream(Document, Document) */ @GenerateBridge - default Multi stream(Document query, Document sort) { - throw operations.implementationInjectionMissing(); + public default Multi stream(Document query, Document sort) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -606,8 +604,8 @@ default Multi stream(Document query, Document sort) { * @see #listAll() */ @GenerateBridge - default Multi streamAll(Sort sort) { - throw operations.implementationInjectionMissing(); + public default Multi streamAll(Sort sort) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -620,8 +618,8 @@ default Multi streamAll(Sort sort) { * @see #listAll(Sort) */ @GenerateBridge - default Multi streamAll() { - throw operations.implementationInjectionMissing(); + public default Multi streamAll() { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -633,8 +631,8 @@ default Multi streamAll() { * @see #count(String, Parameters) */ @GenerateBridge - default Uni count() { - throw operations.implementationInjectionMissing(); + public default Uni count() { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -648,8 +646,8 @@ default Uni count() { * @see #count(String, Parameters) */ @GenerateBridge - default Uni count(String query, Object... params) { - throw operations.implementationInjectionMissing(); + public default Uni count(String query, Object... params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -663,8 +661,8 @@ default Uni count(String query, Object... params) { * @see #count(String, Parameters) */ @GenerateBridge - default Uni count(String query, Map params) { - throw operations.implementationInjectionMissing(); + public default Uni count(String query, Map params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -678,8 +676,8 @@ default Uni count(String query, Map params) { * @see #count(String, Map) */ @GenerateBridge - default Uni count(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + public default Uni count(String query, Parameters params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -692,8 +690,8 @@ default Uni count(String query, Parameters params) { * @see #count(String, Map) */ @GenerateBridge - default Uni count(Document query) { - throw operations.implementationInjectionMissing(); + public default Uni count(Document query) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -705,8 +703,8 @@ default Uni count(Document query) { * @see #delete(String, Parameters) */ @GenerateBridge - default Uni deleteAll() { - throw operations.implementationInjectionMissing(); + public default Uni deleteAll() { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -716,8 +714,8 @@ default Uni deleteAll() { * @return false if the entity was not deleted (not found). */ @GenerateBridge - default Uni deleteById(Id id) { - throw operations.implementationInjectionMissing(); + public default Uni deleteById(Id id) { + throw MongoOperations.implementationInjectionMissing(); } /** @@ -731,8 +729,8 @@ default Uni deleteById(Id id) { * @see #delete(String, Parameters) */ @GenerateBridge - default Uni delete(String query, Object... params) { - throw operations.implementationInjectionMissing(); + public default Uni delete(String query, Object... params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -746,8 +744,8 @@ default Uni delete(String query, Object... params) { * @see #delete(String, Parameters) */ @GenerateBridge - default Uni delete(String query, Map params) { - throw operations.implementationInjectionMissing(); + public default Uni delete(String query, Map params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -761,8 +759,8 @@ default Uni delete(String query, Map params) { * @see #delete(String, Map) */ @GenerateBridge - default Uni delete(String query, Parameters params) { - throw operations.implementationInjectionMissing(); + public default Uni delete(String query, Parameters params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -775,8 +773,8 @@ default Uni delete(String query, Parameters params) { * @see #count(String, Map) */ @GenerateBridge - default Uni delete(Document query) { - throw operations.implementationInjectionMissing(); + public default Uni delete(Document query) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -787,8 +785,8 @@ default Uni delete(Document query) { * @see #persist(Stream) * @see #persist(Object,Object...) */ - default Uni persist(Iterable entities) { - return operations.persist(entities); + public default Uni persist(Iterable entities) { + return ReactiveMongoOperations.persist(entities); } /** @@ -799,8 +797,8 @@ default Uni persist(Iterable entities) { * @see #persist(Iterable) * @see #persist(Object,Object...) */ - default Uni persist(Stream entities) { - return operations.persist(entities); + public default Uni persist(Stream entities) { + return ReactiveMongoOperations.persist(entities); } /** @@ -811,8 +809,8 @@ default Uni persist(Stream entities) { * @see #persist(Stream) * @see #persist(Iterable) */ - default Uni persist(Entity firstEntity, Entity... entities) { - return operations.persist(firstEntity, entities); + public default Uni persist(Entity firstEntity, @SuppressWarnings("unchecked") Entity... entities) { + return ReactiveMongoOperations.persist(firstEntity, entities); } /** @@ -823,8 +821,8 @@ default Uni persist(Entity firstEntity, Entity... entities) { * @see #update(Stream) * @see #update(Object,Object...) */ - default Uni update(Iterable entities) { - return operations.update(entities); + public default Uni update(Iterable entities) { + return ReactiveMongoOperations.update(entities); } /** @@ -835,8 +833,8 @@ default Uni update(Iterable entities) { * @see #update(Iterable) * @see #update(Object,Object...) */ - default Uni update(Stream entities) { - return operations.update(entities); + public default Uni update(Stream entities) { + return ReactiveMongoOperations.update(entities); } /** @@ -847,8 +845,8 @@ default Uni update(Stream entities) { * @see #update(Stream) * @see #update(Iterable) */ - default Uni update(Entity firstEntity, Entity... entities) { - return operations.update(firstEntity, entities); + public default Uni update(Entity firstEntity, @SuppressWarnings("unchecked") Entity... entities) { + return ReactiveMongoOperations.update(firstEntity, entities); } /** @@ -859,8 +857,8 @@ default Uni update(Entity firstEntity, Entity... entities) { * @see #persistOrUpdate(Stream) * @see #persistOrUpdate(Object,Object...) */ - default Uni persistOrUpdate(Iterable entities) { - return operations.persistOrUpdate(entities); + public default Uni persistOrUpdate(Iterable entities) { + return ReactiveMongoOperations.persistOrUpdate(entities); } /** @@ -871,8 +869,8 @@ default Uni persistOrUpdate(Iterable entities) { * @see #persistOrUpdate(Iterable) * @see #persistOrUpdate(Object,Object...) */ - default Uni persistOrUpdate(Stream entities) { - return operations.persistOrUpdate(entities); + public default Uni persistOrUpdate(Stream entities) { + return ReactiveMongoOperations.persistOrUpdate(entities); } /** @@ -883,8 +881,9 @@ default Uni persistOrUpdate(Stream entities) { * @see #update(Stream) * @see #update(Iterable) */ - default Uni persistOrUpdate(Entity firstEntity, Entity... entities) { - return operations.persistOrUpdate(firstEntity, entities); + public default Uni persistOrUpdate(Entity firstEntity, + @SuppressWarnings("unchecked") Entity... entities) { + return ReactiveMongoOperations.persistOrUpdate(firstEntity, entities); } /** @@ -899,8 +898,8 @@ default Uni persistOrUpdate(Entity firstEntity, Entity... entities) { * @see #update(String, Parameters) */ @GenerateBridge - default ReactivePanacheUpdate update(String update, Object... params) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheUpdate update(String update, Object... params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -916,8 +915,8 @@ default ReactivePanacheUpdate update(String update, Object... params) { * */ @GenerateBridge - default ReactivePanacheUpdate update(String update, Map params) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheUpdate update(String update, Map params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** @@ -932,23 +931,23 @@ default ReactivePanacheUpdate update(String update, Map params) * @see #update(String, Map) */ @GenerateBridge - default ReactivePanacheUpdate update(String update, Parameters params) { - throw operations.implementationInjectionMissing(); + public default ReactivePanacheUpdate update(String update, Parameters params) { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** * Allow to access the underlying Mongo Collection */ @GenerateBridge - default ReactiveMongoCollection mongoCollection() { - throw operations.implementationInjectionMissing(); + public default ReactiveMongoCollection mongoCollection() { + throw ReactiveMongoOperations.implementationInjectionMissing(); } /** * Allow to access the underlying Mongo Database. */ @GenerateBridge - default ReactiveMongoDatabase mongoDatabase() { - throw operations.implementationInjectionMissing(); + public default ReactiveMongoDatabase mongoDatabase() { + throw ReactiveMongoOperations.implementationInjectionMissing(); } } diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheUpdate.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheUpdate.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheUpdate.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/ReactivePanacheUpdate.java diff --git a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/JavaReactiveMongoOperations.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/JavaReactiveMongoOperations.java deleted file mode 100644 index 780526bc7c83b..0000000000000 --- a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/JavaReactiveMongoOperations.java +++ /dev/null @@ -1,35 +0,0 @@ -package io.quarkus.mongodb.panache.reactive.runtime; - -import java.util.List; - -import org.bson.Document; - -import io.quarkus.mongodb.panache.reactive.ReactivePanacheQuery; -import io.quarkus.mongodb.panache.reactive.ReactivePanacheUpdate; -import io.quarkus.mongodb.reactive.ReactiveMongoCollection; -import io.smallrye.mutiny.Multi; -import io.smallrye.mutiny.Uni; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class JavaReactiveMongoOperations extends ReactiveMongoOperations, ReactivePanacheUpdate> { - @Override - protected ReactivePanacheQuery createQuery(ReactiveMongoCollection collection, Document query, Document sortDoc) { - return new ReactivePanacheQueryImpl(collection, query, sortDoc); - } - - @Override - protected ReactivePanacheUpdate createUpdate(ReactiveMongoCollection collection, Class entityClass, - Document docUpdate) { - return new ReactivePanacheUpdateImpl(this, entityClass, docUpdate, collection); - } - - @Override - protected Uni> list(ReactivePanacheQuery query) { - return query.list(); - } - - @Override - protected Multi stream(ReactivePanacheQuery query) { - return query.stream(); - } -} diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactiveMongoOperations.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactiveMongoOperations.java similarity index 67% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactiveMongoOperations.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactiveMongoOperations.java index 38671bff4399f..b092143b53a49 100644 --- a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactiveMongoOperations.java +++ b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactiveMongoOperations.java @@ -30,6 +30,8 @@ import io.quarkus.mongodb.panache.MongoEntity; import io.quarkus.mongodb.panache.binder.NativeQueryBinder; import io.quarkus.mongodb.panache.binder.PanacheQlQueryBinder; +import io.quarkus.mongodb.panache.reactive.ReactivePanacheQuery; +import io.quarkus.mongodb.panache.reactive.ReactivePanacheUpdate; import io.quarkus.mongodb.reactive.ReactiveMongoClient; import io.quarkus.mongodb.reactive.ReactiveMongoCollection; import io.quarkus.mongodb.reactive.ReactiveMongoDatabase; @@ -38,27 +40,21 @@ import io.smallrye.mutiny.Multi; import io.smallrye.mutiny.Uni; -@SuppressWarnings({ "rawtypes", "unchecked", "Convert2MethodRef" }) -public abstract class ReactiveMongoOperations { - public final String ID = "_id"; +public class ReactiveMongoOperations { private static final Logger LOGGER = Logger.getLogger(ReactiveMongoOperations.class); - private static final Map defaultDatabaseName = new ConcurrentHashMap<>(); - - protected abstract QueryType createQuery(ReactiveMongoCollection collection, Document query, Document sortDoc); + public static final String ID = "_id"; - protected abstract UpdateType createUpdate(ReactiveMongoCollection collection, Class entityClass, - Document docUpdate); - - protected abstract Uni list(QueryType query); + private static final Map defaultDatabaseName = new ConcurrentHashMap<>(); - protected abstract Multi stream(QueryType query); + // + // Instance methods - public Uni persist(Object entity) { + public static Uni persist(Object entity) { ReactiveMongoCollection collection = mongoCollection(entity); return persist(collection, entity); } - public Uni persist(Iterable entities) { + public static Uni persist(Iterable entities) { return Uni.createFrom().deferred(() -> { // not all iterables are re-traversal, so we traverse it once for copying inside a list List objects = new ArrayList<>(); @@ -76,7 +72,7 @@ public Uni persist(Iterable entities) { }); } - public Uni persist(Object firstEntity, Object... entities) { + public static Uni persist(Object firstEntity, Object... entities) { ReactiveMongoCollection collection = mongoCollection(firstEntity); if (entities == null || entities.length == 0) { return persist(collection, firstEntity); @@ -88,7 +84,7 @@ public Uni persist(Object firstEntity, Object... entities) { } } - public Uni persist(Stream entities) { + public static Uni persist(Stream entities) { return Uni.createFrom().deferred(() -> { List objects = entities.collect(Collectors.toList()); if (objects.size() > 0) { @@ -101,12 +97,12 @@ public Uni persist(Stream entities) { }); } - public Uni update(Object entity) { + public static Uni update(Object entity) { ReactiveMongoCollection collection = mongoCollection(entity); return update(collection, entity); } - public Uni update(Iterable entities) { + public static Uni update(Iterable entities) { return Uni.createFrom().deferred(() -> { // not all iterables are re-traversal, so we traverse it once for copying inside a list List objects = new ArrayList<>(); @@ -124,7 +120,7 @@ public Uni update(Iterable entities) { }); } - public Uni update(Object firstEntity, Object... entities) { + public static Uni update(Object firstEntity, Object... entities) { ReactiveMongoCollection collection = mongoCollection(firstEntity); if (entities == null || entities.length == 0) { return update(collection, firstEntity); @@ -136,7 +132,7 @@ public Uni update(Object firstEntity, Object... entities) { } } - public Uni update(Stream entities) { + public static Uni update(Stream entities) { return Uni.createFrom().deferred(() -> { List objects = entities.collect(Collectors.toList()); if (objects.size() > 0) { @@ -149,12 +145,12 @@ public Uni update(Stream entities) { }); } - public Uni persistOrUpdate(Object entity) { + public static Uni persistOrUpdate(Object entity) { ReactiveMongoCollection collection = mongoCollection(entity); return persistOrUpdate(collection, entity); } - public Uni persistOrUpdate(Iterable entities) { + public static Uni persistOrUpdate(Iterable entities) { return Uni.createFrom().deferred(() -> { // not all iterables are re-traversal, so we traverse it once for copying inside a list List objects = new ArrayList<>(); @@ -172,7 +168,7 @@ public Uni persistOrUpdate(Iterable entities) { }); } - public Uni persistOrUpdate(Object firstEntity, Object... entities) { + public static Uni persistOrUpdate(Object firstEntity, Object... entities) { ReactiveMongoCollection collection = mongoCollection(firstEntity); if (entities == null || entities.length == 0) { return persistOrUpdate(collection, firstEntity); @@ -184,7 +180,7 @@ public Uni persistOrUpdate(Object firstEntity, Object... entities) { } } - public Uni persistOrUpdate(Stream entities) { + public static Uni persistOrUpdate(Stream entities) { return Uni.createFrom().deferred(() -> { List objects = entities.collect(Collectors.toList()); if (objects.size() > 0) { @@ -197,7 +193,7 @@ public Uni persistOrUpdate(Stream entities) { }); } - public Uni delete(Object entity) { + public static Uni delete(Object entity) { ReactiveMongoCollection collection = mongoCollection(entity); BsonDocument document = getBsonDocument(collection, entity); BsonValue id = document.get(ID); @@ -205,7 +201,7 @@ public Uni delete(Object entity) { return collection.deleteOne(query).onItem().ignore().andContinueWithNull(); } - public ReactiveMongoCollection mongoCollection(Class entityClass) { + public static ReactiveMongoCollection mongoCollection(Class entityClass) { MongoEntity mongoEntity = entityClass.getAnnotation(MongoEntity.class); ReactiveMongoDatabase database = mongoDatabase(mongoEntity); if (mongoEntity != null && !mongoEntity.collection().isEmpty()) { @@ -214,7 +210,7 @@ public ReactiveMongoCollection mongoCollection(Class entityClass) { return database.getCollection(entityClass.getSimpleName(), entityClass); } - public ReactiveMongoDatabase mongoDatabase(Class entityClass) { + public static ReactiveMongoDatabase mongoDatabase(Class entityClass) { MongoEntity mongoEntity = entityClass.getAnnotation(MongoEntity.class); return mongoDatabase(mongoEntity); } @@ -222,19 +218,19 @@ public ReactiveMongoDatabase mongoDatabase(Class entityClass) { // // Private stuff - public Uni nullUni() { + public static Uni nullUni() { return Uni.createFrom().item((Void) null); } - private Uni persist(ReactiveMongoCollection collection, Object entity) { + private static Uni persist(ReactiveMongoCollection collection, Object entity) { return collection.insertOne(entity).onItem().ignore().andContinueWithNull(); } - private Uni persist(ReactiveMongoCollection collection, List entities) { + private static Uni persist(ReactiveMongoCollection collection, List entities) { return collection.insertMany(entities).onItem().ignore().andContinueWithNull(); } - private Uni update(ReactiveMongoCollection collection, Object entity) { + private static Uni update(ReactiveMongoCollection collection, Object entity) { //we transform the entity as a document first BsonDocument document = getBsonDocument(collection, entity); @@ -244,12 +240,12 @@ private Uni update(ReactiveMongoCollection collection, Object entity) { return collection.replaceOne(query, entity).onItem().ignore().andContinueWithNull(); } - private Uni update(ReactiveMongoCollection collection, List entities) { + private static Uni update(ReactiveMongoCollection collection, List entities) { List> unis = entities.stream().map(entity -> update(collection, entity)).collect(Collectors.toList()); return Uni.combine().all().unis(unis).combinedWith(u -> null); } - private Uni persistOrUpdate(ReactiveMongoCollection collection, Object entity) { + private static Uni persistOrUpdate(ReactiveMongoCollection collection, Object entity) { //we transform the entity as a document first BsonDocument document = getBsonDocument(collection, entity); @@ -266,7 +262,7 @@ private Uni persistOrUpdate(ReactiveMongoCollection collection, Object ent } } - private Uni persistOrUpdate(ReactiveMongoCollection collection, List entities) { + private static Uni persistOrUpdate(ReactiveMongoCollection collection, List entities) { //this will be an ordered bulk: it's less performant than a unordered one but will fail at the first failed write List bulk = new ArrayList<>(); for (Object entity : entities) { @@ -289,19 +285,19 @@ private Uni persistOrUpdate(ReactiveMongoCollection collection, List entityClass = entity.getClass(); return mongoCollection(entityClass); } - private ReactiveMongoDatabase mongoDatabase(MongoEntity entity) { + private static ReactiveMongoDatabase mongoDatabase(MongoEntity entity) { ReactiveMongoClient mongoClient = clientFromArc(entity, ReactiveMongoClient.class); if (entity != null && !entity.database().isEmpty()) { return mongoClient.getDatabase(entity.database()); @@ -310,7 +306,7 @@ private ReactiveMongoDatabase mongoDatabase(MongoEntity entity) { return mongoClient.getDatabase(databaseName); } - private String getDefaultDatabaseName(MongoEntity entity) { + private static String getDefaultDatabaseName(MongoEntity entity) { return defaultDatabaseName.computeIfAbsent(beanName(entity), new Function() { @Override public String apply(String beanName) { @@ -322,35 +318,35 @@ public String apply(String beanName) { // // Queries - public Uni findById(Class entityClass, Object id) { + public static Uni findById(Class entityClass, Object id) { Uni optionalEntity = findByIdOptional(entityClass, id); return optionalEntity.onItem().transform(optional -> optional.orElse(null)); } - public Uni findByIdOptional(Class entityClass, Object id) { + public static Uni findByIdOptional(Class entityClass, Object id) { ReactiveMongoCollection collection = mongoCollection(entityClass); return collection.find(new Document(ID, id)).collectItems().first() .onItem().transform(Optional::ofNullable); } - public QueryType find(Class entityClass, String query, Object... params) { + public static ReactivePanacheQuery find(Class entityClass, String query, Object... params) { return find(entityClass, query, null, params); } @SuppressWarnings("rawtypes") - public QueryType find(Class entityClass, String query, Sort sort, Object... params) { + public static ReactivePanacheQuery find(Class entityClass, String query, Sort sort, Object... params) { String bindQuery = bindFilter(entityClass, query, params); - Document docQuery = Document.parse(bindQuery); + BsonDocument docQuery = BsonDocument.parse(bindQuery); Document docSort = sortToDocument(sort); ReactiveMongoCollection collection = mongoCollection(entityClass); - return createQuery(collection, docQuery, docSort); + return new ReactivePanacheQueryImpl(collection, docQuery, docSort); } /** * We should have a query like {'firstname': ?1, 'lastname': ?2} for native one * and like firstname = ?1 for PanacheQL one. */ - public String bindFilter(Class clazz, String query, Object[] params) { + static String bindFilter(Class clazz, String query, Object[] params) { String bindQuery = bindQuery(clazz, query, params); LOGGER.debug(bindQuery); return bindQuery; @@ -360,7 +356,7 @@ public String bindFilter(Class clazz, String query, Object[] params) { * We should have a query like {'firstname': :firstname, 'lastname': :lastname} for native one * and like firstname = :firstname and lastname = :lastname for PanacheQL one. */ - public String bindFilter(Class clazz, String query, Map params) { + static String bindFilter(Class clazz, String query, Map params) { String bindQuery = bindQuery(clazz, query, params); LOGGER.debug(bindQuery); return bindQuery; @@ -371,7 +367,7 @@ public String bindFilter(Class clazz, String query, Map param * and like firstname = ?1 and lastname = ?2 for PanacheQL one. * As update document needs a $set operator we add it if needed. */ - String bindUpdate(Class clazz, String query, Object[] params) { + static String bindUpdate(Class clazz, String query, Object[] params) { String bindUpdate = bindQuery(clazz, query, params); if (!bindUpdate.contains("$set")) { bindUpdate = "{'$set':" + bindUpdate + "}"; @@ -385,7 +381,7 @@ String bindUpdate(Class clazz, String query, Object[] params) { * and like firstname = :firstname and lastname = :lastname for PanacheQL one. * As update document needs a $set operator we add it if needed. */ - String bindUpdate(Class clazz, String query, Map params) { + static String bindUpdate(Class clazz, String query, Map params) { String bindUpdate = bindQuery(clazz, query, params); if (!bindUpdate.contains("$set")) { bindUpdate = "{'$set':" + bindUpdate + "}"; @@ -394,7 +390,7 @@ String bindUpdate(Class clazz, String query, Map params) { return bindUpdate; } - String bindQuery(Class clazz, String query, Object[] params) { + static String bindQuery(Class clazz, String query, Object[] params) { String bindQuery = null; //determine the type of the query @@ -409,7 +405,7 @@ String bindQuery(Class clazz, String query, Object[] params) { return bindQuery; } - String bindQuery(Class clazz, String query, Map params) { + static String bindQuery(Class clazz, String query, Map params) { String bindQuery = null; //determine the type of the query @@ -424,125 +420,125 @@ String bindQuery(Class clazz, String query, Map params) { return bindQuery; } - public QueryType find(Class entityClass, String query, Map params) { + public static ReactivePanacheQuery find(Class entityClass, String query, Map params) { return find(entityClass, query, null, params); } @SuppressWarnings("rawtypes") - public QueryType find(Class entityClass, String query, Sort sort, Map params) { + public static ReactivePanacheQuery find(Class entityClass, String query, Sort sort, Map params) { String bindQuery = bindFilter(entityClass, query, params); - Document docQuery = Document.parse(bindQuery); + BsonDocument docQuery = BsonDocument.parse(bindQuery); Document docSort = sortToDocument(sort); ReactiveMongoCollection collection = mongoCollection(entityClass); - return createQuery(collection, docQuery, docSort); + return new ReactivePanacheQueryImpl(collection, docQuery, docSort); } - public QueryType find(Class entityClass, String query, Parameters params) { + public static ReactivePanacheQuery find(Class entityClass, String query, Parameters params) { return find(entityClass, query, null, params.map()); } - public QueryType find(Class entityClass, String query, Sort sort, Parameters params) { + public static ReactivePanacheQuery find(Class entityClass, String query, Sort sort, Parameters params) { return find(entityClass, query, sort, params.map()); } @SuppressWarnings("rawtypes") - public QueryType find(Class entityClass, Document query, Sort sort) { + public static ReactivePanacheQuery find(Class entityClass, Document query, Sort sort) { ReactiveMongoCollection collection = mongoCollection(entityClass); Document sortDoc = sortToDocument(sort); - return createQuery(collection, query, sortDoc); + return new ReactivePanacheQueryImpl(collection, query, sortDoc); } - public QueryType find(Class entityClass, Document query, Document sort) { + public static ReactivePanacheQuery find(Class entityClass, Document query, Document sort) { ReactiveMongoCollection collection = mongoCollection(entityClass); - return createQuery(collection, query, sort); + return new ReactivePanacheQueryImpl(collection, query, sort); } - public QueryType find(Class entityClass, Document query) { + public static ReactivePanacheQuery find(Class entityClass, Document query) { return find(entityClass, query, (Document) null); } - public Uni> list(Class entityClass, String query, Object... params) { - return (Uni) list(find(entityClass, query, params)); + public static Uni> list(Class entityClass, String query, Object... params) { + return (Uni) find(entityClass, query, params).list(); } - public Uni> list(Class entityClass, String query, Sort sort, Object... params) { - return (Uni) list(find(entityClass, query, sort, params)); + public static Uni> list(Class entityClass, String query, Sort sort, Object... params) { + return (Uni) find(entityClass, query, sort, params).list(); } - public Uni> list(Class entityClass, String query, Map params) { - return (Uni) list(find(entityClass, query, params)); + public static Uni> list(Class entityClass, String query, Map params) { + return (Uni) find(entityClass, query, params).list(); } - public Uni> list(Class entityClass, String query, Sort sort, Map params) { - return (Uni) list(find(entityClass, query, sort, params)); + public static Uni> list(Class entityClass, String query, Sort sort, Map params) { + return (Uni) find(entityClass, query, sort, params).list(); } - public Uni> list(Class entityClass, String query, Parameters params) { - return (Uni) list(find(entityClass, query, params)); + public static Uni> list(Class entityClass, String query, Parameters params) { + return (Uni) find(entityClass, query, params).list(); } - public Uni> list(Class entityClass, String query, Sort sort, Parameters params) { - return (Uni) list(find(entityClass, query, sort, params)); + public static Uni> list(Class entityClass, String query, Sort sort, Parameters params) { + return (Uni) find(entityClass, query, sort, params).list(); } //specific Mongo query - public Uni> list(Class entityClass, Document query) { - return (Uni) list(find(entityClass, query)); + public static Uni> list(Class entityClass, Document query) { + return (Uni) find(entityClass, query).list(); } //specific Mongo query - public Uni> list(Class entityClass, Document query, Document sort) { - return (Uni) list(find(entityClass, query, sort)); + public static Uni> list(Class entityClass, Document query, Document sort) { + return (Uni) find(entityClass, query, sort).list(); } - public Multi stream(Class entityClass, String query, Object... params) { - return stream(find(entityClass, query, params)); + public static Multi stream(Class entityClass, String query, Object... params) { + return find(entityClass, query, params).stream(); } - public Multi stream(Class entityClass, String query, Sort sort, Object... params) { - return stream(find(entityClass, query, sort, params)); + public static Multi stream(Class entityClass, String query, Sort sort, Object... params) { + return find(entityClass, query, sort, params).stream(); } - public Multi stream(Class entityClass, String query, Map params) { - return stream(find(entityClass, query, params)); + public static Multi stream(Class entityClass, String query, Map params) { + return find(entityClass, query, params).stream(); } - public Multi stream(Class entityClass, String query, Sort sort, Map params) { - return stream(find(entityClass, query, sort, params)); + public static Multi stream(Class entityClass, String query, Sort sort, Map params) { + return find(entityClass, query, sort, params).stream(); } - public Multi stream(Class entityClass, String query, Parameters params) { - return stream(find(entityClass, query, params)); + public static Multi stream(Class entityClass, String query, Parameters params) { + return find(entityClass, query, params).stream(); } - public Multi stream(Class entityClass, String query, Sort sort, Parameters params) { - return stream(find(entityClass, query, sort, params)); + public static Multi stream(Class entityClass, String query, Sort sort, Parameters params) { + return find(entityClass, query, sort, params).stream(); } //specific Mongo query - public Multi stream(Class entityClass, Document query) { - return stream(find(entityClass, query)); + public static Multi stream(Class entityClass, Document query) { + return find(entityClass, query).stream(); } //specific Mongo query - public Multi stream(Class entityClass, Document query, Document sort) { - return stream(find(entityClass, query, sort)); + public static Multi stream(Class entityClass, Document query, Document sort) { + return find(entityClass, query, sort).stream(); } @SuppressWarnings("rawtypes") - public QueryType findAll(Class entityClass) { + public static ReactivePanacheQuery findAll(Class entityClass) { ReactiveMongoCollection collection = mongoCollection(entityClass); - return createQuery(collection, null, null); + return new ReactivePanacheQueryImpl(collection, null, null); } @SuppressWarnings("rawtypes") - public QueryType findAll(Class entityClass, Sort sort) { + public static ReactivePanacheQuery findAll(Class entityClass, Sort sort) { ReactiveMongoCollection collection = mongoCollection(entityClass); Document sortDoc = sortToDocument(sort); - return createQuery(collection, null, sortDoc); + return new ReactivePanacheQueryImpl(collection, null, sortDoc); } - private Document sortToDocument(Sort sort) { + private static Document sortToDocument(Sort sort) { if (sort == null) { return null; } @@ -554,114 +550,115 @@ private Document sortToDocument(Sort sort) { return sortDoc; } - public Uni> listAll(Class entityClass) { - return (Uni) list(findAll(entityClass)); + public static Uni> listAll(Class entityClass) { + return (Uni) findAll(entityClass).list(); } - public Uni> listAll(Class entityClass, Sort sort) { - return (Uni) list(findAll(entityClass, sort)); + public static Uni> listAll(Class entityClass, Sort sort) { + return (Uni) findAll(entityClass, sort).list(); } - public Multi streamAll(Class entityClass) { - return stream(findAll(entityClass)); + public static Multi streamAll(Class entityClass) { + return findAll(entityClass).stream(); } - public Multi streamAll(Class entityClass, Sort sort) { - return stream(findAll(entityClass, sort)); + public static Multi streamAll(Class entityClass, Sort sort) { + return findAll(entityClass, sort).stream(); } - public Uni count(Class entityClass) { + public static Uni count(Class entityClass) { ReactiveMongoCollection collection = mongoCollection(entityClass); return collection.countDocuments(); } - public Uni count(Class entityClass, String query, Object... params) { + public static Uni count(Class entityClass, String query, Object... params) { String bindQuery = bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); ReactiveMongoCollection collection = mongoCollection(entityClass); return collection.countDocuments(docQuery); } - public Uni count(Class entityClass, String query, Map params) { + public static Uni count(Class entityClass, String query, Map params) { String bindQuery = bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); ReactiveMongoCollection collection = mongoCollection(entityClass); return collection.countDocuments(docQuery); } - public Uni count(Class entityClass, String query, Parameters params) { + public static Uni count(Class entityClass, String query, Parameters params) { return count(entityClass, query, params.map()); } //specific Mongo query - public Uni count(Class entityClass, Document query) { + public static Uni count(Class entityClass, Document query) { ReactiveMongoCollection collection = mongoCollection(entityClass); return collection.countDocuments(query); } - public Uni deleteAll(Class entityClass) { + public static Uni deleteAll(Class entityClass) { ReactiveMongoCollection collection = mongoCollection(entityClass); return collection.deleteMany(new Document()).map(deleteResult -> deleteResult.getDeletedCount()); } - public Uni deleteById(Class entityClass, Object id) { + public static Uni deleteById(Class entityClass, Object id) { ReactiveMongoCollection collection = mongoCollection(entityClass); Document query = new Document().append(ID, id); return collection.deleteOne(query).map(results -> results.getDeletedCount() == 1); } - public Uni delete(Class entityClass, String query, Object... params) { + public static Uni delete(Class entityClass, String query, Object... params) { String bindQuery = bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); ReactiveMongoCollection collection = mongoCollection(entityClass); return collection.deleteMany(docQuery).map(deleteResult -> deleteResult.getDeletedCount()); } - public Uni delete(Class entityClass, String query, Map params) { + public static Uni delete(Class entityClass, String query, Map params) { String bindQuery = bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); ReactiveMongoCollection collection = mongoCollection(entityClass); return collection.deleteMany(docQuery).map(deleteResult -> deleteResult.getDeletedCount()); } - public Uni delete(Class entityClass, String query, Parameters params) { + public static Uni delete(Class entityClass, String query, Parameters params) { return delete(entityClass, query, params.map()); } //specific Mongo query - public Uni delete(Class entityClass, Document query) { + public static Uni delete(Class entityClass, Document query) { ReactiveMongoCollection collection = mongoCollection(entityClass); return collection.deleteMany(query).map(deleteResult -> deleteResult.getDeletedCount()); } - public UpdateType update(Class entityClass, String update, Map params) { + public static ReactivePanacheUpdate update(Class entityClass, String update, Map params) { return executeUpdate(entityClass, update, params); } - public UpdateType update(Class entityClass, String update, Parameters params) { + public static ReactivePanacheUpdate update(Class entityClass, String update, Parameters params) { return update(entityClass, update, params.map()); } - public UpdateType update(Class entityClass, String update, Object... params) { + public static ReactivePanacheUpdate update(Class entityClass, String update, Object... params) { return executeUpdate(entityClass, update, params); } - private UpdateType executeUpdate(Class entityClass, String update, Object... params) { + private static ReactivePanacheUpdate executeUpdate(Class entityClass, String update, Object... params) { String bindUpdate = bindUpdate(entityClass, update, params); - Document docUpdate = Document.parse(bindUpdate); + BsonDocument docUpdate = BsonDocument.parse(bindUpdate); ReactiveMongoCollection collection = mongoCollection(entityClass); - return createUpdate(collection, entityClass, docUpdate); + return new ReactivePanacheUpdateImpl(entityClass, docUpdate, collection); } - private UpdateType executeUpdate(Class entityClass, String update, Map params) { + private static ReactivePanacheUpdate executeUpdate(Class entityClass, String update, Map params) { String bindUpdate = bindUpdate(entityClass, update, params); - Document docUpdate = Document.parse(bindUpdate); + BsonDocument docUpdate = BsonDocument.parse(bindUpdate); ReactiveMongoCollection collection = mongoCollection(entityClass); - return createUpdate(collection, entityClass, docUpdate); + return new ReactivePanacheUpdateImpl(entityClass, docUpdate, collection); } - public IllegalStateException implementationInjectionMissing() { + public static IllegalStateException implementationInjectionMissing() { return new IllegalStateException( "This method is normally automatically overridden in subclasses"); } + } diff --git a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactivePanacheQueryImpl.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactivePanacheQueryImpl.java index bf3c08369f6ac..4ebd2b7d73ff0 100644 --- a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactivePanacheQueryImpl.java +++ b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactivePanacheQueryImpl.java @@ -2,38 +2,74 @@ import java.util.List; import java.util.Optional; +import java.util.Set; +import org.bson.Document; import org.bson.conversions.Bson; import com.mongodb.client.model.Collation; +import io.quarkus.mongodb.FindOptions; import io.quarkus.mongodb.panache.reactive.ReactivePanacheQuery; +import io.quarkus.mongodb.panache.runtime.MongoPropertyUtil; import io.quarkus.mongodb.reactive.ReactiveMongoCollection; import io.quarkus.panache.common.Page; +import io.quarkus.panache.common.Range; +import io.quarkus.panache.common.exception.PanacheQueryException; import io.smallrye.mutiny.Multi; import io.smallrye.mutiny.Uni; -@SuppressWarnings("unchecked") public class ReactivePanacheQueryImpl implements ReactivePanacheQuery { - private final CommonReactivePanacheQueryImpl delegate; + private ReactiveMongoCollection collection; + private Bson mongoQuery; + private Bson sort; + private Bson projections; + + private Page page; + private Uni count; + + private Range range; + + private Collation collation; ReactivePanacheQueryImpl(ReactiveMongoCollection collection, Bson mongoQuery, Bson sort) { - this.delegate = new CommonReactivePanacheQueryImpl<>(collection, mongoQuery, sort); + this.collection = collection; + this.mongoQuery = mongoQuery; + this.sort = sort; } - private ReactivePanacheQueryImpl(CommonReactivePanacheQueryImpl delegate) { - this.delegate = delegate; + private ReactivePanacheQueryImpl(ReactivePanacheQueryImpl previousQuery, Bson projections, Class type) { + this.collection = previousQuery.collection.withDocumentClass(type); + this.mongoQuery = previousQuery.mongoQuery; + this.sort = previousQuery.sort; + this.projections = projections; + this.page = previousQuery.page; + this.count = previousQuery.count; + this.range = previousQuery.range; + this.collation = previousQuery.collation; } + // Builder + @Override public ReactivePanacheQuery project(Class type) { - return new ReactivePanacheQueryImpl<>(delegate.project(type)); + // collect field names from public fields and getters + Set fieldNames = MongoPropertyUtil.collectFields(type); + + // create the projection document + Document projections = new Document(); + for (String fieldName : fieldNames) { + projections.append(fieldName, 1); + } + + return new ReactivePanacheQueryImpl(this, projections, type); } @Override @SuppressWarnings("unchecked") public ReactivePanacheQuery page(Page page) { - delegate.page(page); + this.page = page; + this.range = null; // reset the range to be able to switch from range to page return (ReactivePanacheQuery) this; } @@ -44,92 +80,179 @@ public ReactivePanacheQuery page(int pageIndex, int pageSi @Override public ReactivePanacheQuery nextPage() { - delegate.nextPage(); - return (ReactivePanacheQuery) this; + checkPagination(); + return page(page.next()); } @Override public ReactivePanacheQuery previousPage() { - delegate.previousPage(); - return (ReactivePanacheQuery) this; + checkPagination(); + return page(page.previous()); } @Override public ReactivePanacheQuery firstPage() { - delegate.firstPage(); - return (ReactivePanacheQuery) this; + checkPagination(); + return page(page.first()); } @Override public Uni> lastPage() { - Uni> uni = delegate.lastPage(); - return uni.map(q -> (ReactivePanacheQuery) this); + checkPagination(); + return pageCount().map(pageCount -> page(page.index(pageCount - 1))); } @Override public Uni hasNextPage() { - return delegate.hasNextPage(); + checkPagination(); + return pageCount().map(pageCount -> page.index < (pageCount - 1)); } @Override public boolean hasPreviousPage() { - return delegate.hasPreviousPage(); + checkPagination(); + return page.index > 0; } @Override public Uni pageCount() { - return delegate.pageCount(); + checkPagination(); + return count().map(count -> { + if (count == 0) + return 1; // a single page of zero results + return (int) Math.ceil((double) count / (double) page.size); + }); } @Override public Page page() { - return delegate.page(); + checkPagination(); + return page; + } + + private void checkPagination() { + if (page == null) { + throw new UnsupportedOperationException( + "Cannot call a page related method, " + + "call page(Page) or page(int, int) to initiate pagination first"); + } + if (range != null) { + throw new UnsupportedOperationException("Cannot call a page related method in a ranged query, " + + "call page(Page) or page(int, int) to initiate pagination first"); + } } @Override public ReactivePanacheQuery range(int startIndex, int lastIndex) { - delegate.range(startIndex, lastIndex); + this.range = Range.of(startIndex, lastIndex); + // reset the page to its default to be able to switch from page to range + this.page = null; return (ReactivePanacheQuery) this; } @Override public ReactivePanacheQuery withCollation(Collation collation) { - delegate.withCollation(collation); + this.collation = collation; return (ReactivePanacheQuery) this; } + // Results + @Override + @SuppressWarnings("unchecked") public Uni count() { - return delegate.count(); + if (count == null) { + count = collection.countDocuments(mongoQuery); + } + return count; } @Override + @SuppressWarnings("unchecked") public Uni> list() { - return delegate.list(); + Multi results = stream(); + return results.collectItems().asList(); } @Override + @SuppressWarnings("unchecked") public Multi stream() { - return delegate.stream(); + FindOptions options = buildOptions(); + return mongoQuery == null ? collection.find(options) : collection.find(mongoQuery, options); } @Override public Uni firstResult() { - return delegate.firstResult(); + Uni> optionalEntity = firstResultOptional(); + return optionalEntity.map(optional -> optional.orElse(null)); } @Override public Uni> firstResultOptional() { - return delegate.firstResultOptional(); + FindOptions options = buildOptions(1); + Multi results = mongoQuery == null ? collection.find(options) : collection.find(mongoQuery, options); + return results.collectItems().first().map(o -> Optional.ofNullable(o)); } @Override + @SuppressWarnings("unchecked") public Uni singleResult() { - return delegate.singleResult(); + FindOptions options = buildOptions(2); + Multi results = mongoQuery == null ? collection.find(options) : collection.find(mongoQuery, options); + return results.collectItems().asList().map(list -> { + if (list.size() != 1) { + throw new PanacheQueryException("There should be only one result"); + } else { + return list.get(0); + } + }); } @Override public Uni> singleResultOptional() { - return delegate.singleResultOptional(); + FindOptions options = buildOptions(2); + Multi results = mongoQuery == null ? collection.find(options) : collection.find(mongoQuery, options); + return results.collectItems().asList().map(list -> { + if (list.size() == 2) { + throw new PanacheQueryException("There should be no more than one result"); + } + return list.isEmpty() ? Optional.empty() : Optional.of(list.get(0)); + }); + } + + private FindOptions buildOptions() { + FindOptions options = new FindOptions(); + options.sort(sort); + if (range != null) { + // range is 0 based, so we add 1 to the limit + options.skip(range.getStartIndex()).limit(range.getLastIndex() - range.getStartIndex() + 1); + } else if (page != null) { + options.skip(page.index * page.size).limit(page.size); + } + if (projections != null) { + options.projection(this.projections); + } + if (this.collation != null) { + options.collation(collation); + } + return options; + } + + private FindOptions buildOptions(int maxResults) { + FindOptions options = new FindOptions(); + options.sort(sort); + if (range != null) { + // range is 0 based, so we add 1 to the limit + options.skip(range.getStartIndex()); + } else if (page != null) { + options.skip(page.index * page.size); + } + if (projections != null) { + options.projection(this.projections); + } + if (this.collation != null) { + options.collation(collation); + } + return options.limit(maxResults); } } diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactivePanacheUpdateImpl.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactivePanacheUpdateImpl.java similarity index 69% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactivePanacheUpdateImpl.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactivePanacheUpdateImpl.java index f8d0c502cc8ac..c380211a3edbe 100644 --- a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactivePanacheUpdateImpl.java +++ b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/reactive/runtime/ReactivePanacheUpdateImpl.java @@ -10,16 +10,12 @@ import io.quarkus.panache.common.Parameters; import io.smallrye.mutiny.Uni; -@SuppressWarnings({ "unchecked", "rawtypes" }) public class ReactivePanacheUpdateImpl implements ReactivePanacheUpdate { - private final ReactiveMongoOperations operations; - private final Class entityClass; - private final Bson update; - private final ReactiveMongoCollection collection; - - public ReactivePanacheUpdateImpl(ReactiveMongoOperations operations, Class entityClass, Bson update, - ReactiveMongoCollection collection) { - this.operations = operations; + private Class entityClass; + private Bson update; + private ReactiveMongoCollection collection; + + public ReactivePanacheUpdateImpl(Class entityClass, Bson update, ReactiveMongoCollection collection) { this.entityClass = entityClass; this.update = update; this.collection = collection; @@ -27,14 +23,14 @@ public ReactivePanacheUpdateImpl(ReactiveMongoOperations operations, Class en @Override public Uni where(String query, Object... params) { - String bindQuery = operations.bindFilter(entityClass, query, params); + String bindQuery = ReactiveMongoOperations.bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); return collection.updateMany(docQuery, update).map(result -> result.getModifiedCount()); } @Override public Uni where(String query, Map params) { - String bindQuery = operations.bindFilter(entityClass, query, params); + String bindQuery = ReactiveMongoOperations.bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); return collection.updateMany(docQuery, update).map(result -> result.getModifiedCount()); } diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/BeanUtils.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/BeanUtils.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/BeanUtils.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/BeanUtils.java diff --git a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/JavaMongoOperations.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/JavaMongoOperations.java deleted file mode 100644 index 94d48e4ddb9a0..0000000000000 --- a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/JavaMongoOperations.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.quarkus.mongodb.panache.runtime; - -import java.util.List; -import java.util.stream.Stream; - -import org.bson.Document; - -import com.mongodb.client.MongoCollection; - -import io.quarkus.mongodb.panache.PanacheQuery; -import io.quarkus.mongodb.panache.PanacheUpdate; - -public class JavaMongoOperations extends MongoOperations, PanacheUpdate> { - @Override - protected PanacheQuery createQuery(MongoCollection collection, Document query, Document sortDoc) { - return new PanacheQueryImpl(collection, query, sortDoc); - } - - @Override - protected PanacheUpdate createUpdate(MongoCollection collection, Class entityClass, Document docUpdate) { - return new PanacheUpdateImpl(this, entityClass, docUpdate, collection); - } - - @Override - protected List list(PanacheQuery query) { - return query.list(); - } - - @Override - protected Stream stream(PanacheQuery query) { - return query.stream(); - } -} diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoOperations.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoOperations.java similarity index 65% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoOperations.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoOperations.java index a2cc1e8782e25..f2ea88a7f344d 100644 --- a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoOperations.java +++ b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoOperations.java @@ -32,32 +32,28 @@ import com.mongodb.client.result.DeleteResult; import io.quarkus.mongodb.panache.MongoEntity; +import io.quarkus.mongodb.panache.PanacheQuery; +import io.quarkus.mongodb.panache.PanacheUpdate; import io.quarkus.mongodb.panache.binder.NativeQueryBinder; import io.quarkus.mongodb.panache.binder.PanacheQlQueryBinder; import io.quarkus.panache.common.Parameters; import io.quarkus.panache.common.Sort; -@SuppressWarnings({ "rawtypes", "unchecked" }) -public abstract class MongoOperations { - public final String ID = "_id"; +public class MongoOperations { private static final Logger LOGGER = Logger.getLogger(MongoOperations.class); + public static final String ID = "_id"; - private final Map defaultDatabaseName = new ConcurrentHashMap<>(); + private static final Map defaultDatabaseName = new ConcurrentHashMap<>(); - protected abstract QueryType createQuery(MongoCollection collection, Document query, Document sortDoc); - - protected abstract UpdateType createUpdate(MongoCollection collection, Class entityClass, Document docUpdate); - - protected abstract List list(QueryType queryType); - - protected abstract Stream stream(QueryType queryType); + // + // Instance methods - public void persist(Object entity) { + public static void persist(Object entity) { MongoCollection collection = mongoCollection(entity); persist(collection, entity); } - public void persist(Iterable entities) { + public static void persist(Iterable entities) { // not all iterables are re-traversal, so we traverse it once for copying inside a list List objects = new ArrayList<>(); for (Object entity : entities) { @@ -72,7 +68,7 @@ public void persist(Iterable entities) { } } - public void persist(Object firstEntity, Object... entities) { + public static void persist(Object firstEntity, Object... entities) { MongoCollection collection = mongoCollection(firstEntity); if (entities == null || entities.length == 0) { persist(collection, firstEntity); @@ -84,22 +80,22 @@ public void persist(Object firstEntity, Object... entities) { } } - public void persist(Stream entities) { + public static void persist(Stream entities) { List objects = entities.collect(Collectors.toList()); if (objects.size() > 0) { // get the first entity to be able to retrieve the collection with it Object firstEntity = objects.get(0); MongoCollection collection = mongoCollection(firstEntity); - update(collection, objects); + persist(collection, objects); } } - public void update(Object entity) { + public static void update(Object entity) { MongoCollection collection = mongoCollection(entity); update(collection, entity); } - public void update(Iterable entities) { + public static void update(Iterable entities) { // not all iterables are re-traversal, so we traverse it once for copying inside a list List objects = new ArrayList<>(); for (Object entity : entities) { @@ -114,7 +110,7 @@ public void update(Iterable entities) { } } - public void update(Object firstEntity, Object... entities) { + public static void update(Object firstEntity, Object... entities) { MongoCollection collection = mongoCollection(firstEntity); if (entities == null || entities.length == 0) { update(collection, firstEntity); @@ -126,7 +122,7 @@ public void update(Object firstEntity, Object... entities) { } } - public void update(Stream entities) { + public static void update(Stream entities) { List objects = entities.collect(Collectors.toList()); if (objects.size() > 0) { // get the first entity to be able to retrieve the collection with it @@ -136,12 +132,12 @@ public void update(Stream entities) { } } - public void persistOrUpdate(Object entity) { + public static void persistOrUpdate(Object entity) { MongoCollection collection = mongoCollection(entity); persistOrUpdate(collection, entity); } - public void persistOrUpdate(Iterable entities) { + public static void persistOrUpdate(Iterable entities) { // not all iterables are re-traversal, so we traverse it once for copying inside a list List objects = new ArrayList<>(); for (Object entity : entities) { @@ -156,7 +152,7 @@ public void persistOrUpdate(Iterable entities) { } } - public void persistOrUpdate(Object firstEntity, Object... entities) { + public static void persistOrUpdate(Object firstEntity, Object... entities) { MongoCollection collection = mongoCollection(firstEntity); if (entities == null || entities.length == 0) { persistOrUpdate(collection, firstEntity); @@ -168,7 +164,7 @@ public void persistOrUpdate(Object firstEntity, Object... entities) { } } - public void persistOrUpdate(Stream entities) { + public static void persistOrUpdate(Stream entities) { List objects = entities.collect(Collectors.toList()); if (objects.size() > 0) { // get the first entity to be able to retrieve the collection with it @@ -178,7 +174,7 @@ public void persistOrUpdate(Stream entities) { } } - public void delete(Object entity) { + public static void delete(Object entity) { MongoCollection collection = mongoCollection(entity); BsonDocument document = getBsonDocument(collection, entity); BsonValue id = document.get(ID); @@ -186,7 +182,7 @@ public void delete(Object entity) { collection.deleteOne(query); } - public MongoCollection mongoCollection(Class entityClass) { + public static MongoCollection mongoCollection(Class entityClass) { MongoEntity mongoEntity = entityClass.getAnnotation(MongoEntity.class); MongoDatabase database = mongoDatabase(mongoEntity); if (mongoEntity != null && !mongoEntity.collection().isEmpty()) { @@ -195,7 +191,7 @@ public MongoCollection mongoCollection(Class entityClass) { return database.getCollection(entityClass.getSimpleName(), entityClass); } - public MongoDatabase mongoDatabase(Class entityClass) { + public static MongoDatabase mongoDatabase(Class entityClass) { MongoEntity mongoEntity = entityClass.getAnnotation(MongoEntity.class); return mongoDatabase(mongoEntity); } @@ -203,15 +199,15 @@ public MongoDatabase mongoDatabase(Class entityClass) { // // Private stuff - private void persist(MongoCollection collection, Object entity) { + private static void persist(MongoCollection collection, Object entity) { collection.insertOne(entity); } - private void persist(MongoCollection collection, List entities) { + private static void persist(MongoCollection collection, List entities) { collection.insertMany(entities); } - private void update(MongoCollection collection, Object entity) { + private static void update(MongoCollection collection, Object entity) { //we transform the entity as a document first BsonDocument document = getBsonDocument(collection, entity); @@ -221,13 +217,13 @@ private void update(MongoCollection collection, Object entity) { collection.replaceOne(query, entity); } - private void update(MongoCollection collection, List entities) { + private static void update(MongoCollection collection, List entities) { for (Object entity : entities) { update(collection, entity); } } - private void persistOrUpdate(MongoCollection collection, Object entity) { + private static void persistOrUpdate(MongoCollection collection, Object entity) { //we transform the entity as a document first BsonDocument document = getBsonDocument(collection, entity); @@ -243,7 +239,7 @@ private void persistOrUpdate(MongoCollection collection, Object entity) { } } - private void persistOrUpdate(MongoCollection collection, List entities) { + private static void persistOrUpdate(MongoCollection collection, List entities) { //this will be an ordered bulk: it's less performant than a unordered one but will fail at the first failed write List bulk = new ArrayList<>(); for (Object entity : entities) { @@ -266,19 +262,19 @@ private void persistOrUpdate(MongoCollection collection, List entities) collection.bulkWrite(bulk); } - private BsonDocument getBsonDocument(MongoCollection collection, Object entity) { + private static BsonDocument getBsonDocument(MongoCollection collection, Object entity) { BsonDocument document = new BsonDocument(); Codec codec = collection.getCodecRegistry().get(entity.getClass()); codec.encode(new BsonDocumentWriter(document), entity, EncoderContext.builder().build()); return document; } - private MongoCollection mongoCollection(Object entity) { + private static MongoCollection mongoCollection(Object entity) { Class entityClass = entity.getClass(); return mongoCollection(entityClass); } - private MongoDatabase mongoDatabase(MongoEntity entity) { + private static MongoDatabase mongoDatabase(MongoEntity entity) { MongoClient mongoClient = clientFromArc(entity, MongoClient.class); if (entity != null && !entity.database().isEmpty()) { return mongoClient.getDatabase(entity.database()); @@ -287,7 +283,7 @@ private MongoDatabase mongoDatabase(MongoEntity entity) { return mongoClient.getDatabase(databaseName); } - private String getDefaultDatabaseName(MongoEntity entity) { + private static String getDefaultDatabaseName(MongoEntity entity) { return defaultDatabaseName.computeIfAbsent(beanName(entity), new Function() { @Override public String apply(String beanName) { @@ -295,36 +291,37 @@ public String apply(String beanName) { } }); } + // // Queries - public Object findById(Class entityClass, Object id) { + public static Object findById(Class entityClass, Object id) { MongoCollection collection = mongoCollection(entityClass); return collection.find(new Document(ID, id)).first(); } - public Optional findByIdOptional(Class entityClass, Object id) { + public static Optional findByIdOptional(Class entityClass, Object id) { return Optional.ofNullable(findById(entityClass, id)); } - public QueryType find(Class entityClass, String query, Object... params) { + public static PanacheQuery find(Class entityClass, String query, Object... params) { return find(entityClass, query, null, params); } @SuppressWarnings("rawtypes") - public QueryType find(Class entityClass, String query, Sort sort, Object... params) { + public static PanacheQuery find(Class entityClass, String query, Sort sort, Object... params) { String bindQuery = bindFilter(entityClass, query, params); - Document docQuery = Document.parse(bindQuery); + BsonDocument docQuery = BsonDocument.parse(bindQuery); Document docSort = sortToDocument(sort); MongoCollection collection = mongoCollection(entityClass); - return createQuery(collection, docQuery, docSort); + return new PanacheQueryImpl(collection, docQuery, docSort); } /** * We should have a query like {'firstname': ?1, 'lastname': ?2} for native one * and like firstname = ?1 for PanacheQL one. */ - public String bindFilter(Class clazz, String query, Object[] params) { + static String bindFilter(Class clazz, String query, Object[] params) { String bindQuery = bindQuery(clazz, query, params); LOGGER.debug(bindQuery); return bindQuery; @@ -334,7 +331,7 @@ public String bindFilter(Class clazz, String query, Object[] params) { * We should have a query like {'firstname': :firstname, 'lastname': :lastname} for native one * and like firstname = :firstname and lastname = :lastname for PanacheQL one. */ - public String bindFilter(Class clazz, String query, Map params) { + static String bindFilter(Class clazz, String query, Map params) { String bindQuery = bindQuery(clazz, query, params); LOGGER.debug(bindQuery); return bindQuery; @@ -345,7 +342,7 @@ public String bindFilter(Class clazz, String query, Map param * and like firstname = ?1 and lastname = ?2 for PanacheQL one. * As update document needs a $set operator we add it if needed. */ - String bindUpdate(Class clazz, String query, Object[] params) { + static String bindUpdate(Class clazz, String query, Object[] params) { String bindUpdate = bindQuery(clazz, query, params); if (!bindUpdate.contains("$set")) { bindUpdate = "{'$set':" + bindUpdate + "}"; @@ -359,7 +356,7 @@ String bindUpdate(Class clazz, String query, Object[] params) { * and like firstname = :firstname and lastname = :lastname for PanacheQL one. * As update document needs a $set operator we add it if needed. */ - String bindUpdate(Class clazz, String query, Map params) { + static String bindUpdate(Class clazz, String query, Map params) { String bindUpdate = bindQuery(clazz, query, params); if (!bindUpdate.contains("$set")) { bindUpdate = "{'$set':" + bindUpdate + "}"; @@ -368,7 +365,7 @@ String bindUpdate(Class clazz, String query, Map params) { return bindUpdate; } - private String bindQuery(Class clazz, String query, Object[] params) { + private static String bindQuery(Class clazz, String query, Object[] params) { String bindQuery = null; //determine the type of the query if (query.charAt(0) == '{') { @@ -381,7 +378,7 @@ private String bindQuery(Class clazz, String query, Object[] params) { return bindQuery; } - private String bindQuery(Class clazz, String query, Map params) { + private static String bindQuery(Class clazz, String query, Map params) { String bindQuery = null; //determine the type of the query if (query.charAt(0) == '{') { @@ -394,125 +391,125 @@ private String bindQuery(Class clazz, String query, Map param return bindQuery; } - public QueryType find(Class entityClass, String query, Map params) { + public static PanacheQuery find(Class entityClass, String query, Map params) { return find(entityClass, query, null, params); } @SuppressWarnings("rawtypes") - public QueryType find(Class entityClass, String query, Sort sort, Map params) { + public static PanacheQuery find(Class entityClass, String query, Sort sort, Map params) { String bindQuery = bindFilter(entityClass, query, params); - Document docQuery = Document.parse(bindQuery); + BsonDocument docQuery = BsonDocument.parse(bindQuery); Document docSort = sortToDocument(sort); MongoCollection collection = mongoCollection(entityClass); - return createQuery(collection, docQuery, docSort); + return new PanacheQueryImpl(collection, docQuery, docSort); } - public QueryType find(Class entityClass, String query, Parameters params) { + public static PanacheQuery find(Class entityClass, String query, Parameters params) { return find(entityClass, query, null, params.map()); } - public QueryType find(Class entityClass, String query, Sort sort, Parameters params) { + public static PanacheQuery find(Class entityClass, String query, Sort sort, Parameters params) { return find(entityClass, query, sort, params.map()); } @SuppressWarnings("rawtypes") - public QueryType find(Class entityClass, Document query, Sort sort) { + public static PanacheQuery find(Class entityClass, Document query, Sort sort) { MongoCollection collection = mongoCollection(entityClass); Document sortDoc = sortToDocument(sort); - return createQuery(collection, query, sortDoc); + return new PanacheQueryImpl(collection, query, sortDoc); } - public QueryType find(Class entityClass, Document query, Document sort) { + public static PanacheQuery find(Class entityClass, Document query, Document sort) { MongoCollection collection = mongoCollection(entityClass); - return createQuery(collection, query, sort); + return new PanacheQueryImpl(collection, query, sort); } - public QueryType find(Class entityClass, Document query) { + public static PanacheQuery find(Class entityClass, Document query) { return find(entityClass, query, (Document) null); } - public List list(Class entityClass, String query, Object... params) { - return list(find(entityClass, query, params)); + public static List list(Class entityClass, String query, Object... params) { + return find(entityClass, query, params).list(); } - public List list(Class entityClass, String query, Sort sort, Object... params) { - return list(find(entityClass, query, sort, params)); + public static List list(Class entityClass, String query, Sort sort, Object... params) { + return find(entityClass, query, sort, params).list(); } - public List list(Class entityClass, String query, Map params) { - return list(find(entityClass, query, params)); + public static List list(Class entityClass, String query, Map params) { + return find(entityClass, query, params).list(); } - public List list(Class entityClass, String query, Sort sort, Map params) { - return list(find(entityClass, query, sort, params)); + public static List list(Class entityClass, String query, Sort sort, Map params) { + return find(entityClass, query, sort, params).list(); } - public List list(Class entityClass, String query, Parameters params) { - return list(find(entityClass, query, params)); + public static List list(Class entityClass, String query, Parameters params) { + return find(entityClass, query, params).list(); } - public List list(Class entityClass, String query, Sort sort, Parameters params) { - return list(find(entityClass, query, sort, params)); + public static List list(Class entityClass, String query, Sort sort, Parameters params) { + return find(entityClass, query, sort, params).list(); } //specific Mongo query - public List list(Class entityClass, Document query) { - return list(find(entityClass, query)); + public static List list(Class entityClass, Document query) { + return find(entityClass, query).list(); } //specific Mongo query - public List list(Class entityClass, Document query, Document sort) { - return list(find(entityClass, query, sort)); + public static List list(Class entityClass, Document query, Document sort) { + return find(entityClass, query, sort).list(); } - public Stream stream(Class entityClass, String query, Object... params) { - return stream(find(entityClass, query, params)); + public static Stream stream(Class entityClass, String query, Object... params) { + return find(entityClass, query, params).stream(); } - public Stream stream(Class entityClass, String query, Sort sort, Object... params) { - return stream(find(entityClass, query, sort, params)); + public static Stream stream(Class entityClass, String query, Sort sort, Object... params) { + return find(entityClass, query, sort, params).stream(); } - public Stream stream(Class entityClass, String query, Map params) { - return stream(find(entityClass, query, params)); + public static Stream stream(Class entityClass, String query, Map params) { + return find(entityClass, query, params).stream(); } - public Stream stream(Class entityClass, String query, Sort sort, Map params) { - return stream(find(entityClass, query, sort, params)); + public static Stream stream(Class entityClass, String query, Sort sort, Map params) { + return find(entityClass, query, sort, params).stream(); } - public Stream stream(Class entityClass, String query, Parameters params) { - return stream(find(entityClass, query, params)); + public static Stream stream(Class entityClass, String query, Parameters params) { + return find(entityClass, query, params).stream(); } - public Stream stream(Class entityClass, String query, Sort sort, Parameters params) { - return stream(find(entityClass, query, sort, params)); + public static Stream stream(Class entityClass, String query, Sort sort, Parameters params) { + return find(entityClass, query, sort, params).stream(); } //specific Mongo query - public Stream stream(Class entityClass, Document query) { - return stream(find(entityClass, query)); + public static Stream stream(Class entityClass, Document query) { + return find(entityClass, query).stream(); } //specific Mongo query - public Stream stream(Class entityClass, Document query, Document sort) { - return stream(find(entityClass, query, sort)); + public static Stream stream(Class entityClass, Document query, Document sort) { + return find(entityClass, query, sort).stream(); } @SuppressWarnings("rawtypes") - public QueryType findAll(Class entityClass) { + public static PanacheQuery findAll(Class entityClass) { MongoCollection collection = mongoCollection(entityClass); - return createQuery(collection, null, null); + return new PanacheQueryImpl(collection, null, null); } @SuppressWarnings("rawtypes") - public QueryType findAll(Class entityClass, Sort sort) { + public static PanacheQuery findAll(Class entityClass, Sort sort) { MongoCollection collection = mongoCollection(entityClass); Document sortDoc = sortToDocument(sort); - return createQuery(collection, null, sortDoc); + return new PanacheQueryImpl(collection, null, sortDoc); } - private Document sortToDocument(Sort sort) { + private static Document sortToDocument(Sort sort) { if (sort == null) { return null; } @@ -524,112 +521,114 @@ private Document sortToDocument(Sort sort) { return sortDoc; } - public List listAll(Class entityClass) { - return list(findAll(entityClass)); + public static List listAll(Class entityClass) { + return findAll(entityClass).list(); } - public List listAll(Class entityClass, Sort sort) { - return list(findAll(entityClass, sort)); + public static List listAll(Class entityClass, Sort sort) { + return findAll(entityClass, sort).list(); } - public Stream streamAll(Class entityClass) { - return stream(findAll(entityClass)); + public static Stream streamAll(Class entityClass) { + return findAll(entityClass).stream(); } - public Stream streamAll(Class entityClass, Sort sort) { - return stream(findAll(entityClass, sort)); + public static Stream streamAll(Class entityClass, Sort sort) { + return findAll(entityClass, sort).stream(); } - public long count(Class entityClass) { + public static long count(Class entityClass) { MongoCollection collection = mongoCollection(entityClass); return collection.countDocuments(); } - public long count(Class entityClass, String query, Object... params) { + public static long count(Class entityClass, String query, Object... params) { String bindQuery = bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); MongoCollection collection = mongoCollection(entityClass); return collection.countDocuments(docQuery); } - public long count(Class entityClass, String query, Map params) { + public static long count(Class entityClass, String query, Map params) { String bindQuery = bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); MongoCollection collection = mongoCollection(entityClass); return collection.countDocuments(docQuery); } - public long count(Class entityClass, String query, Parameters params) { + public static long count(Class entityClass, String query, Parameters params) { return count(entityClass, query, params.map()); } //specific Mongo query - public long count(Class entityClass, Document query) { + public static long count(Class entityClass, Document query) { MongoCollection collection = mongoCollection(entityClass); return collection.countDocuments(query); } - public long deleteAll(Class entityClass) { + public static long deleteAll(Class entityClass) { MongoCollection collection = mongoCollection(entityClass); return collection.deleteMany(new Document()).getDeletedCount(); } - public boolean deleteById(Class entityClass, Object id) { + public static boolean deleteById(Class entityClass, Object id) { MongoCollection collection = mongoCollection(entityClass); Document query = new Document().append(ID, id); DeleteResult results = collection.deleteOne(query); return results.getDeletedCount() == 1; } - public long delete(Class entityClass, String query, Object... params) { + public static long delete(Class entityClass, String query, Object... params) { String bindQuery = bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); MongoCollection collection = mongoCollection(entityClass); return collection.deleteMany(docQuery).getDeletedCount(); } - public long delete(Class entityClass, String query, Map params) { + public static long delete(Class entityClass, String query, Map params) { String bindQuery = bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); MongoCollection collection = mongoCollection(entityClass); return collection.deleteMany(docQuery).getDeletedCount(); } - public long delete(Class entityClass, String query, Parameters params) { + public static long delete(Class entityClass, String query, Parameters params) { return delete(entityClass, query, params.map()); } //specific Mongo query - public long delete(Class entityClass, Document query) { + public static long delete(Class entityClass, Document query) { MongoCollection collection = mongoCollection(entityClass); return collection.deleteMany(query).getDeletedCount(); } - public UpdateType update(Class entityClass, String update, Map params) { + public static PanacheUpdate update(Class entityClass, String update, Map params) { return executeUpdate(entityClass, update, params); } - public UpdateType update(Class entityClass, String update, Parameters params) { + public static PanacheUpdate update(Class entityClass, String update, Parameters params) { return update(entityClass, update, params.map()); } - public UpdateType update(Class entityClass, String update, Object... params) { + public static PanacheUpdate update(Class entityClass, String update, Object... params) { return executeUpdate(entityClass, update, params); } - private UpdateType executeUpdate(Class entityClass, String update, Object... params) { + private static PanacheUpdate executeUpdate(Class entityClass, String update, Object... params) { String bindUpdate = bindUpdate(entityClass, update, params); - Document docUpdate = Document.parse(bindUpdate); - return createUpdate(mongoCollection(entityClass), entityClass, docUpdate); + BsonDocument docUpdate = BsonDocument.parse(bindUpdate); + MongoCollection collection = mongoCollection(entityClass); + return new PanacheUpdateImpl(entityClass, docUpdate, collection); } - private UpdateType executeUpdate(Class entityClass, String update, Map params) { + private static PanacheUpdate executeUpdate(Class entityClass, String update, Map params) { String bindUpdate = bindUpdate(entityClass, update, params); - Document docUpdate = Document.parse(bindUpdate); - return createUpdate(mongoCollection(entityClass), entityClass, docUpdate); + BsonDocument docUpdate = BsonDocument.parse(bindUpdate); + MongoCollection collection = mongoCollection(entityClass); + return new PanacheUpdateImpl(entityClass, docUpdate, collection); } - public IllegalStateException implementationInjectionMissing() { + public static IllegalStateException implementationInjectionMissing() { return new IllegalStateException( "This method is normally automatically overridden in subclasses"); } diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoPropertyUtil.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoPropertyUtil.java similarity index 100% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoPropertyUtil.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/MongoPropertyUtil.java diff --git a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/PanacheQueryImpl.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/PanacheQueryImpl.java index bd32897123034..63bcc519a788a 100644 --- a/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/PanacheQueryImpl.java +++ b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/PanacheQueryImpl.java @@ -1,136 +1,252 @@ package io.quarkus.mongodb.panache.runtime; +import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.stream.Stream; +import org.bson.Document; import org.bson.conversions.Bson; +import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoCursor; import com.mongodb.client.model.Collation; import io.quarkus.mongodb.panache.PanacheQuery; import io.quarkus.panache.common.Page; +import io.quarkus.panache.common.Range; +import io.quarkus.panache.common.exception.PanacheQueryException; public class PanacheQueryImpl implements PanacheQuery { - private final CommonPanacheQueryImpl delegate; + private MongoCollection collection; + private Bson mongoQuery; + private Bson sort; + private Bson projections; + + private Page page; + private Long count; + + private Range range; + + private Collation collation; PanacheQueryImpl(MongoCollection collection, Bson mongoQuery, Bson sort) { - this.delegate = new CommonPanacheQueryImpl<>(collection, mongoQuery, sort); + this.collection = collection; + this.mongoQuery = mongoQuery; + this.sort = sort; } - private PanacheQueryImpl(CommonPanacheQueryImpl delegate) { - this.delegate = delegate; + private PanacheQueryImpl(PanacheQueryImpl previousQuery, Bson projections, Class documentClass) { + this.collection = previousQuery.collection.withDocumentClass(documentClass); + this.mongoQuery = previousQuery.mongoQuery; + this.sort = previousQuery.sort; + this.projections = projections; + this.page = previousQuery.page; + this.count = previousQuery.count; + this.range = previousQuery.range; + this.collation = previousQuery.collation; } + // Builder + @Override public PanacheQuery project(Class type) { - return new PanacheQueryImpl<>(delegate.project(type)); + // collect field names from public fields and getters + Set fieldNames = MongoPropertyUtil.collectFields(type); + + // create the projection document + Document projections = new Document(); + for (String fieldName : fieldNames) { + projections.append(fieldName, 1); + } + + return new PanacheQueryImpl<>(this, projections, type); } @Override @SuppressWarnings("unchecked") public PanacheQuery page(Page page) { - delegate.page(page); + this.page = page; + this.range = null; // reset the range to be able to switch from range to page return (PanacheQuery) this; } @Override public PanacheQuery page(int pageIndex, int pageSize) { - delegate.page(Page.of(pageIndex, pageSize)); - return (PanacheQuery) this; + return page(Page.of(pageIndex, pageSize)); } @Override public PanacheQuery nextPage() { - delegate.nextPage(); - return (PanacheQuery) this; + checkPagination(); + return page(page.next()); } @Override public PanacheQuery previousPage() { - delegate.previousPage(); - return (PanacheQuery) this; + checkPagination(); + return page(page.previous()); } @Override public PanacheQuery firstPage() { - delegate.firstPage(); - return (PanacheQuery) this; + checkPagination(); + return page(page.first()); } @Override public PanacheQuery lastPage() { - delegate.lastPage(); - return (PanacheQuery) this; + checkPagination(); + return page(page.index(pageCount() - 1)); } @Override public boolean hasNextPage() { - return delegate.hasNextPage(); + checkPagination(); + return page.index < (pageCount() - 1); } @Override public boolean hasPreviousPage() { - return delegate.hasPreviousPage(); + checkPagination(); + return page.index > 0; } @Override public int pageCount() { - return delegate.pageCount(); + checkPagination(); + long count = count(); + if (count == 0) + return 1; // a single page of zero results + return (int) Math.ceil((double) count / (double) page.size); } @Override public Page page() { - return delegate.page(); + checkPagination(); + return page; + } + + private void checkPagination() { + if (page == null) { + throw new UnsupportedOperationException( + "Cannot call a page related method, " + + "call page(Page) or page(int, int) to initiate pagination first"); + } + if (range != null) { + throw new UnsupportedOperationException("Cannot call a page related method in a ranged query, " + + "call page(Page) or page(int, int) to initiate pagination first"); + } } @Override public PanacheQuery range(int startIndex, int lastIndex) { - delegate.range(startIndex, lastIndex); + this.range = Range.of(startIndex, lastIndex); + // reset the page to its default to be able to switch from page to range + this.page = null; return (PanacheQuery) this; } @Override public PanacheQuery withCollation(Collation collation) { - delegate.withCollation(collation); + this.collation = collation; return (PanacheQuery) this; } // Results @Override + @SuppressWarnings("unchecked") public long count() { - return delegate.count(); + if (count == null) { + count = collection.countDocuments(mongoQuery); + } + return count; } @Override public List list() { - return delegate.list(); + return list(null); + } + + @SuppressWarnings("unchecked") + private List list(Integer limit) { + List list = new ArrayList<>(); + FindIterable find = mongoQuery == null ? collection.find() : collection.find(mongoQuery); + if (this.projections != null) { + find.projection(projections); + } + if (this.collation != null) { + find.collation(collation); + } + manageOffsets(find, limit); + MongoCursor cursor = find.sort(sort).iterator(); + + try { + while (cursor.hasNext()) { + T entity = cursor.next(); + list.add(entity); + } + } finally { + cursor.close(); + } + return list; } @Override + @SuppressWarnings("unchecked") public Stream stream() { - return delegate.stream(); + return (Stream) list().stream(); } @Override public T firstResult() { - return delegate.firstResult(); + List list = list(1); + return list.isEmpty() ? null : list.get(0); } @Override public Optional firstResultOptional() { - return delegate.firstResultOptional(); + return Optional.ofNullable(firstResult()); } @Override public T singleResult() { - return delegate.singleResult(); + List list = list(2); + if (list.size() != 1) { + throw new PanacheQueryException("There should be only one result"); + } + + return list.get(0); } @Override public Optional singleResultOptional() { - return delegate.singleResultOptional(); + List list = list(2); + if (list.size() > 1) { + throw new PanacheQueryException("There should be no more than one result"); + } + + return list.isEmpty() ? Optional.empty() : Optional.of(list.get(0)); + } + + private void manageOffsets(FindIterable find, Integer limit) { + if (range != null) { + find.skip(range.getStartIndex()); + if (limit == null) { + // range is 0 based, so we add 1 to the limit + find.limit(range.getLastIndex() - range.getStartIndex() + 1); + } + } else if (page != null) { + find.skip(page.index * page.size); + if (limit == null) { + find.limit(page.size); + } + } + if (limit != null) { + find.limit(limit); + } } } diff --git a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/PanacheUpdateImpl.java b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/PanacheUpdateImpl.java similarity index 77% rename from extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/PanacheUpdateImpl.java rename to extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/PanacheUpdateImpl.java index 1cf9e9d7bfac6..effeae31cdbb5 100644 --- a/extensions/panache/mongodb-panache-common/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/PanacheUpdateImpl.java +++ b/extensions/panache/mongodb-panache/runtime/src/main/java/io/quarkus/mongodb/panache/runtime/PanacheUpdateImpl.java @@ -11,13 +11,11 @@ import io.quarkus.panache.common.Parameters; public class PanacheUpdateImpl implements PanacheUpdate { - private MongoOperations operations; private Class entityClass; private Bson update; private MongoCollection collection; - public PanacheUpdateImpl(MongoOperations operations, Class entityClass, Bson update, MongoCollection collection) { - this.operations = operations; + public PanacheUpdateImpl(Class entityClass, Bson update, MongoCollection collection) { this.entityClass = entityClass; this.update = update; this.collection = collection; @@ -25,14 +23,14 @@ public PanacheUpdateImpl(MongoOperations operations, Class entityClass, Bson @Override public long where(String query, Object... params) { - String bindQuery = operations.bindFilter(entityClass, query, params); + String bindQuery = MongoOperations.bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); return collection.updateMany(docQuery, update).getModifiedCount(); } @Override public long where(String query, Map params) { - String bindQuery = operations.bindFilter(entityClass, query, params); + String bindQuery = MongoOperations.bindFilter(entityClass, query, params); BsonDocument docQuery = BsonDocument.parse(bindQuery); return collection.updateMany(docQuery, update).getModifiedCount(); } diff --git a/extensions/panache/mongodb-panache/runtime/src/test/java/io/quarkus/mongodb/panache/runtime/MongoOperationsTest.java b/extensions/panache/mongodb-panache/runtime/src/test/java/io/quarkus/mongodb/panache/runtime/MongoOperationsTest.java index 2016dc4e05cde..03cefbed12cbe 100644 --- a/extensions/panache/mongodb-panache/runtime/src/test/java/io/quarkus/mongodb/panache/runtime/MongoOperationsTest.java +++ b/extensions/panache/mongodb-panache/runtime/src/test/java/io/quarkus/mongodb/panache/runtime/MongoOperationsTest.java @@ -22,8 +22,6 @@ class MongoOperationsTest { - private final MongoOperations operations = new JavaMongoOperations(); - private static class DemoObj { public String field; public boolean isOk; @@ -43,32 +41,32 @@ static void setupFieldReplacement() { @Test public void testBindShorthandFilter() { - String query = operations.bindFilter(Object.class, "field", new Object[] { "a value" }); + String query = MongoOperations.bindFilter(Object.class, "field", new Object[] { "a value" }); assertEquals("{'field':'a value'}", query); - query = operations.bindFilter(Object.class, "field", new Object[] { true }); + query = MongoOperations.bindFilter(Object.class, "field", new Object[] { true }); assertEquals("{'field':true}", query); - query = operations.bindFilter(Object.class, "field", new Object[] { LocalDate.of(2019, 3, 4) }); + query = MongoOperations.bindFilter(Object.class, "field", new Object[] { LocalDate.of(2019, 3, 4) }); assertEquals("{'field':ISODate('2019-03-04')}", query); - query = operations.bindFilter(Object.class, "field", new Object[] { LocalDateTime.of(2019, 3, 4, 1, 1, 1) }); + query = MongoOperations.bindFilter(Object.class, "field", new Object[] { LocalDateTime.of(2019, 3, 4, 1, 1, 1) }); assertEquals("{'field':ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "field", + query = MongoOperations.bindFilter(Object.class, "field", new Object[] { LocalDateTime.of(2019, 3, 4, 1, 1, 1).toInstant(ZoneOffset.UTC) }); assertEquals("{'field':ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "field", + query = MongoOperations.bindFilter(Object.class, "field", new Object[] { toDate(LocalDateTime.of(2019, 3, 4, 1, 1, 1)) }); assertEquals("{'field':ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "field", + query = MongoOperations.bindFilter(Object.class, "field", new Object[] { UUID.fromString("7f000101-7370-1f68-8173-70afa71b0000") }); assertEquals("{'field':UUID('7f000101-7370-1f68-8173-70afa71b0000')}", query); //test field replacement - query = operations.bindFilter(DemoObj.class, "property", new Object[] { "a value" }); + query = MongoOperations.bindFilter(DemoObj.class, "property", new Object[] { "a value" }); assertEquals("{'value':'a value'}", query); } @@ -78,53 +76,53 @@ private Object toDate(LocalDateTime of) { @Test public void testBindNativeFilterByIndex() { - String query = operations.bindFilter(DemoObj.class, "{'field': ?1}", new Object[] { "a value" }); + String query = MongoOperations.bindFilter(DemoObj.class, "{'field': ?1}", new Object[] { "a value" }); assertEquals("{'field': 'a value'}", query); - query = operations.bindFilter(DemoObj.class, "{'field.sub': ?1}", new Object[] { "a value" }); + query = MongoOperations.bindFilter(DemoObj.class, "{'field.sub': ?1}", new Object[] { "a value" }); assertEquals("{'field.sub': 'a value'}", query); //test that there are no field replacement for native queries - query = operations.bindFilter(DemoObj.class, "{'property': ?1}", new Object[] { "a value" }); + query = MongoOperations.bindFilter(DemoObj.class, "{'property': ?1}", new Object[] { "a value" }); assertEquals("{'property': 'a value'}", query); - query = operations.bindFilter(Object.class, "{'field': ?1}", + query = MongoOperations.bindFilter(Object.class, "{'field': ?1}", new Object[] { LocalDate.of(2019, 3, 4) }); assertEquals("{'field': ISODate('2019-03-04')}", query); - query = operations.bindFilter(Object.class, "{'field': ?1}", + query = MongoOperations.bindFilter(Object.class, "{'field': ?1}", new Object[] { LocalDateTime.of(2019, 3, 4, 1, 1, 1) }); assertEquals("{'field': ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "{'field': ?1}", + query = MongoOperations.bindFilter(Object.class, "{'field': ?1}", new Object[] { LocalDateTime.of(2019, 3, 4, 1, 1, 1).toInstant(ZoneOffset.UTC) }); assertEquals("{'field': ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "{'field': ?1}", + query = MongoOperations.bindFilter(Object.class, "{'field': ?1}", new Object[] { toDate(LocalDateTime.of(2019, 3, 4, 1, 1, 1)) }); assertEquals("{'field': ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "{'field': ?1}", + query = MongoOperations.bindFilter(Object.class, "{'field': ?1}", new Object[] { UUID.fromString("7f000101-7370-1f68-8173-70afa71b0000") }); assertEquals("{'field': UUID('7f000101-7370-1f68-8173-70afa71b0000')}", query); - query = operations.bindFilter(Object.class, "{'field': ?1, 'isOk': ?2}", new Object[] { "a value", true }); + query = MongoOperations.bindFilter(Object.class, "{'field': ?1, 'isOk': ?2}", new Object[] { "a value", true }); assertEquals("{'field': 'a value', 'isOk': true}", query); //queries related to '$in' operator List list = Arrays.asList("f1", "f2"); - query = operations.bindFilter(DemoObj.class, "{ field: { '$in': [?1] } }", new Object[] { list }); + query = MongoOperations.bindFilter(DemoObj.class, "{ field: { '$in': [?1] } }", new Object[] { list }); assertEquals("{ field: { '$in': ['f1', 'f2'] } }", query); - query = operations.bindFilter(DemoObj.class, "{ field: { '$in': [?1] }, isOk: ?2 }", new Object[] { list, true }); + query = MongoOperations.bindFilter(DemoObj.class, "{ field: { '$in': [?1] }, isOk: ?2 }", new Object[] { list, true }); assertEquals("{ field: { '$in': ['f1', 'f2'] }, isOk: true }", query); - query = operations.bindFilter(DemoObj.class, + query = MongoOperations.bindFilter(DemoObj.class, "{ field: { '$in': [?1] }, $or: [ {'property': ?2}, {'property': ?3} ] }", new Object[] { list, "jpg", "gif" }); assertEquals("{ field: { '$in': ['f1', 'f2'] }, $or: [ {'property': 'jpg'}, {'property': 'gif'} ] }", query); - query = operations.bindFilter(DemoObj.class, + query = MongoOperations.bindFilter(DemoObj.class, "{ field: { '$in': [?1] }, isOk: ?2, $or: [ {'property': ?3}, {'property': ?4} ] }", new Object[] { list, true, "jpg", "gif" }); assertEquals("{ field: { '$in': ['f1', 'f2'] }, isOk: true, $or: [ {'property': 'jpg'}, {'property': 'gif'} ] }", @@ -133,59 +131,59 @@ public void testBindNativeFilterByIndex() { @Test public void testBindNativeFilterByName() { - String query = operations.bindFilter(Object.class, "{'field': :field}", + String query = MongoOperations.bindFilter(Object.class, "{'field': :field}", Parameters.with("field", "a value").map()); assertEquals("{'field': 'a value'}", query); - query = operations.bindFilter(Object.class, "{'field.sub': :field}", + query = MongoOperations.bindFilter(Object.class, "{'field.sub': :field}", Parameters.with("field", "a value").map()); assertEquals("{'field.sub': 'a value'}", query); //test that there are no field replacement for native queries - query = operations.bindFilter(DemoObj.class, "{'property': :field}", + query = MongoOperations.bindFilter(DemoObj.class, "{'property': :field}", Parameters.with("field", "a value").map()); assertEquals("{'property': 'a value'}", query); - query = operations.bindFilter(Object.class, "{'field': :field}", + query = MongoOperations.bindFilter(Object.class, "{'field': :field}", Parameters.with("field", LocalDate.of(2019, 3, 4)).map()); assertEquals("{'field': ISODate('2019-03-04')}", query); - query = operations.bindFilter(Object.class, "{'field': :field}", + query = MongoOperations.bindFilter(Object.class, "{'field': :field}", Parameters.with("field", LocalDateTime.of(2019, 3, 4, 1, 1, 1)).map()); assertEquals("{'field': ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "{'field': :field}", + query = MongoOperations.bindFilter(Object.class, "{'field': :field}", Parameters.with("field", LocalDateTime.of(2019, 3, 4, 1, 1, 1).toInstant(ZoneOffset.UTC)).map()); assertEquals("{'field': ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "{'field': :field}", + query = MongoOperations.bindFilter(Object.class, "{'field': :field}", Parameters.with("field", toDate(LocalDateTime.of(2019, 3, 4, 1, 1, 1))).map()); assertEquals("{'field': ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "{'field': :field}", + query = MongoOperations.bindFilter(Object.class, "{'field': :field}", Parameters.with("field", UUID.fromString("7f000101-7370-1f68-8173-70afa71b0000")).map()); assertEquals("{'field': UUID('7f000101-7370-1f68-8173-70afa71b0000')}", query); - query = operations.bindFilter(Object.class, "{'field': :field, 'isOk': :isOk}", + query = MongoOperations.bindFilter(Object.class, "{'field': :field, 'isOk': :isOk}", Parameters.with("field", "a value").and("isOk", true).map()); assertEquals("{'field': 'a value', 'isOk': true}", query); //queries related to '$in' operator List ids = Arrays.asList("f1", "f2"); - query = operations.bindFilter(DemoObj.class, "{ field: { '$in': [:fields] } }", + query = MongoOperations.bindFilter(DemoObj.class, "{ field: { '$in': [:fields] } }", Parameters.with("fields", ids).map()); assertEquals("{ field: { '$in': ['f1', 'f2'] } }", query); - query = operations.bindFilter(DemoObj.class, "{ field: { '$in': [:fields] }, isOk: :isOk }", + query = MongoOperations.bindFilter(DemoObj.class, "{ field: { '$in': [:fields] }, isOk: :isOk }", Parameters.with("fields", ids).and("isOk", true).map()); assertEquals("{ field: { '$in': ['f1', 'f2'] }, isOk: true }", query); - query = operations.bindFilter(DemoObj.class, + query = MongoOperations.bindFilter(DemoObj.class, "{ field: { '$in': [:fields] }, $or: [ {'property': :p1}, {'property': :p2} ] }", Parameters.with("fields", ids).and("p1", "jpg").and("p2", "gif").map()); assertEquals("{ field: { '$in': ['f1', 'f2'] }, $or: [ {'property': 'jpg'}, {'property': 'gif'} ] }", query); - query = operations.bindFilter(DemoObj.class, + query = MongoOperations.bindFilter(DemoObj.class, "{ field: { '$in': [:fields] }, isOk: :isOk, $or: [ {'property': :p1}, {'property': :p2} ] }", Parameters.with("fields", ids) .and("isOk", true) @@ -197,74 +195,74 @@ public void testBindNativeFilterByName() { @Test public void testBindEnhancedFilterByIndex() { - String query = operations.bindFilter(Object.class, "field = ?1", new Object[] { "a value" }); + String query = MongoOperations.bindFilter(Object.class, "field = ?1", new Object[] { "a value" }); assertEquals("{'field':'a value'}", query); - query = operations.bindFilter(Object.class, "{'field.sub': :field}", + query = MongoOperations.bindFilter(Object.class, "{'field.sub': :field}", Parameters.with("field", "a value").map()); assertEquals("{'field.sub': 'a value'}", query); //test field replacement - query = operations.bindFilter(DemoObj.class, "property = ?1", new Object[] { "a value" }); + query = MongoOperations.bindFilter(DemoObj.class, "property = ?1", new Object[] { "a value" }); assertEquals("{'value':'a value'}", query); - query = operations.bindFilter(Object.class, "field = ?1", new Object[] { LocalDate.of(2019, 3, 4) }); + query = MongoOperations.bindFilter(Object.class, "field = ?1", new Object[] { LocalDate.of(2019, 3, 4) }); assertEquals("{'field':ISODate('2019-03-04')}", query); - query = operations.bindFilter(Object.class, "field = ?1", new Object[] { LocalDateTime.of(2019, 3, 4, 1, 1, 1) }); + query = MongoOperations.bindFilter(Object.class, "field = ?1", new Object[] { LocalDateTime.of(2019, 3, 4, 1, 1, 1) }); assertEquals("{'field':ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "field = ?1", + query = MongoOperations.bindFilter(Object.class, "field = ?1", new Object[] { LocalDateTime.of(2019, 3, 4, 1, 1, 1).toInstant(ZoneOffset.UTC) }); assertEquals("{'field':ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "field = ?1", + query = MongoOperations.bindFilter(Object.class, "field = ?1", new Object[] { toDate(LocalDateTime.of(2019, 3, 4, 1, 1, 1)) }); assertEquals("{'field':ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "field = ?1", + query = MongoOperations.bindFilter(Object.class, "field = ?1", new Object[] { UUID.fromString("7f000101-7370-1f68-8173-70afa71b0000") }); assertEquals("{'field':UUID('7f000101-7370-1f68-8173-70afa71b0000')}", query); - query = operations.bindFilter(Object.class, "field = ?1 and isOk = ?2", new Object[] { "a value", true }); + query = MongoOperations.bindFilter(Object.class, "field = ?1 and isOk = ?2", new Object[] { "a value", true }); assertEquals("{'field':'a value','isOk':true}", query); - query = operations.bindFilter(Object.class, "field = ?1 or isOk = ?2", new Object[] { "a value", true }); + query = MongoOperations.bindFilter(Object.class, "field = ?1 or isOk = ?2", new Object[] { "a value", true }); assertEquals("{'$or':[{'field':'a value'},{'isOk':true}]}", query); - query = operations.bindFilter(Object.class, "count >= ?1 and count < ?2", new Object[] { 5, 10 }); + query = MongoOperations.bindFilter(Object.class, "count >= ?1 and count < ?2", new Object[] { 5, 10 }); assertEquals("{'count':{'$gte':5},'count':{'$lt':10}}", query); - query = operations.bindFilter(Object.class, "field != ?1", new Object[] { "a value" }); + query = MongoOperations.bindFilter(Object.class, "field != ?1", new Object[] { "a value" }); assertEquals("{'field':{'$ne':'a value'}}", query); - query = operations.bindFilter(Object.class, "field like ?1", new Object[] { "a value" }); + query = MongoOperations.bindFilter(Object.class, "field like ?1", new Object[] { "a value" }); assertEquals("{'field':{'$regex':'a value'}}", query); - query = operations.bindFilter(Object.class, "field is not null", new Object[] {}); + query = MongoOperations.bindFilter(Object.class, "field is not null", new Object[] {}); assertEquals("{'field':{'$exists':true}}", query); - query = operations.bindFilter(Object.class, "field is null", new Object[] {}); + query = MongoOperations.bindFilter(Object.class, "field is null", new Object[] {}); assertEquals("{'field':{'$exists':false}}", query); // test with hardcoded value - query = operations.bindFilter(Object.class, "field = 'some hardcoded value'", new Object[] {}); + query = MongoOperations.bindFilter(Object.class, "field = 'some hardcoded value'", new Object[] {}); assertEquals("{'field':'some hardcoded value'}", query); //queries related to '$in' operator List list = Arrays.asList("f1", "f2"); - query = operations.bindFilter(DemoObj.class, "field in ?1", new Object[] { list }); + query = MongoOperations.bindFilter(DemoObj.class, "field in ?1", new Object[] { list }); assertEquals("{'field':{'$in':['f1', 'f2']}}", query); - query = operations.bindFilter(DemoObj.class, "field in ?1 and isOk = ?2", new Object[] { list, true }); + query = MongoOperations.bindFilter(DemoObj.class, "field in ?1 and isOk = ?2", new Object[] { list, true }); assertEquals("{'field':{'$in':['f1', 'f2']},'isOk':true}", query); - query = operations.bindFilter(DemoObj.class, + query = MongoOperations.bindFilter(DemoObj.class, "field in ?1 and property = ?2 or property = ?3", new Object[] { list, "jpg", "gif" }); assertEquals("{'field':{'$in':['f1', 'f2']},'$or':[{'value':'jpg'},{'value':'gif'}]}", query); - query = operations.bindFilter(DemoObj.class, + query = MongoOperations.bindFilter(DemoObj.class, "field in ?1 and isOk = ?2 and property = ?3 or property = ?4", new Object[] { list, true, "jpg", "gif" }); assertEquals("{'field':{'$in':['f1', 'f2']},'isOk':true,'$or':[{'value':'jpg'},{'value':'gif'}]}", query); @@ -272,75 +270,75 @@ public void testBindEnhancedFilterByIndex() { @Test public void testBindEnhancedFilterByName() { - String query = operations.bindFilter(Object.class, "field = :field", + String query = MongoOperations.bindFilter(Object.class, "field = :field", Parameters.with("field", "a value").map()); assertEquals("{'field':'a value'}", query); - query = operations.bindFilter(Object.class, "field.sub = :field", + query = MongoOperations.bindFilter(Object.class, "field.sub = :field", Parameters.with("field", "a value").map()); assertEquals("{'field.sub':'a value'}", query); //test field replacement - query = operations.bindFilter(DemoObj.class, "property = :field", + query = MongoOperations.bindFilter(DemoObj.class, "property = :field", Parameters.with("field", "a value").map()); assertEquals("{'value':'a value'}", query); - query = operations.bindFilter(Object.class, "field = :field", + query = MongoOperations.bindFilter(Object.class, "field = :field", Parameters.with("field", LocalDate.of(2019, 3, 4)).map()); assertEquals("{'field':ISODate('2019-03-04')}", query); - query = operations.bindFilter(Object.class, "field = :field", + query = MongoOperations.bindFilter(Object.class, "field = :field", Parameters.with("field", LocalDateTime.of(2019, 3, 4, 1, 1, 1)).map()); assertEquals("{'field':ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "field = :field", + query = MongoOperations.bindFilter(Object.class, "field = :field", Parameters.with("field", LocalDateTime.of(2019, 3, 4, 1, 1, 1).toInstant(ZoneOffset.UTC)).map()); assertEquals("{'field':ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "field = :field", + query = MongoOperations.bindFilter(Object.class, "field = :field", Parameters.with("field", toDate(LocalDateTime.of(2019, 3, 4, 1, 1, 1))).map()); assertEquals("{'field':ISODate('2019-03-04T01:01:01.000Z')}", query); - query = operations.bindFilter(Object.class, "field = :field", + query = MongoOperations.bindFilter(Object.class, "field = :field", Parameters.with("field", UUID.fromString("7f000101-7370-1f68-8173-70afa71b0000")).map()); assertEquals("{'field':UUID('7f000101-7370-1f68-8173-70afa71b0000')}", query); - query = operations.bindFilter(Object.class, "field = :field and isOk = :isOk", + query = MongoOperations.bindFilter(Object.class, "field = :field and isOk = :isOk", Parameters.with("field", "a value").and("isOk", true).map()); assertEquals("{'field':'a value','isOk':true}", query); - query = operations.bindFilter(Object.class, "field = :field or isOk = :isOk", + query = MongoOperations.bindFilter(Object.class, "field = :field or isOk = :isOk", Parameters.with("field", "a value").and("isOk", true).map()); assertEquals("{'$or':[{'field':'a value'},{'isOk':true}]}", query); - query = operations.bindFilter(Object.class, "count > :lower and count <= :upper", + query = MongoOperations.bindFilter(Object.class, "count > :lower and count <= :upper", Parameters.with("lower", 5).and("upper", 10).map()); assertEquals("{'count':{'$gt':5},'count':{'$lte':10}}", query); - query = operations.bindFilter(Object.class, "field != :field", + query = MongoOperations.bindFilter(Object.class, "field != :field", Parameters.with("field", "a value").map()); assertEquals("{'field':{'$ne':'a value'}}", query); - query = operations.bindFilter(Object.class, "field like :field", + query = MongoOperations.bindFilter(Object.class, "field like :field", Parameters.with("field", "a value").map()); assertEquals("{'field':{'$regex':'a value'}}", query); //queries related to '$in' operator List list = Arrays.asList("f1", "f2"); - query = operations.bindFilter(DemoObj.class, "field in :fields", + query = MongoOperations.bindFilter(DemoObj.class, "field in :fields", Parameters.with("fields", list).map()); assertEquals("{'field':{'$in':['f1', 'f2']}}", query); - query = operations.bindFilter(DemoObj.class, "field in :fields and isOk = :isOk", + query = MongoOperations.bindFilter(DemoObj.class, "field in :fields and isOk = :isOk", Parameters.with("fields", list).and("isOk", true).map()); assertEquals("{'field':{'$in':['f1', 'f2']},'isOk':true}", query); - query = operations.bindFilter(DemoObj.class, + query = MongoOperations.bindFilter(DemoObj.class, "field in :fields and property = :p1 or property = :p2", Parameters.with("fields", list).and("p1", "jpg").and("p2", "gif").map()); assertEquals("{'field':{'$in':['f1', 'f2']},'$or':[{'value':'jpg'},{'value':'gif'}]}", query); - query = operations.bindFilter(DemoObj.class, + query = MongoOperations.bindFilter(DemoObj.class, "field in :fields and isOk = :isOk and property = :p1 or property = :p2", Parameters.with("fields", list) .and("isOk", true) @@ -352,33 +350,33 @@ public void testBindEnhancedFilterByName() { @Test public void testBindUpdate() { // native update by index without $set - String update = operations.bindUpdate(DemoObj.class, "{'field': ?1}", new Object[] { "a value" }); + String update = MongoOperations.bindUpdate(DemoObj.class, "{'field': ?1}", new Object[] { "a value" }); assertEquals("{'$set':{'field': 'a value'}}", update); // native update by name without $set - update = operations.bindUpdate(Object.class, "{'field': :field}", + update = MongoOperations.bindUpdate(Object.class, "{'field': :field}", Parameters.with("field", "a value").map()); assertEquals("{'$set':{'field': 'a value'}}", update); // native update by index with $set - update = operations.bindUpdate(DemoObj.class, "{'$set':{'field': ?1}}", new Object[] { "a value" }); + update = MongoOperations.bindUpdate(DemoObj.class, "{'$set':{'field': ?1}}", new Object[] { "a value" }); assertEquals("{'$set':{'field': 'a value'}}", update); // native update by name with $set - update = operations.bindUpdate(Object.class, "{'$set':{'field': :field}}", + update = MongoOperations.bindUpdate(Object.class, "{'$set':{'field': :field}}", Parameters.with("field", "a value").map()); assertEquals("{'$set':{'field': 'a value'}}", update); // shortand update - update = operations.bindUpdate(Object.class, "field", new Object[] { "a value" }); + update = MongoOperations.bindUpdate(Object.class, "field", new Object[] { "a value" }); assertEquals("{'$set':{'field':'a value'}}", update); // enhanced update by index - update = operations.bindUpdate(Object.class, "field = ?1", new Object[] { "a value" }); + update = MongoOperations.bindUpdate(Object.class, "field = ?1", new Object[] { "a value" }); assertEquals("{'$set':{'field':'a value'}}", update); // enhanced update by name - update = operations.bindUpdate(Object.class, "field = :field", + update = MongoOperations.bindUpdate(Object.class, "field = :field", Parameters.with("field", "a value").map()); assertEquals("{'$set':{'field':'a value'}}", update); } diff --git a/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheEntityEnhancer.java b/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheEntityEnhancer.java index 9ad0cc67daea2..7ca3128a8d780 100644 --- a/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheEntityEnhancer.java +++ b/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheEntityEnhancer.java @@ -1,34 +1,64 @@ package io.quarkus.panache.common.deployment; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.function.BiFunction; +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; +import org.jboss.jandex.FieldInfo; import org.jboss.jandex.IndexView; +import org.jboss.jandex.MethodInfo; +import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import io.quarkus.deployment.util.AsmUtil; +import io.quarkus.gizmo.Gizmo; +import io.quarkus.panache.common.Parameters; +import io.quarkus.panache.common.Sort; +import io.quarkus.panache.common.deployment.EntityField.EntityFieldAnnotation; import io.quarkus.panache.common.impl.GenerateBridge; public abstract class PanacheEntityEnhancer> implements BiFunction { - public static final DotName DOTNAME_GENERATE_BRIDGE = DotName.createSimple(GenerateBridge.class.getName()); + public final static DotName DOTNAME_GENERATE_BRIDGE = DotName.createSimple(GenerateBridge.class.getName()); - public static final String JAXB_ANNOTATION_PREFIX = "Ljavax/xml/bind/annotation/"; + public final static String SORT_NAME = Sort.class.getName(); + public final static String SORT_BINARY_NAME = SORT_NAME.replace('.', '/'); + public final static String SORT_SIGNATURE = "L" + SORT_BINARY_NAME + ";"; + + public final static String PARAMETERS_NAME = Parameters.class.getName(); + public final static String PARAMETERS_BINARY_NAME = PARAMETERS_NAME.replace('.', '/'); + public final static String PARAMETERS_SIGNATURE = "L" + PARAMETERS_BINARY_NAME + ";"; + + private static final String JAXB_ANNOTATION_PREFIX = "Ljavax/xml/bind/annotation/"; private static final String JAXB_TRANSIENT_BINARY_NAME = "javax/xml/bind/annotation/XmlTransient"; - public static final String JAXB_TRANSIENT_SIGNATURE = "L" + JAXB_TRANSIENT_BINARY_NAME + ";"; + private static final String JAXB_TRANSIENT_SIGNATURE = "L" + JAXB_TRANSIENT_BINARY_NAME + ";"; private static final String JSON_PROPERTY_BINARY_NAME = "com/fasterxml/jackson/annotation/JsonProperty"; - public static final String JSON_PROPERTY_SIGNATURE = "L" + JSON_PROPERTY_BINARY_NAME + ";"; + private static final String JSON_PROPERTY_SIGNATURE = "L" + JSON_PROPERTY_BINARY_NAME + ";"; - public static final DotName JSON_IGNORE_DOT_NAME = DotName.createSimple("com.fasterxml.jackson.annotation.JsonIgnore"); + private static final DotName JSON_IGNORE_DOT_NAME = DotName.createSimple("com.fasterxml.jackson.annotation.JsonIgnore"); protected MetamodelType modelInfo; + protected final ClassInfo panacheEntityBaseClassInfo; protected final IndexView indexView; protected final List methodCustomizers; - public PanacheEntityEnhancer(IndexView index, List methodCustomizers) { + public PanacheEntityEnhancer(IndexView index, DotName panacheEntityBaseName, + List methodCustomizers) { + this.panacheEntityBaseClassInfo = index.getClassByName(panacheEntityBaseName); this.indexView = index; this.methodCustomizers = methodCustomizers; } @@ -36,6 +66,260 @@ public PanacheEntityEnhancer(IndexView index, List meth @Override public abstract ClassVisitor apply(String className, ClassVisitor outputClassVisitor); + public abstract static class PanacheEntityClassVisitor extends ClassVisitor { + + protected Type thisClass; + protected Map fields; + // set of name + "/" + descriptor + private Set userMethods = new HashSet<>(); + private MetamodelInfo modelInfo; + private ClassInfo panacheEntityBaseClassInfo; + protected ClassInfo entityInfo; + protected List methodCustomizers; + + public PanacheEntityClassVisitor(String className, ClassVisitor outputClassVisitor, + MetamodelInfo> modelInfo, + ClassInfo panacheEntityBaseClassInfo, + ClassInfo entityInfo, + List methodCustomizers) { + super(Gizmo.ASM_API_VERSION, outputClassVisitor); + thisClass = Type.getType("L" + className.replace('.', '/') + ";"); + this.modelInfo = modelInfo; + EntityModel entityModel = modelInfo.getEntityModel(className); + fields = entityModel != null ? entityModel.fields : null; + this.panacheEntityBaseClassInfo = panacheEntityBaseClassInfo; + this.entityInfo = entityInfo; + this.methodCustomizers = methodCustomizers; + } + + @Override + public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { + EntityField ef = fields.get(name); + if (ef == null) { + return super.visitField(access, name, descriptor, signature, value); + } + //we make the fields protected + //so any errors are visible immediately, rather than data just being lost + + FieldVisitor superVisitor; + if (name.equals("id")) { + superVisitor = super.visitField(access, name, descriptor, signature, value); + } else { + superVisitor = super.visitField((access | Modifier.PROTECTED) & ~(Modifier.PRIVATE | Modifier.PUBLIC), + name, descriptor, signature, value); + } + ef.signature = signature; + // if we have a mapped field, let's add some annotations + return new FieldVisitor(Gizmo.ASM_API_VERSION, superVisitor) { + private Set descriptors = new HashSet<>(); + + @Override + public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { + descriptors.add(descriptor); + if (!descriptor.startsWith(JAXB_ANNOTATION_PREFIX)) { + return super.visitAnnotation(descriptor, visible); + } else { + // Save off JAX-B annotations on the field so they can be applied to the generated getter later + EntityFieldAnnotation efAnno = new EntityFieldAnnotation(descriptor); + ef.annotations.add(efAnno); + return new PanacheMovingAnnotationVisitor(efAnno); + } + } + + @Override + public void visitEnd() { + // Add the @JaxbTransient property to the field so that JAXB prefers the generated getter (otherwise JAXB complains about + // having a field and property both with the same name) + // JSONB will already use the getter so we're good + // Note: we don't need to check if we already have @XmlTransient in the descriptors because if we did, we moved it to the getter + // so we can't have any duplicate + super.visitAnnotation(JAXB_TRANSIENT_SIGNATURE, true); + super.visitEnd(); + } + }; + } + + @Override + public MethodVisitor visitMethod(int access, String methodName, String descriptor, String signature, + String[] exceptions) { + userMethods.add(methodName + "/" + descriptor); + MethodVisitor superVisitor = super.visitMethod(access, methodName, descriptor, signature, exceptions); + if (Modifier.isStatic(access) + && Modifier.isPublic(access) + && (access & Opcodes.ACC_SYNTHETIC) == 0 + && !methodCustomizers.isEmpty()) { + org.jboss.jandex.Type[] argTypes = AsmUtil.getParameterTypes(descriptor); + MethodInfo method = this.entityInfo.method(methodName, argTypes); + if (method == null) { + throw new IllegalStateException( + "Could not find indexed method: " + thisClass + "." + methodName + " with descriptor " + descriptor + + " and arg types " + Arrays.toString(argTypes)); + } + superVisitor = new PanacheMethodCustomizerVisitor(superVisitor, method, thisClass, methodCustomizers); + } + return new PanacheFieldAccessMethodVisitor(superVisitor, thisClass.getInternalName(), methodName, descriptor, + modelInfo); + } + + @Override + public void visitEnd() { + // FIXME: generate default constructor + + for (MethodInfo method : panacheEntityBaseClassInfo.methods()) { + // Do not generate a method that already exists + String descriptor = AsmUtil.getDescriptor(method, name -> null); + if (!userMethods.contains(method.name() + "/" + descriptor)) { + AnnotationInstance bridge = method.annotation(DOTNAME_GENERATE_BRIDGE); + if (bridge != null) { + generateMethod(method, bridge.value("targetReturnTypeErased")); + } + } + } + + generateAccessors(); + + super.visitEnd(); + } + + private void generateMethod(MethodInfo method, AnnotationValue targetReturnTypeErased) { + String descriptor = AsmUtil.getDescriptor(method, name -> null); + String signature = AsmUtil.getSignature(method, name -> null); + List parameters = method.parameters(); + String castTo = null; + if (targetReturnTypeErased != null && targetReturnTypeErased.asBoolean()) { + castTo = method.returnType().name().toString('/'); + } + + MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, + method.name(), + descriptor, + signature, + null); + for (int i = 0; i < parameters.size(); i++) { + mv.visitParameter(method.parameterName(i), 0 /* modifiers */); + } + mv.visitCode(); + for (PanacheMethodCustomizer customizer : methodCustomizers) { + customizer.customize(thisClass, method, mv); + } + // inject model + injectModel(mv); + for (int i = 0; i < parameters.size(); i++) { + mv.visitIntInsn(Opcodes.ALOAD, i); + } + // inject Class + String forwardingDescriptor = "(" + getModelDescriptor() + descriptor.substring(1); + if (castTo != null) { + // return type is erased to Object + int lastParen = forwardingDescriptor.lastIndexOf(')'); + forwardingDescriptor = forwardingDescriptor.substring(0, lastParen + 1) + "Ljava/lang/Object;"; + } + mv.visitMethodInsn(Opcodes.INVOKESTATIC, + getPanacheOperationsBinaryName(), + method.name(), + forwardingDescriptor, false); + if (castTo != null) + mv.visitTypeInsn(Opcodes.CHECKCAST, castTo); + String returnTypeDescriptor = descriptor.substring(descriptor.lastIndexOf(")") + 1); + mv.visitInsn(AsmUtil.getReturnInstruction(returnTypeDescriptor)); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + + protected abstract String getModelDescriptor(); + + protected abstract String getPanacheOperationsBinaryName(); + + protected abstract void injectModel(MethodVisitor mv); + + protected void generateAccessors() { + if (fields == null) + return; + for (EntityField field : fields.values()) { + // Getter + String getterName = field.getGetterName(); + String getterDescriptor = "()" + field.descriptor; + if (!userMethods.contains(getterName + "/" + getterDescriptor)) { + MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC, + getterName, getterDescriptor, field.signature == null ? null : "()" + field.signature, null); + mv.visitCode(); + mv.visitIntInsn(Opcodes.ALOAD, 0); + generateAccessorGetField(mv, field); + int returnCode = AsmUtil.getReturnInstruction(field.descriptor); + mv.visitInsn(returnCode); + mv.visitMaxs(0, 0); + // Apply JAX-B annotations that are being transferred from the field + for (EntityFieldAnnotation anno : field.annotations) { + anno.writeToVisitor(mv); + } + // Add an explicit Jackson annotation so that the entire property is not ignored due to having @XmlTransient + // on the field + if (shouldAddJsonProperty(field)) { + mv.visitAnnotation(JSON_PROPERTY_SIGNATURE, true); + } + mv.visitEnd(); + } + + // Setter + String setterName = field.getSetterName(); + String setterDescriptor = "(" + field.descriptor + ")V"; + if (!userMethods.contains(setterName + "/" + setterDescriptor)) { + MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC, + setterName, setterDescriptor, field.signature == null ? null : "(" + field.signature + ")V", null); + mv.visitCode(); + mv.visitIntInsn(Opcodes.ALOAD, 0); + int loadCode; + switch (field.descriptor) { + case "Z": + case "B": + case "C": + case "S": + case "I": + loadCode = Opcodes.ILOAD; + break; + case "J": + loadCode = Opcodes.LLOAD; + break; + case "F": + loadCode = Opcodes.FLOAD; + break; + case "D": + loadCode = Opcodes.DLOAD; + break; + default: + loadCode = Opcodes.ALOAD; + break; + } + mv.visitIntInsn(loadCode, 1); + generateAccessorSetField(mv, field); + mv.visitInsn(Opcodes.RETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + } + } + + private boolean shouldAddJsonProperty(EntityField entityField) { + if (isAnnotatedWithJsonIgnore(entityField)) { + return false; + } + return !entityField.hasAnnotation(JSON_PROPERTY_SIGNATURE); + } + + private boolean isAnnotatedWithJsonIgnore(EntityField entityField) { + FieldInfo field = entityInfo.field(entityField.name); + if (field != null) { + return field.hasAnnotation(JSON_IGNORE_DOT_NAME); + } + + return false; + } + + protected abstract void generateAccessorSetField(MethodVisitor mv, EntityField field); + + protected abstract void generateAccessorGetField(MethodVisitor mv, EntityField field); + } + public abstract void collectFields(ClassInfo classInfo); public MetamodelType getModelInfo() { diff --git a/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheRepositoryEnhancer.java b/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheRepositoryEnhancer.java index ef55d00f18bc6..1b83709d56759 100644 --- a/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheRepositoryEnhancer.java +++ b/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/PanacheRepositoryEnhancer.java @@ -1,12 +1,28 @@ package io.quarkus.panache.common.deployment; import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.function.BiFunction; +import org.jboss.jandex.AnnotationInstance; +import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.IndexView; +import org.jboss.jandex.MethodInfo; +import org.jboss.jandex.Type.Kind; import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; + +import io.quarkus.deployment.util.AsmUtil; +import io.quarkus.deployment.util.JandexUtil; +import io.quarkus.gizmo.Gizmo; public abstract class PanacheRepositoryEnhancer implements BiFunction { @@ -21,7 +37,237 @@ public PanacheRepositoryEnhancer(IndexView index, DotName panacheRepositoryBaseN @Override public abstract ClassVisitor apply(String className, ClassVisitor outputClassVisitor); - public boolean skipRepository(ClassInfo classInfo) { + public static abstract class PanacheRepositoryClassVisitor extends ClassVisitor { + + protected Type entityType; + protected String entitySignature; + protected String entityBinaryType; + protected String idSignature; + protected String idBinaryType; + protected String daoBinaryName; + protected ClassInfo daoClassInfo; + protected ClassInfo panacheRepositoryBaseClassInfo; + protected IndexView indexView; + protected Map typeArguments = new HashMap<>(); + // set of name + "/" + descriptor + protected Set userMethods = new HashSet<>(); + + public PanacheRepositoryClassVisitor(String className, ClassVisitor outputClassVisitor, + ClassInfo panacheRepositoryBaseClassInfo, IndexView indexView) { + super(Gizmo.ASM_API_VERSION, outputClassVisitor); + daoClassInfo = indexView.getClassByName(DotName.createSimple(className)); + daoBinaryName = className.replace('.', '/'); + this.panacheRepositoryBaseClassInfo = panacheRepositoryBaseClassInfo; + this.indexView = indexView; + } + + protected abstract DotName getPanacheRepositoryDotName(); + + protected abstract DotName getPanacheRepositoryBaseDotName(); + + protected abstract String getPanacheOperationsBinaryName(); + + protected abstract String getModelDescriptor(); + + protected abstract void injectModel(MethodVisitor mv); + + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + super.visit(version, access, name, signature, superName, interfaces); + + final String repositoryClassName = name.replace('/', '.'); + + String[] foundTypeArguments = findEntityTypeArgumentsForPanacheRepository(indexView, repositoryClassName, + getPanacheRepositoryBaseDotName()); + + entityBinaryType = foundTypeArguments[0]; + entitySignature = "L" + entityBinaryType + ";"; + entityType = Type.getType(entitySignature); + idBinaryType = foundTypeArguments[1]; + idSignature = "L" + idBinaryType + ";"; + + typeArguments.put("Entity", entitySignature); + typeArguments.put("Id", idSignature); + } + + @Override + public MethodVisitor visitMethod(int access, String methodName, String descriptor, String signature, + String[] exceptions) { + userMethods.add(methodName + "/" + descriptor); + return super.visitMethod(access, methodName, descriptor, signature, exceptions); + } + + public static String[] findEntityTypeArgumentsForPanacheRepository(IndexView indexView, + String repositoryClassName, + DotName repositoryDotName) { + for (ClassInfo classInfo : indexView.getAllKnownImplementors(repositoryDotName)) { + if (repositoryClassName.equals(classInfo.name().toString())) { + return recursivelyFindEntityTypeArgumentsFromClass(indexView, classInfo.name(), repositoryDotName); + } + } + + return null; + } + + public static String[] recursivelyFindEntityTypeArgumentsFromClass(IndexView indexView, DotName clazz, + DotName repositoryDotName) { + if (clazz.equals(JandexUtil.DOTNAME_OBJECT)) { + return null; + } + + List typeParameters = JandexUtil + .resolveTypeParameters(clazz, repositoryDotName, indexView); + if (typeParameters.isEmpty()) + throw new IllegalStateException( + "Failed to find supertype " + repositoryDotName + " from entity class " + clazz); + org.jboss.jandex.Type entityType = typeParameters.get(0); + org.jboss.jandex.Type idType = typeParameters.get(1); + return new String[] { + entityType.name().toString().replace('.', '/'), + idType.name().toString().replace('.', '/') + }; + } + + @Override + public void visitEnd() { + for (MethodInfo method : panacheRepositoryBaseClassInfo.methods()) { + // Do not generate a method that already exists + String descriptor = AsmUtil.getDescriptor(method, name -> typeArguments.get(name)); + if (!userMethods.contains(method.name() + "/" + descriptor)) { + AnnotationInstance bridge = method.annotation(PanacheEntityEnhancer.DOTNAME_GENERATE_BRIDGE); + if (bridge != null) { + generateModelBridge(method, bridge.value("targetReturnTypeErased")); + if (needsJvmBridge(method)) { + generateJvmBridge(method); + } + } + } + } + super.visitEnd(); + } + + private boolean needsJvmBridge(MethodInfo method) { + if (needsJvmBridge(method.returnType())) + return true; + for (org.jboss.jandex.Type paramType : method.parameters()) { + if (needsJvmBridge(paramType)) + return true; + } + return false; + } + + private boolean needsJvmBridge(org.jboss.jandex.Type type) { + if (type.kind() == Kind.TYPE_VARIABLE) { + String typeParamName = type.asTypeVariable().identifier(); + return typeArguments.containsKey(typeParamName); + } + return false; + } + + private void generateJvmBridge(MethodInfo method) { + // get a bounds-erased descriptor + String descriptor = AsmUtil.getDescriptor(method, name -> null); + // make sure we need a bridge + if (!userMethods.contains(method.name() + "/" + descriptor)) { + MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE, + method.name(), + descriptor, + null, + null); + List parameters = method.parameters(); + for (int i = 0; i < parameters.size(); i++) { + mv.visitParameter(method.parameterName(i), 0 /* modifiers */); + } + mv.visitCode(); + // this + mv.visitIntInsn(Opcodes.ALOAD, 0); + // each param + for (int i = 0; i < parameters.size(); i++) { + org.jboss.jandex.Type paramType = parameters.get(i); + if (paramType.kind() == Kind.PRIMITIVE) + throw new IllegalStateException("BUG: Don't know how to generate JVM bridge method for " + method + + ": has primitive parameters"); + mv.visitIntInsn(Opcodes.ALOAD, i + 1); + if (paramType.kind() == Kind.TYPE_VARIABLE) { + String typeParamName = paramType.asTypeVariable().identifier(); + switch (typeParamName) { + case "Entity": + mv.visitTypeInsn(Opcodes.CHECKCAST, entityBinaryType); + break; + case "Id": + mv.visitTypeInsn(Opcodes.CHECKCAST, idBinaryType); + break; + } + } + } + + String targetDescriptor = AsmUtil.getDescriptor(method, name -> typeArguments.get(name)); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, + daoBinaryName, + method.name(), + targetDescriptor, false); + String targetReturnTypeDescriptor = targetDescriptor.substring(targetDescriptor.indexOf(')') + 1); + mv.visitInsn(AsmUtil.getReturnInstruction(targetReturnTypeDescriptor)); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + + } + + private void generateModelBridge(MethodInfo method, AnnotationValue targetReturnTypeErased) { + String descriptor = AsmUtil.getDescriptor(method, name -> typeArguments.get(name)); + // JpaOperations erases the Id type to Object + String descriptorForJpaOperations = AsmUtil.getDescriptor(method, + name -> name.equals("Entity") ? entitySignature : null); + String signature = AsmUtil.getSignature(method, name -> typeArguments.get(name)); + List parameters = method.parameters(); + + String castTo = null; + if (targetReturnTypeErased != null && targetReturnTypeErased.asBoolean()) { + org.jboss.jandex.Type type = method.returnType(); + if (type.kind() == Kind.TYPE_VARIABLE && + type.asTypeVariable().identifier().equals("Entity")) { + castTo = entityBinaryType; + } + if (castTo == null) + castTo = type.name().toString('/'); + } + + // Note: we can't use SYNTHETIC here because otherwise Mockito will never mock these methods + MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC, + method.name(), + descriptor, + signature, + null); + for (int i = 0; i < parameters.size(); i++) { + mv.visitParameter(method.parameterName(i), 0 /* modifiers */); + } + mv.visitCode(); + injectModel(mv); + for (int i = 0; i < parameters.size(); i++) { + mv.visitIntInsn(Opcodes.ALOAD, i + 1); + } + // inject Class + String forwardingDescriptor = "(" + getModelDescriptor() + descriptorForJpaOperations.substring(1); + if (castTo != null) { + // return type is erased to Object + int lastParen = forwardingDescriptor.lastIndexOf(')'); + forwardingDescriptor = forwardingDescriptor.substring(0, lastParen + 1) + "Ljava/lang/Object;"; + } + mv.visitMethodInsn(Opcodes.INVOKESTATIC, + getPanacheOperationsBinaryName(), + method.name(), + forwardingDescriptor, false); + if (castTo != null) + mv.visitTypeInsn(Opcodes.CHECKCAST, castTo); + String returnTypeDescriptor = descriptor.substring(descriptor.lastIndexOf(")") + 1); + mv.visitInsn(AsmUtil.getReturnInstruction(returnTypeDescriptor)); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + } + + public static boolean skipRepository(ClassInfo classInfo) { // we don't want to add methods to abstract/generic entities/repositories: they get added to bottom types // which can't be either return Modifier.isAbstract(classInfo.flags()) diff --git a/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/visitors/PanacheEntityClassVisitor.java b/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/visitors/PanacheEntityClassVisitor.java deleted file mode 100644 index 9713118aff299..0000000000000 --- a/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/visitors/PanacheEntityClassVisitor.java +++ /dev/null @@ -1,293 +0,0 @@ -package io.quarkus.panache.common.deployment.visitors; - -import static io.quarkus.panache.common.deployment.PanacheEntityEnhancer.JSON_IGNORE_DOT_NAME; -import static io.quarkus.panache.common.deployment.PanacheEntityEnhancer.JSON_PROPERTY_SIGNATURE; - -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.jboss.jandex.AnnotationInstance; -import org.jboss.jandex.AnnotationValue; -import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.FieldInfo; -import org.jboss.jandex.MethodInfo; -import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; - -import io.quarkus.deployment.util.AsmUtil; -import io.quarkus.gizmo.Gizmo; -import io.quarkus.panache.common.deployment.EntityField; -import io.quarkus.panache.common.deployment.EntityField.EntityFieldAnnotation; -import io.quarkus.panache.common.deployment.EntityModel; -import io.quarkus.panache.common.deployment.MetamodelInfo; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; -import io.quarkus.panache.common.deployment.PanacheFieldAccessMethodVisitor; -import io.quarkus.panache.common.deployment.PanacheMethodCustomizer; -import io.quarkus.panache.common.deployment.PanacheMethodCustomizerVisitor; -import io.quarkus.panache.common.deployment.PanacheMovingAnnotationVisitor; - -public abstract class PanacheEntityClassVisitor extends ClassVisitor { - - protected Type thisClass; - protected final Map fields; - private final Set userMethods = new HashSet<>(); - private final MetamodelInfo modelInfo; - protected final ClassInfo panacheEntityBaseClassInfo; - protected ClassInfo entityInfo; - protected List methodCustomizers; - - public PanacheEntityClassVisitor(String className, ClassVisitor outputClassVisitor, - MetamodelInfo> modelInfo, - ClassInfo panacheEntityBaseClassInfo, ClassInfo entityInfo, - List methodCustomizers) { - super(Gizmo.ASM_API_VERSION, outputClassVisitor); - - thisClass = Type.getType("L" + className.replace('.', '/') + ";"); - this.modelInfo = modelInfo; - EntityModel entityModel = modelInfo.getEntityModel(className); - fields = entityModel != null ? entityModel.fields : null; - this.panacheEntityBaseClassInfo = panacheEntityBaseClassInfo; - this.entityInfo = entityInfo; - this.methodCustomizers = methodCustomizers; - } - - @Override - public FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { - EntityField ef = fields.get(name); - if (ef == null) { - return super.visitField(access, name, descriptor, signature, value); - } - //we make the fields protected - //so any errors are visible immediately, rather than data just being lost - - FieldVisitor superVisitor; - if (name.equals("id")) { - superVisitor = super.visitField(access, name, descriptor, signature, value); - } else { - superVisitor = super.visitField((access | Modifier.PROTECTED) & ~(Modifier.PRIVATE | Modifier.PUBLIC), - name, descriptor, signature, value); - } - ef.signature = signature; - // if we have a mapped field, let's add some annotations - return new FieldVisitor(Gizmo.ASM_API_VERSION, superVisitor) { - @Override - public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { - if (!descriptor.startsWith(PanacheEntityEnhancer.JAXB_ANNOTATION_PREFIX)) { - return super.visitAnnotation(descriptor, visible); - } else { - // Save off JAX-B annotations on the field so they can be applied to the generated getter later - EntityFieldAnnotation efAnno = new EntityFieldAnnotation(descriptor); - ef.annotations.add(efAnno); - return new PanacheMovingAnnotationVisitor(efAnno); - } - } - - @Override - public void visitEnd() { - // Add the @JaxbTransient property to the field so that JAXB prefers the generated getter (otherwise JAXB complains about - // having a field and property both with the same name) - // JSONB will already use the getter so we're good - // Note: we don't need to check if we already have @XmlTransient in the descriptors because if we did, we moved it to the getter - // so we can't have any duplicate - super.visitAnnotation(PanacheEntityEnhancer.JAXB_TRANSIENT_SIGNATURE, true); - super.visitEnd(); - } - }; - } - - @Override - public MethodVisitor visitMethod(int access, String methodName, String descriptor, String signature, - String[] exceptions) { - userMethods.add(methodName + "/" + descriptor); - MethodVisitor superVisitor = super.visitMethod(access, methodName, descriptor, signature, exceptions); - if (Modifier.isStatic(access) - && Modifier.isPublic(access) - && (access & Opcodes.ACC_SYNTHETIC) == 0 - && !methodCustomizers.isEmpty()) { - org.jboss.jandex.Type[] argTypes = AsmUtil.getParameterTypes(descriptor); - MethodInfo method = this.entityInfo.method(methodName, argTypes); - if (method == null) { - throw new IllegalStateException( - "Could not find indexed method: " + thisClass + "." + methodName + " with descriptor " + descriptor - + " and arg types " + Arrays.toString(argTypes)); - } - superVisitor = new PanacheMethodCustomizerVisitor(superVisitor, method, thisClass, methodCustomizers); - } - return new PanacheFieldAccessMethodVisitor(superVisitor, thisClass.getInternalName(), methodName, descriptor, - modelInfo); - } - - @Override - public void visitEnd() { - // FIXME: generate default constructor - - for (MethodInfo method : panacheEntityBaseClassInfo.methods()) { - // Do not generate a method that already exists - String descriptor = AsmUtil.getDescriptor(method, name -> null); - if (!userMethods.contains(method.name() + "/" + descriptor)) { - AnnotationInstance bridge = method.annotation(PanacheEntityEnhancer.DOTNAME_GENERATE_BRIDGE); - if (bridge != null) { - generateMethod(method, bridge.value("targetReturnTypeErased")); - } - } - } - - generateAccessors(); - - super.visitEnd(); - } - - protected void generateMethod(MethodInfo method, AnnotationValue targetReturnTypeErased) { - String descriptor = AsmUtil.getDescriptor(method, name -> null); - String signature = AsmUtil.getSignature(method, name -> null); - List parameters = method.parameters(); - String castTo = null; - if (targetReturnTypeErased != null && targetReturnTypeErased.asBoolean()) { - castTo = method.returnType().name().toString('/'); - } - - MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, - method.name(), - descriptor, - signature, - null); - for (int i = 0; i < parameters.size(); i++) { - mv.visitParameter(method.parameterName(i), 0 /* modifiers */); - } - mv.visitCode(); - for (PanacheMethodCustomizer customizer : methodCustomizers) { - customizer.customize(thisClass, method, mv); - } - // inject model - injectModel(mv); - for (int i = 0; i < parameters.size(); i++) { - mv.visitIntInsn(Opcodes.ALOAD, i); - } - // inject Class - String forwardingDescriptor = "(" + getModelDescriptor() + descriptor.substring(1); - if (castTo != null) { - // return type is erased to Object - int lastParen = forwardingDescriptor.lastIndexOf(')'); - forwardingDescriptor = forwardingDescriptor.substring(0, lastParen + 1) + "Ljava/lang/Object;"; - } - invokeOperation(method, mv, forwardingDescriptor); - if (castTo != null) - mv.visitTypeInsn(Opcodes.CHECKCAST, castTo); - String returnTypeDescriptor = descriptor.substring(descriptor.lastIndexOf(")") + 1); - mv.visitInsn(AsmUtil.getReturnInstruction(returnTypeDescriptor)); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - protected void invokeOperation(MethodInfo method, MethodVisitor mv, String forwardingDescriptor) { - mv.visitMethodInsn(Opcodes.INVOKESTATIC, - getPanacheOperationsInternalName(), - method.name(), - forwardingDescriptor, false); - } - - protected String getModelDescriptor() { - return "Ljava/lang/Class;"; - } - - protected abstract String getPanacheOperationsInternalName(); - - protected void injectModel(MethodVisitor mv) { - mv.visitLdcInsn(thisClass); - } - - protected void generateAccessors() { - if (fields == null) - return; - for (EntityField field : fields.values()) { - // Getter - String getterName = field.getGetterName(); - String getterDescriptor = "()" + field.descriptor; - if (!userMethods.contains(getterName + "/" + getterDescriptor)) { - MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC, - getterName, getterDescriptor, field.signature == null ? null : "()" + field.signature, null); - mv.visitCode(); - mv.visitIntInsn(Opcodes.ALOAD, 0); - generateAccessorGetField(mv, field); - int returnCode = AsmUtil.getReturnInstruction(field.descriptor); - mv.visitInsn(returnCode); - mv.visitMaxs(0, 0); - // Apply JAX-B annotations that are being transferred from the field - for (EntityFieldAnnotation anno : field.annotations) { - anno.writeToVisitor(mv); - } - // Add an explicit Jackson annotation so that the entire property is not ignored due to having @XmlTransient - // on the field - if (shouldAddJsonProperty(field)) { - mv.visitAnnotation(JSON_PROPERTY_SIGNATURE, true); - } - mv.visitEnd(); - } - - // Setter - String setterName = field.getSetterName(); - String setterDescriptor = "(" + field.descriptor + ")V"; - if (!userMethods.contains(setterName + "/" + setterDescriptor)) { - MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC, - setterName, setterDescriptor, field.signature == null ? null : "(" + field.signature + ")V", null); - mv.visitCode(); - mv.visitIntInsn(Opcodes.ALOAD, 0); - int loadCode; - switch (field.descriptor) { - case "Z": - case "B": - case "C": - case "S": - case "I": - loadCode = Opcodes.ILOAD; - break; - case "J": - loadCode = Opcodes.LLOAD; - break; - case "F": - loadCode = Opcodes.FLOAD; - break; - case "D": - loadCode = Opcodes.DLOAD; - break; - default: - loadCode = Opcodes.ALOAD; - break; - } - mv.visitIntInsn(loadCode, 1); - generateAccessorSetField(mv, field); - mv.visitInsn(Opcodes.RETURN); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - } - } - - private boolean shouldAddJsonProperty(EntityField entityField) { - if (isAnnotatedWithJsonIgnore(entityField)) { - return false; - } - return !entityField.hasAnnotation(JSON_PROPERTY_SIGNATURE); - } - - private boolean isAnnotatedWithJsonIgnore(EntityField entityField) { - FieldInfo field = entityInfo.field(entityField.name); - if (field != null) { - return field.hasAnnotation(JSON_IGNORE_DOT_NAME); - } - - return false; - } - - protected abstract void generateAccessorSetField(MethodVisitor mv, EntityField field); - - protected abstract void generateAccessorGetField(MethodVisitor mv, EntityField field); -} diff --git a/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/visitors/PanacheRepositoryClassVisitor.java b/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/visitors/PanacheRepositoryClassVisitor.java deleted file mode 100644 index 44c6a6b70cacb..0000000000000 --- a/extensions/panache/panache-common/deployment/src/main/java/io/quarkus/panache/common/deployment/visitors/PanacheRepositoryClassVisitor.java +++ /dev/null @@ -1,258 +0,0 @@ -package io.quarkus.panache.common.deployment.visitors; - -import static io.quarkus.deployment.util.AsmUtil.unboxIfRequired; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.jboss.jandex.AnnotationInstance; -import org.jboss.jandex.AnnotationValue; -import org.jboss.jandex.ClassInfo; -import org.jboss.jandex.DotName; -import org.jboss.jandex.IndexView; -import org.jboss.jandex.MethodInfo; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.Type; - -import io.quarkus.deployment.util.AsmUtil; -import io.quarkus.deployment.util.JandexUtil; -import io.quarkus.gizmo.Gizmo; -import io.quarkus.panache.common.deployment.PanacheEntityEnhancer; - -public abstract class PanacheRepositoryClassVisitor extends ClassVisitor { - - protected Type entityType; - protected String entitySignature; - protected String entityBinaryType; - protected String idSignature; - protected String idBinaryType; - protected String daoBinaryName; - protected ClassInfo daoClassInfo; - protected ClassInfo panacheRepositoryBaseClassInfo; - protected IndexView indexView; - protected Map typeArguments = new HashMap<>(); - // set of name + "/" + descriptor - protected Set userMethods = new HashSet<>(); - - public PanacheRepositoryClassVisitor(String className, ClassVisitor outputClassVisitor, IndexView indexView) { - super(Gizmo.ASM_API_VERSION, outputClassVisitor); - daoClassInfo = indexView.getClassByName(DotName.createSimple(className)); - daoBinaryName = className.replace('.', '/'); - this.indexView = indexView; - } - - protected abstract DotName getPanacheRepositoryDotName(); - - protected abstract DotName getPanacheRepositoryBaseDotName(); - - protected abstract String getPanacheOperationsInternalName(); - - protected String getModelDescriptor() { - return "Ljava/lang/Class;"; - } - - protected void injectModel(MethodVisitor mv) { - // inject Class - mv.visitLdcInsn(entityType); - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - super.visit(version, access, name, signature, superName, interfaces); - - final String repositoryClassName = name.replace('/', '.'); - - String[] foundTypeArguments = findEntityTypeArgumentsForPanacheRepository(indexView, repositoryClassName, - getPanacheRepositoryBaseDotName()); - - entityBinaryType = foundTypeArguments[0]; - entitySignature = "L" + entityBinaryType + ";"; - this.entityType = Type.getType(entitySignature); - idBinaryType = foundTypeArguments[1]; - idSignature = "L" + idBinaryType + ";"; - Type idType = Type.getType(idSignature); - - typeArguments.put("Entity", this.entityType.getDescriptor()); - typeArguments.put("Id", idType.getDescriptor()); - this.panacheRepositoryBaseClassInfo = indexView.getClassByName(getPanacheRepositoryBaseDotName()); - } - - @Override - public MethodVisitor visitMethod(int access, String methodName, String descriptor, String signature, - String[] exceptions) { - userMethods.add(methodName + "/" + descriptor); - return super.visitMethod(access, methodName, descriptor, signature, exceptions); - } - - public static String[] findEntityTypeArgumentsForPanacheRepository(IndexView indexView, - String repositoryClassName, - DotName repositoryDotName) { - for (ClassInfo classInfo : indexView.getAllKnownImplementors(repositoryDotName)) { - if (repositoryClassName.equals(classInfo.name().toString())) { - return recursivelyFindEntityTypeArgumentsFromClass(indexView, classInfo.name(), repositoryDotName); - } - } - - return null; - } - - public static String[] recursivelyFindEntityTypeArgumentsFromClass(IndexView indexView, DotName clazz, - DotName repositoryDotName) { - if (clazz.equals(JandexUtil.DOTNAME_OBJECT)) { - return null; - } - - List typeParameters = JandexUtil - .resolveTypeParameters(clazz, repositoryDotName, indexView); - if (typeParameters.isEmpty()) - throw new IllegalStateException( - "Failed to find supertype " + repositoryDotName + " from entity class " + clazz); - org.jboss.jandex.Type entityType = typeParameters.get(0); - org.jboss.jandex.Type idType = typeParameters.get(1); - return new String[] { - entityType.name().toString().replace('.', '/'), - idType.name().toString().replace('.', '/') - }; - } - - @Override - public void visitEnd() { - for (MethodInfo method : panacheRepositoryBaseClassInfo.methods()) { - // Do not generate a method that already exists - String descriptor = AsmUtil.getDescriptor(method, name -> typeArguments.get(name)); - if (!userMethods.contains(method.name() + "/" + descriptor)) { - AnnotationInstance bridge = method.annotation(PanacheEntityEnhancer.DOTNAME_GENERATE_BRIDGE); - if (bridge != null) { - generateModelBridge(method, bridge.value("targetReturnTypeErased")); - if (needsJvmBridge(method)) { - generateJvmBridge(method); - } - } - } - } - super.visitEnd(); - } - - private boolean needsJvmBridge(MethodInfo method) { - if (needsJvmBridge(method.returnType())) - return true; - for (org.jboss.jandex.Type paramType : method.parameters()) { - if (needsJvmBridge(paramType)) - return true; - } - return false; - } - - private boolean needsJvmBridge(org.jboss.jandex.Type type) { - if (type.kind() == org.jboss.jandex.Type.Kind.TYPE_VARIABLE) { - String typeParamName = type.asTypeVariable().identifier(); - return typeArguments.containsKey(typeParamName); - } - return false; - } - - protected void generateJvmBridge(MethodInfo method) { - // get a bounds-erased descriptor - String descriptor = AsmUtil.getDescriptor(method, name -> null); - // make sure we need a bridge - if (!userMethods.contains(method.name() + "/" + descriptor)) { - MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_BRIDGE, - method.name(), - descriptor, - null, - null); - List parameters = method.parameters(); - for (int i = 0; i < parameters.size(); i++) { - mv.visitParameter(method.parameterName(i), 0 /* modifiers */); - } - mv.visitCode(); - // this - mv.visitIntInsn(Opcodes.ALOAD, 0); - // each param - for (int i = 0; i < parameters.size(); i++) { - org.jboss.jandex.Type paramType = parameters.get(i); - if (paramType.kind() == org.jboss.jandex.Type.Kind.PRIMITIVE) - throw new IllegalStateException("BUG: Don't know how to generate JVM bridge method for " + method - + ": has primitive parameters"); - mv.visitIntInsn(Opcodes.ALOAD, i + 1); - if (paramType.kind() == org.jboss.jandex.Type.Kind.TYPE_VARIABLE) { - String typeParamName = paramType.asTypeVariable().identifier(); - Type type = Type.getType(typeArguments.get(typeParamName)); - if (type.getSort() > Type.DOUBLE) { - mv.visitTypeInsn(Opcodes.CHECKCAST, type.getInternalName()); - } else { - unboxIfRequired(mv, type); - } - } - } - - String targetDescriptor = AsmUtil.getDescriptor(method, name -> typeArguments.get(name)); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, - daoBinaryName, - method.name(), - targetDescriptor, false); - String targetReturnTypeDescriptor = targetDescriptor.substring(targetDescriptor.indexOf(')') + 1); - mv.visitInsn(AsmUtil.getReturnInstruction(targetReturnTypeDescriptor)); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - } - - protected void generateModelBridge(MethodInfo method, AnnotationValue targetReturnTypeErased) { - String descriptor = AsmUtil.getDescriptor(method, name -> typeArguments.get(name)); - // JpaOperations erases the Id type to Object - String descriptorForJpaOperations = AsmUtil.getDescriptor(method, - name -> name.equals("Entity") ? entitySignature : null); - String signature = AsmUtil.getSignature(method, name -> typeArguments.get(name)); - List parameters = method.parameters(); - - String castTo = null; - if (targetReturnTypeErased != null && targetReturnTypeErased.asBoolean()) { - org.jboss.jandex.Type type = method.returnType(); - if (type.kind() == org.jboss.jandex.Type.Kind.TYPE_VARIABLE && - type.asTypeVariable().identifier().equals("Entity")) { - castTo = entityBinaryType; - } - if (castTo == null) - castTo = type.name().toString('/'); - } - - // Note: we can't use SYNTHETIC here because otherwise Mockito will never mock these methods - MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC, - method.name(), - descriptor, - signature, - null); - for (int i = 0; i < parameters.size(); i++) { - mv.visitParameter(method.parameterName(i), 0 /* modifiers */); - } - mv.visitCode(); - injectModel(mv); - for (int i = 0; i < parameters.size(); i++) { - mv.visitIntInsn(Opcodes.ALOAD, i + 1); - } - // inject Class - String forwardingDescriptor = "(" + getModelDescriptor() + descriptorForJpaOperations.substring(1); - if (castTo != null) { - // return type is erased to Object - int lastParen = forwardingDescriptor.lastIndexOf(')'); - forwardingDescriptor = forwardingDescriptor.substring(0, lastParen + 1) + "Ljava/lang/Object;"; - } - mv.visitMethodInsn(Opcodes.INVOKESTATIC, - getPanacheOperationsInternalName(), - method.name(), - forwardingDescriptor, false); - if (castTo != null) - mv.visitTypeInsn(Opcodes.CHECKCAST, castTo); - String returnTypeDescriptor = descriptor.substring(descriptor.lastIndexOf(")") + 1); - mv.visitInsn(AsmUtil.getReturnInstruction(returnTypeDescriptor)); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } -} diff --git a/extensions/panache/pom.xml b/extensions/panache/pom.xml index 11fbc95dc77f0..39d2a3d946119 100644 --- a/extensions/panache/pom.xml +++ b/extensions/panache/pom.xml @@ -19,9 +19,7 @@ hibernate-orm-panache-common hibernate-orm-panache hibernate-orm-panache-kotlin - mongodb-panache-common mongodb-panache - mongodb-panache-kotlin panacheql rest-data-panache hibernate-orm-rest-data-panache diff --git a/integration-tests/hibernate-orm-panache/src/test/java/io/quarkus/it/panache/JacksonTest.java b/integration-tests/hibernate-orm-panache/src/test/java/io/quarkus/it/panache/JacksonTest.java index 81e59b415072c..47f341da3d64f 100644 --- a/integration-tests/hibernate-orm-panache/src/test/java/io/quarkus/it/panache/JacksonTest.java +++ b/integration-tests/hibernate-orm-panache/src/test/java/io/quarkus/it/panache/JacksonTest.java @@ -16,7 +16,6 @@ public class JacksonTest { public void testJsonIgnoreHonoured() { List books = RestAssured.when().get("/book/Berlin/Beevor").then().extract().body().jsonPath().getList(".", Book.class); - assertThat(books).hasSize(1).filteredOn(book -> book.author != null).isEmpty(); } } diff --git a/integration-tests/mongodb-panache-kotlin/pom.xml b/integration-tests/mongodb-panache-kotlin/pom.xml deleted file mode 100755 index 55f9b195a7e64..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/pom.xml +++ /dev/null @@ -1,233 +0,0 @@ - - - 4.0.0 - - - io.quarkus - quarkus-integration-tests-parent - 999-SNAPSHOT - - - quarkus-integration-test-mongodb-panache-kotlin - - Quarkus - Integration Tests - MongoDB Panache Kotlin - - - - io.quarkus - quarkus-resteasy-jsonb - - - io.quarkus - quarkus-resteasy-mutiny - - - io.quarkus - quarkus-mongodb-panache-kotlin - - - io.quarkus - quarkus-rest-client - - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-test - ${kotlin.version} - test - - - com.fasterxml.jackson.module - jackson-module-kotlin - - - org.jetbrains.kotlin - kotlin-stdlib - - - org.jetbrains.kotlin - kotlin-stdlib-jdk8 - - - - - - - org.junit.jupiter - junit-jupiter-api - compile - - - - io.quarkus - quarkus-junit5 - test - - - io.quarkus - quarkus-panache-mock - test - - - io.rest-assured - rest-assured - test - - - de.flapdoodle.embed - de.flapdoodle.embed.mongo - test - - - com.fasterxml.jackson.datatype - jackson-datatype-jdk8 - test - - - com.fasterxml.jackson.datatype - jackson-datatype-jsr310 - test - - - org.awaitility - awaitility - test - - - - - src/main/kotlin - src/test/kotlin - - - src/main/resources - true - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - compile - compile - - compile - - - - test-compile - test-compile - - test-compile - - - - - - org.jetbrains.kotlin - kotlin-maven-allopen - ${kotlin.version} - - - - - all-open - - - - - 1.8 - - - - maven-failsafe-plugin - - true - - - - io.quarkus - quarkus-maven-plugin - - - - build - - - - - - - - - - native-image - - - native - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - ${native.surefire.skip} - - - - org.apache.maven.plugins - maven-failsafe-plugin - - - - integration-test - verify - - - - - ${project.build.directory}/${project.build.finalName}-runner - - - - - - - false - - - - io.quarkus - quarkus-maven-plugin - - - native-image - - native-image - - - true - true - ${graalvmHome} - - - - - - - - - - diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/Book.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/Book.kt deleted file mode 100644 index 63d54cd962df3..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/Book.kt +++ /dev/null @@ -1,58 +0,0 @@ -package io.quarkus.it.mongodb.panache.book - -import io.quarkus.mongodb.panache.MongoEntity -import org.bson.codecs.pojo.annotations.BsonIgnore -import org.bson.codecs.pojo.annotations.BsonProperty -import org.bson.types.ObjectId -import java.time.LocalDate -import javax.json.bind.annotation.JsonbDateFormat - -@MongoEntity(collection = "TheBook", clientName = "cl2") -class Book { - @BsonProperty("bookTitle") - var title: String? = null - private set - var author: String? = null - private set - var id: ObjectId? = null - - @BsonIgnore - var transientDescription: String? = null - private set - - @JsonbDateFormat("yyyy-MM-dd") - var creationDate: LocalDate? = null - var categories = listOf() - private set - private var details: BookDetail? = null - - fun setTitle(title: String?): Book { - this.title = title - return this - } - - fun setAuthor(author: String?): Book { - this.author = author - return this - } - - fun setCategories(categories: List): Book { - this.categories = categories - return this - } - - fun getDetails(): BookDetail? { - return details - } - - fun setDetails(details: BookDetail?): Book { - this.details = details - return this - } - - fun setTransientDescription(transientDescription: String?): Book { - this.transientDescription = transientDescription - return this - } - -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookDetail.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookDetail.kt deleted file mode 100644 index 5b4d2e2a9a737..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookDetail.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.quarkus.it.mongodb.panache.book - -class BookDetail { - var summary: String? = null - private set - var rating = 0 - private set - - fun setSummary(summary: String?): BookDetail { - this.summary = summary - return this - } - - fun setRating(rating: Int): BookDetail { - this.rating = rating - return this - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntity.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntity.kt deleted file mode 100644 index e2fd0b2bd63ec..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntity.kt +++ /dev/null @@ -1,59 +0,0 @@ -package io.quarkus.it.mongodb.panache.book - -import io.quarkus.mongodb.panache.MongoEntity -import io.quarkus.mongodb.panache.kotlin.PanacheMongoCompanion -import io.quarkus.mongodb.panache.kotlin.PanacheMongoEntity -import org.bson.codecs.pojo.annotations.BsonIgnore -import org.bson.codecs.pojo.annotations.BsonProperty -import org.bson.types.ObjectId -import java.time.LocalDate -import javax.json.bind.annotation.JsonbDateFormat - -@MongoEntity(collection = "TheBookEntity", clientName = "cl2") -class BookEntity : PanacheMongoEntity() { - companion object : PanacheMongoCompanion { - override fun findById(id: ObjectId): BookEntity { - return operations.findById(BookEntity::class.java, id) as BookEntity - } - } - - @BsonProperty("bookTitle") - var title: String? = null - private set - var author: String? = null - private set - - @BsonIgnore - var transientDescription: String? = null - - @JsonbDateFormat("yyyy-MM-dd") - var creationDate: LocalDate? = null - var categories = listOf() - private set - private var details: BookDetail? = null - - fun setTitle(title: String?): BookEntity { - this.title = title - return this - } - - fun setAuthor(author: String?): BookEntity { - this.author = author - return this - } - - fun setCategories(categories: List): BookEntity { - this.categories = categories - return this - } - - fun getDetails(): BookDetail? { - return details - } - - fun setDetails(details: BookDetail?): BookEntity { - this.details = details - return this - } - -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntityResource.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntityResource.kt deleted file mode 100644 index 914f50c29ee81..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookEntityResource.kt +++ /dev/null @@ -1,111 +0,0 @@ -package io.quarkus.it.mongodb.panache.book - -import io.quarkus.panache.common.Parameters -import io.quarkus.panache.common.Sort -import org.bson.types.ObjectId -import org.jboss.logging.Logger -import java.net.URI -import java.time.LocalDate -import javax.annotation.PostConstruct -import javax.ws.rs.Consumes -import javax.ws.rs.DELETE -import javax.ws.rs.GET -import javax.ws.rs.NotFoundException -import javax.ws.rs.PATCH -import javax.ws.rs.POST -import javax.ws.rs.PUT -import javax.ws.rs.Path -import javax.ws.rs.PathParam -import javax.ws.rs.Produces -import javax.ws.rs.QueryParam -import javax.ws.rs.core.MediaType -import javax.ws.rs.core.Response - -@Path("/books/entity") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -class BookEntityResource { - @PostConstruct - fun init() { - val databaseName: String = BookEntity.mongoDatabase().name - val collectionName: String = BookEntity.mongoCollection().namespace.collectionName - LOGGER.infov("Using BookEntity[database={0}, collection={1}]", databaseName, collectionName) - } - - @GET - fun getBooks(@QueryParam("sort") sort: String?): List { - return if (sort != null) { - BookEntity.listAll(Sort.ascending(sort)) - } else BookEntity.listAll() - } - - @POST - fun addBook(book: BookEntity): Response { - book.persist() - val id: String = book.id.toString() - return Response.created(URI.create("/books/entity/$id")).build() - } - - @PUT - fun updateBook(book: BookEntity): Response { - book.update() - return Response.accepted().build() - } - - // PATCH is not correct here but it allows to test persistOrUpdate without a specific subpath - @PATCH - fun upsertBook(book: BookEntity): Response { - book.persistOrUpdate() - return Response.accepted().build() - } - - @DELETE - @Path("/{id}") - fun deleteBook(@PathParam("id") id: String?) { - val deleted: Boolean = BookEntity.deleteById(ObjectId(id)) - if (!deleted) { - throw NotFoundException() - } - } - - @GET - @Path("/{id}") - fun getBook(@PathParam("id") id: String?): BookEntity = BookEntity.findById(ObjectId(id)) - - @GET - @Path("/search/{author}") - fun getBooksByAuthor(@PathParam("author") author: String): List = - BookEntity.find("author", author).project(BookShortView::class.java).list() - - @GET - @Path("/search") - fun search(@QueryParam("author") author: String?, @QueryParam("title") title: String?, - @QueryParam("dateFrom") dateFrom: String?, @QueryParam("dateTo") dateTo: String?): BookEntity? { - return if (author != null) { - BookEntity.find("{'author': ?1,'bookTitle': ?2}", author, title!!).firstResult() - } else BookEntity - .find("{'creationDate': {\$gte: ?1}, 'creationDate': {\$lte: ?2}}", LocalDate.parse(dateFrom), - LocalDate.parse(dateTo)) - .firstResult() - } - - @GET - @Path("/search2") - fun search2(@QueryParam("author") author: String?, @QueryParam("title") title: String?, - @QueryParam("dateFrom") dateFrom: String?, @QueryParam("dateTo") dateTo: String?): BookEntity? { - return if (author != null) { - BookEntity.find("{'author': :author,'bookTitle': :title}", - Parameters.with("author", author).and("title", title)).firstResult() - } else BookEntity.find("{'creationDate': {\$gte: :dateFrom}, 'creationDate': {\$lte: :dateTo}}", - Parameters.with("dateFrom", LocalDate.parse(dateFrom)).and("dateTo", LocalDate.parse(dateTo))).firstResult() - } - - @DELETE - fun deleteAll() { - BookEntity.deleteAll() - } - - companion object { - private val LOGGER: Logger = Logger.getLogger(BookEntityResource::class.java) - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookRepository.kt deleted file mode 100644 index c2d2bebd4c4e6..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookRepository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.quarkus.it.mongodb.panache.book - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoRepository -import javax.enterprise.context.ApplicationScoped - -@ApplicationScoped -class BookRepository : PanacheMongoRepository \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookRepositoryResource.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookRepositoryResource.kt deleted file mode 100644 index 6e0b79389b43b..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookRepositoryResource.kt +++ /dev/null @@ -1,114 +0,0 @@ -package io.quarkus.it.mongodb.panache.book - -import io.quarkus.panache.common.Parameters -import io.quarkus.panache.common.Sort -import org.bson.types.ObjectId -import org.jboss.logging.Logger -import java.net.URI -import java.time.LocalDate -import javax.annotation.PostConstruct -import javax.inject.Inject -import javax.ws.rs.Consumes -import javax.ws.rs.DELETE -import javax.ws.rs.GET -import javax.ws.rs.NotFoundException -import javax.ws.rs.PATCH -import javax.ws.rs.POST -import javax.ws.rs.PUT -import javax.ws.rs.Path -import javax.ws.rs.PathParam -import javax.ws.rs.Produces -import javax.ws.rs.QueryParam -import javax.ws.rs.core.MediaType -import javax.ws.rs.core.Response - -@Path("/books/repository") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -class BookRepositoryResource { - @Inject - lateinit var bookRepository: BookRepository - - @PostConstruct - fun init() { - val databaseName: String = bookRepository.mongoDatabase().name - val collectionName: String = bookRepository.mongoCollection().namespace.collectionName - LOGGER.infov("Using BookRepository[database={0}, collection={1}]", databaseName, collectionName) - } - - @GET - fun getBooks(@QueryParam("sort") sort: String?): List { - return if (sort != null) { - bookRepository.listAll(Sort.ascending(sort)) - } else bookRepository.listAll() - } - - @POST - fun addBook(book: Book): Response { - bookRepository.persist(book) - return Response.created(URI.create("/books/entity${book.id}")).build() - } - - @PUT - fun updateBook(book: Book): Response { - bookRepository.update(book) - return Response.accepted().build() - } - - // PATCH is not correct here but it allows to test persistOrUpdate without a specific subpath - @PATCH - fun upsertBook(book: Book): Response { - bookRepository.persistOrUpdate(book) - return Response.accepted().build() - } - - @DELETE - @Path("/{id}") - fun deleteBook(@PathParam("id") id: String) { - val deleted: Boolean = bookRepository.deleteById(ObjectId(id)) - if (!deleted) { - throw NotFoundException() - } - } - - @GET - @Path("/{id}") - fun getBook(@PathParam("id") id: String?) = bookRepository.findById(ObjectId(id)) - - @GET - @Path("/search/{author}") - fun getBooksByAuthor(@PathParam("author") author: String): List = - bookRepository.find("author", author).project(BookShortView::class.java).list() - - @GET - @Path("/search") - fun search(@QueryParam("author") author: String?, @QueryParam("title") title: String?, - @QueryParam("dateFrom") dateFrom: String?, @QueryParam("dateTo") dateTo: String?): Book? { - return if (author != null) { - bookRepository.find("{'author': ?1,'bookTitle': ?2}", author, title!!).firstResult() - } else bookRepository - .find("{'creationDate': {\$gte: ?1}, 'creationDate': {\$lte: ?2}}", LocalDate.parse(dateFrom), - LocalDate.parse(dateTo)) - .firstResult() ?: throw NotFoundException() - } - - @GET - @Path("/search2") - fun search2(@QueryParam("author") author: String?, @QueryParam("title") title: String?, - @QueryParam("dateFrom") dateFrom: String?, @QueryParam("dateTo") dateTo: String?): Book? { - return if (author != null) { - bookRepository.find("{'author': :author,'bookTitle': :title}", - Parameters.with("author", author).and("title", title)).firstResult() - } else bookRepository.find("{'creationDate': {\$gte: :dateFrom}, 'creationDate': {\$lte: :dateTo}}", - Parameters.with("dateFrom", LocalDate.parse(dateFrom)).and("dateTo", LocalDate.parse(dateTo))).firstResult() - } - - @DELETE - fun deleteAll() { - bookRepository.deleteAll() - } - - companion object { - private val LOGGER: Logger = Logger.getLogger(BookRepositoryResource::class.java) - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookShortView.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookShortView.kt deleted file mode 100644 index fe12bfd04ed45..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/book/BookShortView.kt +++ /dev/null @@ -1,15 +0,0 @@ -package io.quarkus.it.mongodb.panache.book - -import io.quarkus.mongodb.panache.ProjectionFor -import java.time.LocalDate -import javax.json.bind.annotation.JsonbDateFormat - -@ProjectionFor(Book::class) -class BookShortView { - // uses the field name title and not the column name bookTitle - var title: String? = null - var author: String? = null - - @JsonbDateFormat("yyyy-MM-dd") - var creationDate: LocalDate? = null -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/AbstractRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/AbstractRepository.kt deleted file mode 100644 index aa5732ad6656d..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/AbstractRepository.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.quarkus.it.mongodb.panache.bugs - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoRepositoryBase - -abstract class AbstractRepository : PanacheMongoRepositoryBase \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5274EntityRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5274EntityRepository.kt deleted file mode 100644 index 7abdd45fa5479..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5274EntityRepository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.quarkus.it.mongodb.panache.bugs - -import io.quarkus.it.mongodb.panache.book.Book -import javax.enterprise.context.ApplicationScoped - -@ApplicationScoped -class Bug5274EntityRepository : AbstractRepository() \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5885AbstractRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5885AbstractRepository.kt deleted file mode 100644 index ec8109aa86bb5..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5885AbstractRepository.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.quarkus.it.mongodb.panache.bugs - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoRepositoryBase - -abstract class Bug5885AbstractRepository : PanacheMongoRepositoryBase \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5885EntityRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5885EntityRepository.kt deleted file mode 100644 index fdd2538e763f2..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug5885EntityRepository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.quarkus.it.mongodb.panache.bugs - -import io.quarkus.it.mongodb.panache.person.PersonEntity -import javax.enterprise.context.ApplicationScoped - -@ApplicationScoped -class Bug5885EntityRepository : Bug5885AbstractRepository() \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324AbstractRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324AbstractRepository.kt deleted file mode 100644 index 0ad66742a6eee..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324AbstractRepository.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.quarkus.it.mongodb.panache.bugs - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoRepository - -abstract class Bug6324AbstractRepository : PanacheMongoRepository \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324ConcreteRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324ConcreteRepository.kt deleted file mode 100644 index 4b98163786cb5..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324ConcreteRepository.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.quarkus.it.mongodb.panache.bugs - -import javax.enterprise.context.ApplicationScoped - -@ApplicationScoped -class Bug6324ConcreteRepository : Bug6324AbstractRepository() \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324Repository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324Repository.kt deleted file mode 100644 index 78ed184bd4736..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/Bug6324Repository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.quarkus.it.mongodb.panache.bugs - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoRepository -import javax.enterprise.context.ApplicationScoped - -@ApplicationScoped -class Bug6324Repository : PanacheMongoRepository \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/BugResource.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/BugResource.kt deleted file mode 100644 index 06b7af4bb4463..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/BugResource.kt +++ /dev/null @@ -1,94 +0,0 @@ -package io.quarkus.it.mongodb.panache.bugs - -import java.time.Instant -import java.time.LocalDate -import java.time.LocalDateTime -import java.time.temporal.ChronoUnit -import java.util.Date -import javax.inject.Inject -import javax.ws.rs.Consumes -import javax.ws.rs.GET -import javax.ws.rs.NotFoundException -import javax.ws.rs.Path -import javax.ws.rs.Produces -import javax.ws.rs.core.MediaType -import javax.ws.rs.core.Response - -@Path("/bugs") -@Produces(MediaType.TEXT_PLAIN) -@Consumes(MediaType.TEXT_PLAIN) -class BugResource { - @Inject - lateinit var bug5274EntityRepository: Bug5274EntityRepository - - @Inject - lateinit var bug5885EntityRepository: Bug5885EntityRepository - - @Inject - lateinit var bug6324Repository: Bug6324Repository - - @Inject - lateinit var bug6324ConcreteRepository: Bug6324ConcreteRepository - - @GET - @Path("5274") - fun testBug5274(): String { - bug5274EntityRepository.count() - return "OK" - } - - @GET - @Path("5885") - fun testBug5885(): String { - bug5885EntityRepository.findById(1L) - return "OK" - } - - @GET - @Path("6324") - fun testNeedReflection(): Response { - return Response.ok(bug6324Repository.listAll()).build() - } - - @GET - @Path("6324/abstract") - fun testNeedReflectionAndAbstract(): Response { - return Response.ok(bug6324ConcreteRepository.listAll()).build() - } - - @GET - @Path("dates") - fun testDatesFormat(): Response { - val dateEntity = DateEntity() - dateEntity.persist() - - // search on all possible fields - val millisInDay = 1000 * 60 * 60 * 24.toLong() - val dateTomorrow = Date(System.currentTimeMillis() + 1000 * millisInDay) - val localDateTomorrow: LocalDate = LocalDate.now().plus(1, ChronoUnit.DAYS) - val localDateTimeTomorrow: LocalDateTime = LocalDateTime.now().plus(1, ChronoUnit.DAYS) - val instantTomorrow: Instant = Instant.now().plus(1, ChronoUnit.DAYS) - val result: DateEntity = DateEntity - .find("dateDate < ?1 and localDate < ?2 and localDateTime < ?3 and instant < ?4", - dateTomorrow, localDateTomorrow, localDateTimeTomorrow, instantTomorrow) - .firstResult() - ?: return Response.status(404).build() - return Response.ok().build() - } - - @GET - @Path("7415") - fun testForeignObjectId(): Response { - val link = LinkedEntity() - link.name = "toto" - link.persist() - val entity = LinkedEntity() - entity.name = "tata" - entity.myForeignId = link.id - entity.persist() - - // we should be able to retrieve `entity` from the foreignId ... - LinkedEntity.find("myForeignId", link.id!!).firstResult() ?: throw NotFoundException() - return Response.ok().build() - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/DateEntity.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/DateEntity.kt deleted file mode 100644 index b9390d4ab5f6d..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/DateEntity.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.quarkus.it.mongodb.panache.bugs - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoCompanion -import io.quarkus.mongodb.panache.kotlin.PanacheMongoEntity -import java.time.Instant -import java.time.LocalDate -import java.time.LocalDateTime -import java.util.Date - -/** - * An entity that have all the supported date format. - * Asserting #6566 and possibility other date issues. - */ -class DateEntity(var dateDate: Date = Date(), var localDate: LocalDate = LocalDate.now(), - var localDateTime: LocalDateTime = LocalDateTime.now(), - var instant: Instant = Instant.now()) : PanacheMongoEntity() { - companion object: PanacheMongoCompanion - -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/LinkedEntity.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/LinkedEntity.kt deleted file mode 100644 index 72fecd3e9a8d4..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/LinkedEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.quarkus.it.mongodb.panache.bugs - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoCompanion -import io.quarkus.mongodb.panache.kotlin.PanacheMongoEntity -import org.bson.types.ObjectId - -class LinkedEntity : PanacheMongoEntity() { - companion object: PanacheMongoCompanion - - var name: String? = null - var myForeignId: ObjectId? = null -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/NeedReflection.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/NeedReflection.kt deleted file mode 100644 index 5af253182e2c2..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/bugs/NeedReflection.kt +++ /dev/null @@ -1,5 +0,0 @@ -package io.quarkus.it.mongodb.panache.bugs - -class NeedReflection { - var comment: String? = null -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/MockablePersonRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/MockablePersonRepository.kt deleted file mode 100644 index 3da2463cbbb89..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/MockablePersonRepository.kt +++ /dev/null @@ -1,14 +0,0 @@ -package io.quarkus.it.mongodb.panache.person - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoRepositoryBase -import io.quarkus.panache.common.Sort -import javax.enterprise.context.ApplicationScoped - -@ApplicationScoped -class MockablePersonRepository : PanacheMongoRepositoryBase { - open fun findOrdered(): List? { - val sort = Sort.by("lastname", "firstname") - val found = findAll(sort) - return found.list() - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/Person.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/Person.kt deleted file mode 100644 index fd83f6ebecf8c..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/Person.kt +++ /dev/null @@ -1,10 +0,0 @@ -package io.quarkus.it.mongodb.panache.person - -import org.bson.codecs.pojo.annotations.BsonId - -class Person { - @BsonId - var id: Long? = null - var firstname: String? = null - var lastname: String? = null -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonEntity.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonEntity.kt deleted file mode 100644 index 790cc1d2fff1c..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonEntity.kt +++ /dev/null @@ -1,20 +0,0 @@ -package io.quarkus.it.mongodb.panache.person - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoCompanionBase -import io.quarkus.mongodb.panache.kotlin.PanacheMongoEntityBase -import io.quarkus.panache.common.Sort -import org.bson.codecs.pojo.annotations.BsonId - -class PersonEntity : PanacheMongoEntityBase() { - @BsonId - var id: Long? = null - var firstname: String? = null - var lastname: String? = null - - companion object : PanacheMongoCompanionBase { - fun findOrdered(): List { - return findAll(Sort.by("lastname", "firstname")).list() - } - - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonEntityResource.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonEntityResource.kt deleted file mode 100644 index 89f7a2d2a9caa..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonEntityResource.kt +++ /dev/null @@ -1,87 +0,0 @@ -package io.quarkus.it.mongodb.panache.person - -import io.quarkus.panache.common.Sort -import java.net.URI -import javax.ws.rs.Consumes -import javax.ws.rs.DELETE -import javax.ws.rs.GET -import javax.ws.rs.PATCH -import javax.ws.rs.POST -import javax.ws.rs.PUT -import javax.ws.rs.Path -import javax.ws.rs.PathParam -import javax.ws.rs.Produces -import javax.ws.rs.QueryParam -import javax.ws.rs.core.MediaType -import javax.ws.rs.core.Response - -@Path("/persons/entity") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -class PersonEntityResource { - @GET - fun getPersons(@QueryParam("sort") sort: String?): List = - sort?.let { PersonEntity.listAll(Sort.ascending(sort)) } - ?: PersonEntity.listAll() - - @GET - @Path("/search/{name}") - fun searchPersons(@PathParam("name") name: String): Set { - return PersonEntity.find("lastname", name) - .project(PersonName::class.java) - .list() - .toSet() - } - - @POST - fun addPerson(person: PersonEntity): Response { - person.persist() - return Response.created(URI.create("/persons/entity/${person.id}")).build() - } - - @POST - @Path("/multiple") - fun addPersons(persons: List) { - PersonEntity.persist(persons) - } - - @PUT - fun updatePerson(person: PersonEntity): Response { - person.update() - return Response.accepted().build() - } - - // PATCH is not correct here but it allows to test persistOrUpdate without a specific subpath - @PATCH - fun upsertPerson(person: PersonEntity): Response { - person.persistOrUpdate() - return Response.accepted().build() - } - - @DELETE - @Path("/{id}") - fun deletePerson(@PathParam("id") id: String) { - PersonEntity.deleteById(id.toLong()) - } - - @GET - @Path("/{id}") - fun getPerson(@PathParam("id") id: String) = PersonEntity.findById(id.toLong()) - - @GET - @Path("/count") - fun countAll(): Long = PersonEntity.count() - - @DELETE - fun deleteAll() { - PersonEntity.deleteAll() - } - - @POST - @Path("/rename") - fun rename(@QueryParam("previousName") previousName: String, @QueryParam("newName") newName: String): Response { - PersonEntity.update("lastname", newName) - .where("lastname", previousName) - return Response.ok().build() - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonName.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonName.kt deleted file mode 100644 index 5808cd7e3df1b..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonName.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.quarkus.it.mongodb.panache.person - -class PersonName { - var lastname: String? = null - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is PersonName) return false - - if (lastname != other.lastname) return false - - return true - } - - override fun hashCode(): Int { - return lastname?.hashCode() ?: 0 - } - -} diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonRepository.kt deleted file mode 100644 index d38f6b57708ab..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonRepository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.quarkus.it.mongodb.panache.person - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoRepositoryBase -import javax.enterprise.context.ApplicationScoped - -@ApplicationScoped -class PersonRepository : PanacheMongoRepositoryBase { -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonRepositoryResource.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonRepositoryResource.kt deleted file mode 100644 index 21f4581f533d8..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/person/PersonRepositoryResource.kt +++ /dev/null @@ -1,98 +0,0 @@ -package io.quarkus.it.mongodb.panache.person - -import io.quarkus.panache.common.Sort -import java.net.URI -import javax.inject.Inject -import javax.ws.rs.Consumes -import javax.ws.rs.DELETE -import javax.ws.rs.GET -import javax.ws.rs.PATCH -import javax.ws.rs.POST -import javax.ws.rs.PUT -import javax.ws.rs.Path -import javax.ws.rs.PathParam -import javax.ws.rs.Produces -import javax.ws.rs.QueryParam -import javax.ws.rs.core.MediaType -import javax.ws.rs.core.Response - -@Path("/persons/repository") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -class PersonRepositoryResource { - // fake unused injection point to force ArC to not remove this otherwise I can't mock it in the tests - @Inject - lateinit var mockablePersonRepository: MockablePersonRepository - - @Inject - lateinit var personRepository: PersonRepository - - @GET - fun getPersons(@QueryParam("sort") sort: String?): List { - return sort?.let { - personRepository.listAll(Sort.ascending(sort)) - } ?: personRepository.listAll() - } - - @GET - @Path("/search/{name}") - fun searchPersons(@PathParam("name") name: String): Set { - return personRepository.find("lastname", name) - .project(PersonName::class.java) - .list() - .toSet() - } - - @POST - fun addPerson(person: Person): Response { - personRepository.persist(person) - return Response.created(URI.create("/persons/repository/${person.id}")).build() - } - - @POST - @Path("/multiple") - fun addPersons(persons: List) { - personRepository.persist(persons) - } - - @PUT - fun updatePerson(person: Person): Response { - personRepository.update(person) - return Response.accepted().build() - } - - // PATCH is not correct here but it allows to test persistOrUpdate without a specific subpath - @PATCH - fun upsertPerson(person: Person): Response { - personRepository.persistOrUpdate(person) - return Response.accepted().build() - } - - @DELETE - @Path("/{id}") - fun deletePerson(@PathParam("id") id: String) { - val person = personRepository.findById(id.toLong()) - personRepository.delete(person!!) - } - - - @GET - @Path("/{id}") - fun getPerson(@PathParam("id") id: String) = personRepository.findById(id.toLong()) - - @GET - @Path("/count") - fun countAll(): Long = personRepository.count() - - @DELETE - fun deleteAll() { - personRepository.deleteAll() - } - - @POST - @Path("/rename") - fun rename(@QueryParam("previousName") previousName: String, @QueryParam("newName") newName: String): Response { - personRepository.update("lastname", newName).where("lastname", previousName) - return Response.ok().build() - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.kt deleted file mode 100644 index 38ebce70fb33b..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntity.kt +++ /dev/null @@ -1,53 +0,0 @@ -package io.quarkus.it.mongodb.panache.reactive.book - -import io.quarkus.it.mongodb.panache.book.BookDetail -import io.quarkus.mongodb.panache.MongoEntity -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoCompanion -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoEntity -import org.bson.codecs.pojo.annotations.BsonIgnore -import org.bson.codecs.pojo.annotations.BsonProperty -import java.time.LocalDate -import java.util.ArrayList -import javax.json.bind.annotation.JsonbDateFormat - -@MongoEntity(collection = "TheBookEntity", clientName = "cl2") -class ReactiveBookEntity : ReactivePanacheMongoEntity() { - companion object: ReactivePanacheMongoCompanion - - @BsonProperty("bookTitle") - var title: String? = null - private set - var author: String? = null - private set - - @BsonIgnore - var transientDescription: String? = null - - @JsonbDateFormat("yyyy-MM-dd") - var creationDate: LocalDate? = null - var categories: List = ArrayList() - private set - var details: BookDetail? = null - private set - - fun setTitle(title: String?): ReactiveBookEntity { - this.title = title - return this - } - - fun setAuthor(author: String?): ReactiveBookEntity { - this.author = author - return this - } - - fun setCategories(categories: List): ReactiveBookEntity { - this.categories = categories - return this - } - - fun setDetails(details: BookDetail?): ReactiveBookEntity { - this.details = details - return this - } - -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntityResource.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntityResource.kt deleted file mode 100644 index 2ff7361b04f8a..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookEntityResource.kt +++ /dev/null @@ -1,125 +0,0 @@ -package io.quarkus.it.mongodb.panache.reactive.book - -import io.quarkus.panache.common.Parameters.with -import io.quarkus.panache.common.Sort -import io.smallrye.mutiny.Uni -import org.bson.types.ObjectId -import org.jboss.logging.Logger -import org.jboss.resteasy.annotations.SseElementType -import org.reactivestreams.Publisher -import java.net.URI -import java.time.LocalDate.parse -import javax.annotation.PostConstruct -import javax.ws.rs.Consumes -import javax.ws.rs.DELETE -import javax.ws.rs.GET -import javax.ws.rs.NotFoundException -import javax.ws.rs.PATCH -import javax.ws.rs.POST -import javax.ws.rs.PUT -import javax.ws.rs.Path -import javax.ws.rs.PathParam -import javax.ws.rs.Produces -import javax.ws.rs.QueryParam -import javax.ws.rs.core.MediaType -import javax.ws.rs.core.Response - -@Path("/reactive/books/entity") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -class ReactiveBookEntityResource { - @PostConstruct - fun init() { - val databaseName: String = ReactiveBookEntity.mongoDatabase().name - val collectionName: String = ReactiveBookEntity.mongoCollection().namespace.collectionName - LOGGER.infov("Using BookEntity[database={0}, collection={1}]", databaseName, collectionName) - } - - @GET - fun getBooks(@QueryParam("sort") sort: String?): Uni> { - return if (sort != null) { - ReactiveBookEntity.listAll(Sort.ascending(sort)) - } else ReactiveBookEntity.listAll() - } - - @GET - @Path("/stream") - @Produces(MediaType.SERVER_SENT_EVENTS) - @SseElementType(MediaType.APPLICATION_JSON) - fun streamBooks(@QueryParam("sort") sort: String?): Publisher { - return if (sort != null) { - ReactiveBookEntity.streamAll(Sort.ascending(sort)) - } else ReactiveBookEntity.streamAll() - } - - @POST - fun addBook(book: ReactiveBookEntity): Uni { - return book.persist().map { - //the ID is populated before sending it to the database - Response.created(URI.create("/books/entity${book.id}")).build() - } - } - - @PUT - fun updateBook(book: ReactiveBookEntity): Uni = book.update().map { _ -> Response.accepted().build() } - - // PATCH is not correct here but it allows to test persistOrUpdate without a specific subpath - @PATCH - fun upsertBook(book: ReactiveBookEntity): Uni = - book.persistOrUpdate().map { v -> Response.accepted().build() } - - @DELETE - @Path("/{id}") - fun deleteBook(@PathParam("id") id: String?): Uni { - return ReactiveBookEntity.deleteById(ObjectId(id)) - .map { d -> - if (d) { - return@map null - } - throw NotFoundException() - } - } - - @GET - @Path("/{id}") - fun getBook(@PathParam("id") id: String?): Uni = ReactiveBookEntity.findById(ObjectId(id)) - - @GET - @Path("/search/{author}") - fun getBooksByAuthor(@PathParam("author") author: String): Uni> = - ReactiveBookEntity.list("author", author) - - @GET - @Path("/search") - fun search(@QueryParam("author") author: String?, @QueryParam("title") title: String?, - @QueryParam("dateFrom") dateFrom: String?, @QueryParam("dateTo") dateTo: String?): Uni { - return if (author != null) { - ReactiveBookEntity.find("{'author': ?1,'bookTitle': ?2}", author, title!!).firstResult() - } else ReactiveBookEntity - .find("{'creationDate': {\$gte: ?1}, 'creationDate': {\$lte: ?2}}", parse(dateFrom), - parse(dateTo)) - .firstResult() - } - - @GET - @Path("/search2") - fun search2(@QueryParam("author") author: String?, @QueryParam("title") title: String?, - @QueryParam("dateFrom") dateFrom: String?, @QueryParam("dateTo") dateTo: String?) - : Uni = - - if (author != null) { - ReactiveBookEntity.find("{'author': :author,'bookTitle': :title}", - with("author", author).and("title", title)).firstResult() - } else { - ReactiveBookEntity.find("{'creationDate': {\$gte: :dateFrom}, 'creationDate': {\$lte: :dateTo}}", - with("dateFrom", parse(dateFrom)).and("dateTo", parse(dateTo))) - .firstResult() - } - - @DELETE - fun deleteAll(): Uni = ReactiveBookEntity.deleteAll().map { l -> null } - - companion object { - private val LOGGER: Logger = Logger.getLogger(ReactiveBookEntityResource::class.java) - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookRepository.kt deleted file mode 100644 index cae81fd8d66ce..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookRepository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.quarkus.it.mongodb.panache.reactive.book - -import io.quarkus.it.mongodb.panache.book.Book -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoRepository -import javax.enterprise.context.ApplicationScoped - -@ApplicationScoped -class ReactiveBookRepository : ReactivePanacheMongoRepository \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookRepositoryResource.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookRepositoryResource.kt deleted file mode 100644 index 55a94730ce1ad..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/book/ReactiveBookRepositoryResource.kt +++ /dev/null @@ -1,128 +0,0 @@ -package io.quarkus.it.mongodb.panache.reactive.book - -import io.quarkus.it.mongodb.panache.book.Book -import io.quarkus.panache.common.Parameters -import io.quarkus.panache.common.Sort -import io.smallrye.mutiny.Uni -import org.bson.types.ObjectId -import org.jboss.logging.Logger -import org.jboss.resteasy.annotations.SseElementType -import org.reactivestreams.Publisher -import java.net.URI -import java.time.LocalDate -import javax.annotation.PostConstruct -import javax.inject.Inject -import javax.ws.rs.Consumes -import javax.ws.rs.DELETE -import javax.ws.rs.GET -import javax.ws.rs.NotFoundException -import javax.ws.rs.PATCH -import javax.ws.rs.POST -import javax.ws.rs.PUT -import javax.ws.rs.Path -import javax.ws.rs.PathParam -import javax.ws.rs.Produces -import javax.ws.rs.QueryParam -import javax.ws.rs.core.MediaType -import javax.ws.rs.core.Response - -@Path("/reactive/books/repository") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -class ReactiveBookRepositoryResource { - @Inject - lateinit var reactiveBookRepository: ReactiveBookRepository - - @PostConstruct - fun init() { - val databaseName: String = reactiveBookRepository.mongoDatabase().name - val collectionName: String = reactiveBookRepository.mongoCollection().namespace.collectionName - LOGGER.infov("Using BookRepository[database={0}, collection={1}]", databaseName, collectionName) - } - - @GET - fun getBooks(@QueryParam("sort") sort: String?): Uni> { - return if (sort != null) { - reactiveBookRepository.listAll(Sort.ascending(sort)) - } else reactiveBookRepository.listAll() - } - - @GET - @Path("/stream") - @Produces(MediaType.SERVER_SENT_EVENTS) - @SseElementType(MediaType.APPLICATION_JSON) - fun streamBooks(@QueryParam("sort") sort: String?): Publisher { - return if (sort != null) { - reactiveBookRepository.streamAll(Sort.ascending(sort)) - } else reactiveBookRepository.streamAll() - } - - @POST - fun addBook(book: Book): Uni { - return reactiveBookRepository.persist(book).map { - //the ID is populated before sending it to the database - Response.created(URI.create("/books/entity${book.id}")).build() - } - } - - @PUT - fun updateBook(book: Book): Uni = reactiveBookRepository.update(book).map { Response.accepted().build() } - - // PATCH is not correct here but it allows to test persistOrUpdate without a specific subpath - @PATCH - fun upsertBook(book: Book): Uni = - reactiveBookRepository.persistOrUpdate(book).map { Response.accepted().build() } - - @DELETE - @Path("/{id}") - fun deleteBook(@PathParam("id") id: String?): Uni { - return reactiveBookRepository.deleteById(ObjectId(id)) - .map { d -> - if (d) { - return@map null - } - throw NotFoundException() - } - } - - @GET - @Path("/{id}") - fun getBook(@PathParam("id") id: String?): Uni = reactiveBookRepository.findById(ObjectId(id)) - - @GET - @Path("/search/{author}") - fun getBooksByAuthor(@PathParam("author") author: String): Uni> = - reactiveBookRepository.list("author", author) - - @GET - @Path("/search") - fun search(@QueryParam("author") author: String?, @QueryParam("title") title: String?, - @QueryParam("dateFrom") dateFrom: String?, @QueryParam("dateTo") dateTo: String?): Uni { - return if (author != null) { - reactiveBookRepository.find("{'author': ?1,'bookTitle': ?2}", author, title!!).firstResult() - } else { - reactiveBookRepository - .find("{'creationDate': {\$gte: ?1}, 'creationDate': {\$lte: ?2}}", LocalDate.parse(dateFrom), - LocalDate.parse(dateTo)) - .firstResult() - } - } - - @GET - @Path("/search2") - fun search2(@QueryParam("author") author: String?, @QueryParam("title") title: String?, - @QueryParam("dateFrom") dateFrom: String?, @QueryParam("dateTo") dateTo: String?): Uni { - return if (author != null) { - reactiveBookRepository.find("{'author': :author,'bookTitle': :title}", - Parameters.with("author", author).and("title", title)).firstResult() - } else reactiveBookRepository.find("{'creationDate': {\$gte: :dateFrom}, 'creationDate': {\$lte: :dateTo}}", - Parameters.with("dateFrom", LocalDate.parse(dateFrom)).and("dateTo", LocalDate.parse(dateTo))).firstResult() - } - - @DELETE - fun deleteAll(): Uni = reactiveBookRepository.deleteAll().map { null } - - companion object { - private val LOGGER: Logger = Logger.getLogger(ReactiveBookRepositoryResource::class.java) - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonEntity.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonEntity.kt deleted file mode 100644 index 2e7e76a27d276..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonEntity.kt +++ /dev/null @@ -1,14 +0,0 @@ -package io.quarkus.it.mongodb.panache.reactive.person - -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoCompanionBase -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoEntityBase -import org.bson.codecs.pojo.annotations.BsonId - -class ReactivePersonEntity : ReactivePanacheMongoEntityBase() { - companion object: ReactivePanacheMongoCompanionBase - - @BsonId - var id: Long? = null - var firstname: String? = null - var lastname: String? = null -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonEntityResource.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonEntityResource.kt deleted file mode 100644 index 346e4f22e383a..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonEntityResource.kt +++ /dev/null @@ -1,88 +0,0 @@ -package io.quarkus.it.mongodb.panache.reactive.person - - -import io.quarkus.it.mongodb.panache.person.PersonName -import io.quarkus.panache.common.Sort -import io.smallrye.mutiny.Uni -import java.net.URI -import javax.ws.rs.Consumes -import javax.ws.rs.DELETE -import javax.ws.rs.GET -import javax.ws.rs.PATCH -import javax.ws.rs.POST -import javax.ws.rs.PUT -import javax.ws.rs.Path -import javax.ws.rs.PathParam -import javax.ws.rs.Produces -import javax.ws.rs.QueryParam -import javax.ws.rs.core.MediaType -import javax.ws.rs.core.Response - -@Path("/reactive/persons/entity") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -class ReactivePersonEntityResource { - @GET - fun getPersons(@QueryParam("sort") sort: String?): Uni> { - return if (sort != null) { - ReactivePersonEntity.listAll(Sort.ascending(sort)) - } else ReactivePersonEntity.listAll() - } - - @GET - @Path("/search/{name}") - fun searchPersons(@PathParam("name") name: String): Set { - val uniqueNames = mutableSetOf() - val lastnames: List = ReactivePersonEntity.find("lastname", name) - .project(PersonName::class.java) - .list() - .await() - .indefinitely() - lastnames.forEach { p -> uniqueNames.add(p) } - return uniqueNames - } - - @POST - fun addPerson(person: ReactivePersonEntity): Uni { - return person.persist() - .map { Response.created(URI.create("/persons/entity${person.id}")).build() } - } - - @POST - @Path("/multiple") - fun addPersons(persons: List): Uni = ReactivePersonEntity.persist(persons) - - @PUT - fun updatePerson(person: ReactivePersonEntity): Uni = - person.update().map { Response.accepted().build() } - - // PATCH is not correct here but it allows to test persistOrUpdate without a specific subpath - @PATCH - fun upsertPerson(person: ReactivePersonEntity): Uni = - person.persistOrUpdate().map { Response.accepted().build() } - - @DELETE - @Path("/{id}") - fun deletePerson(@PathParam("id") id: String): Uni = - ReactivePersonEntity.findById(id.toLong()).flatMap { person -> person.delete() } - - @GET - @Path("/{id}") - fun getPerson(@PathParam("id") id: String): Uni = - ReactivePersonEntity.findById(id.toLong()) - - @GET - @Path("/count") - fun countAll(): Uni = ReactivePersonEntity.count() - - @DELETE - fun deleteAll(): Uni = ReactivePersonEntity.deleteAll().map { null } - - @POST - @Path("/rename") - fun rename(@QueryParam("previousName") previousName: String, @QueryParam("newName") newName: String): Uni { - return ReactivePersonEntity.update("lastname", newName) - .where("lastname", previousName) - .map { count -> Response.ok().build() } - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonRepository.kt deleted file mode 100644 index e14dd7e9e5379..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonRepository.kt +++ /dev/null @@ -1,8 +0,0 @@ -package io.quarkus.it.mongodb.panache.reactive.person - -import io.quarkus.it.mongodb.panache.person.Person -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoRepositoryBase -import javax.enterprise.context.ApplicationScoped - -@ApplicationScoped -class ReactivePersonRepository : ReactivePanacheMongoRepositoryBase \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonRepositoryResource.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonRepositoryResource.kt deleted file mode 100644 index 2dccf07605b22..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/reactive/person/ReactivePersonRepositoryResource.kt +++ /dev/null @@ -1,95 +0,0 @@ -package io.quarkus.it.mongodb.panache.reactive.person - - -import io.quarkus.it.mongodb.panache.person.Person -import io.quarkus.it.mongodb.panache.person.PersonName -import io.quarkus.panache.common.Sort -import io.smallrye.mutiny.Uni -import java.net.URI -import javax.inject.Inject -import javax.ws.rs.Consumes -import javax.ws.rs.DELETE -import javax.ws.rs.GET -import javax.ws.rs.PATCH -import javax.ws.rs.POST -import javax.ws.rs.PUT -import javax.ws.rs.Path -import javax.ws.rs.PathParam -import javax.ws.rs.Produces -import javax.ws.rs.QueryParam -import javax.ws.rs.core.MediaType -import javax.ws.rs.core.Response - -@Path("/reactive/persons/repository") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -class ReactivePersonRepositoryResource { - @Inject - lateinit var reactivePersonRepository: ReactivePersonRepository - - @GET - fun getPersons(@QueryParam("sort") sort: String?): Uni> { - return if (sort != null) { - reactivePersonRepository.listAll(Sort.ascending(sort)) - } else reactivePersonRepository.listAll() - } - - @GET - @Path("/search/{name}") - fun searchPersons(@PathParam("name") name: String): Set { - val uniqueNames = mutableSetOf() - val lastnames: List = reactivePersonRepository.find("lastname", name) - .project(PersonName::class.java) - .list() - .await() - .indefinitely() - lastnames.forEach { p -> uniqueNames.add(p) } // this will throw if it's not the right type - return uniqueNames - } - - @POST - fun addPerson(person: Person): Uni { - return reactivePersonRepository.persist(person).map { - //the ID is populated before sending it to the database - Response.created(URI.create("/persons/entity${person.id}")).build() - } - } - - @POST - @Path("/multiple") - fun addPersons(persons: List): Uni = reactivePersonRepository.persist(persons) - - @PUT - fun updatePerson(person: Person): Uni = - reactivePersonRepository.update(person).map { Response.accepted().build() } - - // PATCH is not correct here but it allows to test persistOrUpdate without a specific subpath - @PATCH - fun upsertPerson(person: Person): Uni = - reactivePersonRepository.persistOrUpdate(person).map { v -> Response.accepted().build() } - - @DELETE - @Path("/{id}") - fun deletePerson(@PathParam("id") id: String): Uni { - return reactivePersonRepository.findById(id.toLong()) - .flatMap { person -> reactivePersonRepository.delete(person) } - } - - @GET - @Path("/{id}") - fun getPerson(@PathParam("id") id: String): Uni = reactivePersonRepository.findById(id.toLong()) - - @GET - @Path("/count") - fun countAll(): Uni = reactivePersonRepository.count() - - @DELETE - fun deleteAll(): Uni = reactivePersonRepository.deleteAll().map { null } - - @POST - @Path("/rename") - fun rename(@QueryParam("previousName") previousName: String, @QueryParam("newName") newName: String): Uni { - return reactivePersonRepository.update("lastname", newName).where("lastname", previousName) - .map { count -> Response.ok().build() } - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestImperativeEntity.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestImperativeEntity.kt deleted file mode 100644 index 952e43611e65f..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestImperativeEntity.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.quarkus.it.mongodb.panache.test - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoCompanion -import io.quarkus.mongodb.panache.kotlin.PanacheMongoEntity - -class TestImperativeEntity : PanacheMongoEntity { - companion object : PanacheMongoCompanion - - lateinit var title: String - lateinit var category: String - lateinit var description: String - - constructor() {} - constructor(title: String, category: String, description: String) { - this.title = title - this.category = category - this.description = description - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestImperativeRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestImperativeRepository.kt deleted file mode 100644 index 19fb094764583..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestImperativeRepository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.quarkus.it.mongodb.panache.test - -import io.quarkus.mongodb.panache.kotlin.PanacheMongoRepository -import javax.enterprise.context.ApplicationScoped - -@ApplicationScoped -class TestImperativeRepository : PanacheMongoRepository \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestReactiveEntity.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestReactiveEntity.kt deleted file mode 100644 index f1df4203bbd3d..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestReactiveEntity.kt +++ /dev/null @@ -1,18 +0,0 @@ -package io.quarkus.it.mongodb.panache.test - -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoCompanion -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoEntity - -class TestReactiveEntity : ReactivePanacheMongoEntity { - companion object : ReactivePanacheMongoCompanion - lateinit var title: String - lateinit var category: String - lateinit var description: String - - constructor() {} - constructor(title: String, category: String, description: String) { - this.title = title - this.category = category - this.description = description - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestReactiveRepository.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestReactiveRepository.kt deleted file mode 100644 index 383a4855c3420..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestReactiveRepository.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.quarkus.it.mongodb.panache.test - -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheMongoRepository -import javax.enterprise.context.ApplicationScoped - -@ApplicationScoped -class TestReactiveRepository : ReactivePanacheMongoRepository \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestResource.kt b/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestResource.kt deleted file mode 100644 index 9fff5f13c6a6d..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/kotlin/io/quarkus/it/mongodb/panache/test/TestResource.kt +++ /dev/null @@ -1,745 +0,0 @@ -package io.quarkus.it.mongodb.panache.test - -import com.mongodb.client.model.Collation -import com.mongodb.client.model.CollationStrength -import io.quarkus.mongodb.panache.kotlin.PanacheQuery -import io.quarkus.mongodb.panache.kotlin.reactive.ReactivePanacheQuery -import io.quarkus.panache.common.Page -import io.quarkus.panache.common.Parameters -import io.quarkus.panache.common.Sort -import org.bson.Document -import org.junit.jupiter.api.Assertions -import javax.inject.Inject -import javax.ws.rs.GET -import javax.ws.rs.Path -import javax.ws.rs.core.Response - -@Path("/test") -class TestResource { - @Inject - lateinit var testImperativeRepository: TestImperativeRepository - - @Inject - lateinit var testReactiveRepository: TestReactiveRepository - - private val testImperativeEntities: List by lazy { - (0..9).map { TestImperativeEntity("title$it", "category" + it % 2, "description$it") } - } - - @GET - @Path("imperative/entity") - fun testImperativeEntity(): Response { - val entities: List = testImperativeEntities - - // insert all - Assertions.assertEquals(0, TestImperativeEntity.count()) - TestImperativeEntity.persist(entities) - Assertions.assertEquals(10, TestImperativeEntity.count()) - - // varargs - val entity11 = TestImperativeEntity("title11", "category", "desc") - val entity12 = TestImperativeEntity("title11", "category", "desc") - TestImperativeEntity.persist(entity11, entity12) - Assertions.assertEquals(12, TestImperativeEntity.count()) - entity11.category = "categoryUpdated" - entity12.category = "categoryUpdated" - TestImperativeEntity.update(entity11, entity12) - entity11.delete() - entity12.delete() - TestImperativeEntity.persistOrUpdate(entity11, entity12) - Assertions.assertEquals(12, TestImperativeEntity.count()) - entity11.category = "categoryUpdated" - entity12.category = "categoryUpdated" - TestImperativeEntity.persistOrUpdate(entity11, entity12) - entity11.delete() - entity12.delete() - Assertions.assertEquals(10, TestImperativeEntity.count()) - - // paginate - testImperativePagination(TestImperativeEntity.findAll()) - - // range - testImperativeRange(TestImperativeEntity.findAll()) - - // query - Assertions.assertEquals(5, TestImperativeEntity.list("category", "category0").size) - Assertions.assertEquals(5, TestImperativeEntity.list("category = ?1", "category0").size) - Assertions.assertEquals(5, TestImperativeEntity.list("category = :category", - Parameters.with("category", "category1")).size) - Assertions.assertEquals(5, TestImperativeEntity.list("{'category' : ?1}", "category0").size) - Assertions.assertEquals(5, TestImperativeEntity.list("{'category' : :category}", - Parameters.with("category", "category1")).size) - val listQuery: Document = Document().append("category", "category1") - Assertions.assertEquals(5, TestImperativeEntity.list(listQuery).size) - Assertions.assertEquals(0, TestImperativeEntity.list("category", null).size) - Assertions.assertEquals(0, TestImperativeEntity.list("category = :category", - Parameters.with("category", null)).size) - - // regex - val entityWithUpperCase = TestImperativeEntity("title11", "upperCaseCategory", "desc") - entityWithUpperCase.persist() - Assertions.assertEquals(1, TestImperativeEntity.list("category like ?1", "upperCase.*").size) - Assertions.assertEquals(1, TestImperativeEntity.list("category like ?1", "/uppercase.*/i").size) - entityWithUpperCase.delete() - - // sort - val entityA = TestImperativeEntity("aaa", "aaa", "aaa") - entityA.persist() - val entityZ = TestImperativeEntity("zzz", "zzz", "zzz") - entityZ.persistOrUpdate() - var result: TestImperativeEntity = TestImperativeEntity.listAll(Sort.ascending("title"))[0] - Assertions.assertEquals("aaa", result.title) - result = TestImperativeEntity.listAll(Sort.descending("title"))[0] - Assertions.assertEquals("zzz", result.title) - entityA.delete() - entityZ.delete() - - // collation - val entityALower = TestImperativeEntity("aaa", "aaa", "aaa") - entityALower.persist() - val entityAUpper = TestImperativeEntity("AAA", "AAA", "AAA") - entityAUpper.persist() - val entityB = TestImperativeEntity("BBB", "BBB", "BBB") - entityB.persistOrUpdate() - var results: List = TestImperativeEntity.listAll(Sort.ascending("title")) - Assertions.assertEquals("AAA", results[0].title) - Assertions.assertEquals("BBB", results[1].title) - Assertions.assertEquals("aaa", results[2].title) - val collation: Collation = Collation.builder().caseLevel(true).collationStrength(CollationStrength.PRIMARY).locale("fr") - .build() - results = TestImperativeEntity.findAll(Sort.ascending("title")).withCollation(collation).list() - Assertions.assertEquals("aaa", results[0].title) - Assertions.assertEquals("AAA", results[1].title) - Assertions.assertEquals("BBB", results[2].title) - entityAUpper.delete() - entityALower.delete() - entityB.delete() - - // count - Assertions.assertEquals(5, TestImperativeEntity.count("category", "category0")) - Assertions.assertEquals(5, TestImperativeEntity.count("category = ?1", "category0")) - Assertions.assertEquals(5, TestImperativeEntity.count("category = :category", - Parameters.with("category", "category1"))) - Assertions.assertEquals(5, TestImperativeEntity.count("{'category' : ?1}", "category0")) - Assertions.assertEquals(5, TestImperativeEntity.count("{'category' : :category}", - Parameters.with("category", "category1"))) - val countQuery: Document = Document().append("category", "category1") - Assertions.assertEquals(5, TestImperativeEntity.count(countQuery)) - - // update - val list: List = TestImperativeEntity.list("category = ?1", "category0") - Assertions.assertEquals(5, list.size) - for (entity in list) { - entity.category = "newCategory" - } - TestImperativeEntity.update(list) - TestImperativeEntity.update(list.stream()) - TestImperativeEntity.persistOrUpdate(list) - var updated: Long = TestImperativeEntity.update("category", "newCategory2").where("category", "newCategory") - Assertions.assertEquals(5, updated) - updated = TestImperativeEntity.update("category = ?1", "newCategory").where("category = ?1", "newCategory2") - Assertions.assertEquals(5, updated) - updated = TestImperativeEntity.update("{'category' : ?1}", "newCategory2").where("{'category' : ?1}", "newCategory") - Assertions.assertEquals(5, updated) - updated = TestImperativeEntity.update("category = :category", Parameters.with("category", "newCategory")) - .where("category = :category", Parameters.with("category", "newCategory2")) - Assertions.assertEquals(5, updated) - updated = TestImperativeEntity.update("{'category' : :category}", Parameters.with("category", "newCategory2")) - .where("{'category' : :category}", Parameters.with("category", "newCategory")) - Assertions.assertEquals(5, updated) - Assertions.assertEquals(5, TestImperativeEntity.count("category = ?1", "newCategory2")) - updated = TestImperativeEntity.update("newField", "newValue").all() - Assertions.assertEquals(10, updated) - - // delete - TestImperativeEntity.delete("category = ?1", "newCategory2") - TestImperativeEntity.delete("{'category' : ?1}", "category1") - Assertions.assertEquals(0, TestImperativeEntity.count()) - TestImperativeEntity.persist(entities.stream()) - TestImperativeEntity.delete("category = :category", Parameters.with("category", "category0")) - TestImperativeEntity.delete("{'category' : :category}", Parameters.with("category", "category1")) - Assertions.assertEquals(0, TestImperativeEntity.count()) - TestImperativeEntity.persistOrUpdate(entities.stream()) - TestImperativeEntity.delete("category", "category0") - TestImperativeEntity.delete("category", "category1") - Assertions.assertEquals(0, TestImperativeEntity.count()) - return Response.ok().build() - } - - @GET - @Path("imperative/repository") - fun testImperativeRepository(): Response { - val entities: List = testImperativeEntities - - // insert all - Assertions.assertEquals(0, testImperativeRepository.count()) - testImperativeRepository.persist(entities) - Assertions.assertEquals(10, testImperativeRepository.count()) - - // varargs - val entity11 = TestImperativeEntity("title11", "category", "desc") - val entity12 = TestImperativeEntity("title11", "category", "desc") - testImperativeRepository.persist(entity11, entity12) - Assertions.assertEquals(12, testImperativeRepository.count()) - entity11.category = "categoryUpdated" - entity12.category = "categoryUpdated" - testImperativeRepository.update(entity11, entity12) - entity11.delete() - entity12.delete() - testImperativeRepository.persistOrUpdate(entity11, entity12) - Assertions.assertEquals(12, testImperativeRepository.count()) - entity11.category = "categoryUpdated" - entity12.category = "categoryUpdated" - testImperativeRepository.persistOrUpdate(entity11, entity12) - entity11.delete() - entity12.delete() - Assertions.assertEquals(10, testImperativeRepository.count()) - - // paginate - testImperativePagination(testImperativeRepository.findAll()) - - // range - testImperativeRange(testImperativeRepository.findAll()) - - // query - Assertions.assertEquals(5, testImperativeRepository.list("category", "category0").size) - Assertions.assertEquals(5, testImperativeRepository.list("category = ?1", "category0").size) - Assertions.assertEquals(5, testImperativeRepository.list("category = :category", - Parameters.with("category", "category1")).size) - Assertions.assertEquals(5, testImperativeRepository.list("{'category' : ?1}", "category0").size) - Assertions.assertEquals(5, testImperativeRepository.list("{'category' : :category}", - Parameters.with("category", "category1")).size) - val listQuery: Document = Document().append("category", "category1") - Assertions.assertEquals(5, testImperativeRepository.list(listQuery).size) - Assertions.assertEquals(0, testImperativeRepository.list("category", null).size) - Assertions.assertEquals(0, testImperativeRepository.list("category = :category", - Parameters.with("category", null)).size) - - // regex - val entityWithUpperCase = TestImperativeEntity("title11", "upperCaseCate)gory", "desc") - testImperativeRepository.persist(entityWithUpperCase) - Assertions.assertEquals(1, testImperativeRepository.list("category like ?1", "upperCase.*").size) - Assertions.assertEquals(1, testImperativeRepository.list("category like ?1", "/uppercase.*/i").size) - testImperativeRepository.delete(entityWithUpperCase) - - // sort - val entityA = TestImperativeEntity("aaa", "aaa", "aaa") - testImperativeRepository.persist(entityA) - val entityZ = TestImperativeEntity("zzz", "zzz", "zzz") - testImperativeRepository.persistOrUpdate(entityZ) - var result: TestImperativeEntity = testImperativeRepository.listAll(Sort.ascending("title"))[0] - Assertions.assertEquals("aaa", result.title) - result = testImperativeRepository.listAll(Sort.descending("title"))[0] - Assertions.assertEquals("zzz", result.title) - testImperativeRepository.delete(entityA) - testImperativeRepository.delete(entityZ) - - // collation - val entityALower = TestImperativeEntity("aaa", "aaa", "aaa") - testImperativeRepository.persist(entityALower) - val entityAUpper = TestImperativeEntity("AAA", "AAA", "AAA") - testImperativeRepository.persist(entityAUpper) - val entityB = TestImperativeEntity("BBB", "BBB", "BBB") - testImperativeRepository.persistOrUpdate(entityB) - var results: List = testImperativeRepository.listAll(Sort.ascending("title")) - Assertions.assertEquals("AAA", results[0].title) - Assertions.assertEquals("BBB", results[1].title) - Assertions.assertEquals("aaa", results[2].title) - val collation: Collation = Collation.builder().caseLevel(true).collationStrength(CollationStrength.PRIMARY).locale("fr") - .build() - results = testImperativeRepository.findAll(Sort.ascending("title")) - .withCollation(collation) - .list() - Assertions.assertEquals("aaa", results[0].title) - Assertions.assertEquals("AAA", results[1].title) - Assertions.assertEquals("BBB", results[2].title) - testImperativeRepository.delete(entityALower) - testImperativeRepository.delete(entityAUpper) - testImperativeRepository.delete(entityB) - - // count - Assertions.assertEquals(5, testImperativeRepository.count("category", "category0")) - Assertions.assertEquals(5, testImperativeRepository.count("category = ?1", "category0")) - Assertions.assertEquals(5, testImperativeRepository.count("category = :category", - Parameters.with("category", "category1"))) - Assertions.assertEquals(5, testImperativeRepository.count("{'category' : ?1}", "category0")) - Assertions.assertEquals(5, testImperativeRepository.count("{'category' : :category}", - Parameters.with("category", "category1"))) - val countQuery: Document = Document().append("category", "category1") - Assertions.assertEquals(5, testImperativeRepository.count(countQuery)) - - // update - val list: List = testImperativeRepository.list("category = ?1", "category0") - Assertions.assertEquals(5, list.size) - for (entity in list) { - entity.category = "newCategory" - } - testImperativeRepository.update(list) - testImperativeRepository.update(list.stream()) - testImperativeRepository.persistOrUpdate(list) - var updated: Long = testImperativeRepository.update("category", "newCategory2").where("category", "newCategory") - Assertions.assertEquals(5, updated) - updated = testImperativeRepository.update("category = ?1", "newCategory").where("category = ?1", "newCategory2") - Assertions.assertEquals(5, updated) - updated = testImperativeRepository.update("{'category' : ?1}", "newCategory2").where("{'category' : ?1}", - "newCategory") - Assertions.assertEquals(5, updated) - updated = testImperativeRepository.update("category = :category", Parameters.with("category", "newCategory")) - .where("category = :category", Parameters.with("category", "newCategory2")) - Assertions.assertEquals(5, updated) - updated = testImperativeRepository.update("{'category' : :category}", Parameters.with("category", "newCategory2")) - .where("{'category' : :category}", Parameters.with("category", "newCategory")) - Assertions.assertEquals(5, updated) - Assertions.assertEquals(5, testImperativeRepository.count("category = ?1", "newCategory2")) - updated = testImperativeRepository.update("newField", "newValue").all() - Assertions.assertEquals(10, updated) - - // delete - testImperativeRepository.delete("category = ?1", "newCategory2") - testImperativeRepository.delete("{'category' : ?1}", "category1") - Assertions.assertEquals(0, testImperativeRepository.count()) - testImperativeRepository.persist(entities.stream()) - testImperativeRepository.delete("category = :category", Parameters.with("category", "category0")) - testImperativeRepository.delete("{'category' : :category}", Parameters.with("category", "category1")) - Assertions.assertEquals(0, testImperativeRepository.count()) - testImperativeRepository.persistOrUpdate(entities.stream()) - testImperativeRepository.delete("category", "category0") - testImperativeRepository.delete("category", "category1") - Assertions.assertEquals(0, testImperativeRepository.count()) - return Response.ok().build() - } - - private fun testImperativePagination(query: PanacheQuery) { - query.page(0, 4) - Assertions.assertEquals(3, query.pageCount()) - var page: List = query.list() - Assertions.assertEquals(4, page.size) - Assertions.assertTrue(query.hasNextPage()) - Assertions.assertFalse(query.hasPreviousPage()) - query.nextPage() - page = query.list() - Assertions.assertEquals(4, page.size) - Assertions.assertTrue(query.hasNextPage()) - Assertions.assertTrue(query.hasPreviousPage()) - query.lastPage() - page = query.list() - Assertions.assertEquals(2, page.size) - Assertions.assertFalse(query.hasNextPage()) - Assertions.assertTrue(query.hasPreviousPage()) - query.firstPage() - page = query.list() - Assertions.assertEquals(4, page.size) - Assertions.assertTrue(query.hasNextPage()) - Assertions.assertFalse(query.hasPreviousPage()) - query.page(Page.of(1, 5)) - Assertions.assertEquals(2, query.pageCount()) - page = query.list() - Assertions.assertEquals(5, page.size) - Assertions.assertFalse(query.hasNextPage()) - Assertions.assertTrue(query.hasPreviousPage()) - - // mix page with range - page = query.page(0, 3).range(0, 1).list() - Assertions.assertEquals(2, page.size) - } - - private fun testImperativeRange(query: PanacheQuery) { - query.range(0, 3) - var range: List = query.list() - Assertions.assertEquals(4, range.size) - range = query.range(4, 7).list() - Assertions.assertEquals(4, range.size) - range = query.range(8, 12).list() - Assertions.assertEquals(2, range.size) - range = query.range(10, 12).list() - Assertions.assertEquals(0, range.size) - - // when using range, we cannot use any of the page related operations - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).nextPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).previousPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).pageCount() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).lastPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).firstPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).hasPreviousPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).hasNextPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).page() } - - // but this is valid to switch from range to page - range = query.range(0, 2).page(0, 3).list() - Assertions.assertEquals(3, range.size) - } - - @GET - @Path("reactive/entity") - fun testReactiveEntity(): Response { - val entities: List = testReactiveEntities - - // insert all - Assertions.assertEquals(0, TestReactiveEntity.count().await().indefinitely()) - TestReactiveEntity.persist(entities).await().indefinitely() - Assertions.assertEquals(10, TestReactiveEntity.count().await().indefinitely()) - - // varargs - val entity11 = TestReactiveEntity("title11", "category", "desc") - val entity12 = TestReactiveEntity("title11", "category", "desc") - TestReactiveEntity.persist(entity11, entity12).await().indefinitely() - Assertions.assertEquals(12, TestReactiveEntity.count().await().indefinitely()) - entity11.category = "categoryUpdated" - entity12.category = "categoryUpdated" - TestReactiveEntity.update(entity11, entity12).await().indefinitely() - entity11.delete().await().indefinitely() - entity12.delete().await().indefinitely() - TestReactiveEntity.persistOrUpdate(entity11, entity12).await().indefinitely() - Assertions.assertEquals(12, TestReactiveEntity.count().await().indefinitely()) - entity11.category = "categoryUpdated" - entity12.category = "categoryUpdated" - TestReactiveEntity.persistOrUpdate(entity11, entity12).await().indefinitely() - entity11.delete().await().indefinitely() - entity12.delete().await().indefinitely() - Assertions.assertEquals(10, TestReactiveEntity.count().await().indefinitely()) - - // paginate - testReactivePagination(TestReactiveEntity.findAll()) - - // range - testReactiveRange(TestReactiveEntity.findAll()) - - // query - Assertions.assertEquals(5, - TestReactiveEntity.list("category", "category0").await().indefinitely().size) - Assertions.assertEquals(5, - TestReactiveEntity.list("category = ?1", "category0").await().indefinitely().size) - Assertions.assertEquals(5, TestReactiveEntity.list("category = :category", - Parameters.with("category", "category1")).await().indefinitely().size) - Assertions.assertEquals(5, - TestReactiveEntity.list("{'category' : ?1}", "category0").await().indefinitely().size) - Assertions.assertEquals(5, TestReactiveEntity.list("{'category' : :category}", - Parameters.with("category", "category1")).await().indefinitely().size) - val listQuery: Document = Document().append("category", "category1") - Assertions.assertEquals(5, TestReactiveEntity.list(listQuery).await().indefinitely().size) - Assertions.assertEquals(0, TestReactiveEntity.list("category", null).await().indefinitely().size) - Assertions.assertEquals(0, TestReactiveEntity.list("category = :category", - Parameters.with("category", null)).await().indefinitely().size) - - // regex - val entityWithUpperCase = TestReactiveEntity("title11", "upperCaseCategory", "desc") - entityWithUpperCase.persist().await().indefinitely() - Assertions.assertEquals(1, TestReactiveEntity.list("category like ?1", "upperCase.*") - .await().indefinitely().size) - Assertions.assertEquals(1, TestReactiveEntity.list("category like ?1", "/uppercase.*/i") - .await().indefinitely().size) - entityWithUpperCase.delete().await().indefinitely() - - // sort - val entityA = TestReactiveEntity("aaa", "aaa", "aaa") - entityA.persist().await().indefinitely() - val entityZ = TestReactiveEntity("zzz", "zzz", "zzz") - entityZ.persistOrUpdate().await().indefinitely() - var result: TestReactiveEntity = TestReactiveEntity.listAll(Sort.ascending("title")).await() - .indefinitely()[0] - Assertions.assertEquals("aaa", result.title) - result = TestReactiveEntity.listAll(Sort.descending("title")).await().indefinitely()[0] - Assertions.assertEquals("zzz", result.title) - entityA.delete().await().indefinitely() - entityZ.delete().await().indefinitely() - - // collation - val entityALower = TestReactiveEntity("aaa", "aaa", "aaa") - entityALower.persist().await().indefinitely() - val entityAUpper = TestReactiveEntity("AAA", "AAA", "AAA") - entityAUpper.persist().await().indefinitely() - val entityB = TestReactiveEntity("BBB", "BBB", "BBB") - entityB.persistOrUpdate().await().indefinitely() - var results: List = TestReactiveEntity.listAll(Sort.ascending("title")).await() - .indefinitely() - Assertions.assertEquals("AAA", results[0].title) - Assertions.assertEquals("BBB", results[1].title) - Assertions.assertEquals("aaa", results[2].title) - val collation: Collation = Collation.builder().caseLevel(true).collationStrength(CollationStrength.PRIMARY).locale("fr") - .build() - results = TestReactiveEntity.findAll( Sort.ascending("title")).withCollation(collation).list() - .await().indefinitely() - Assertions.assertEquals("aaa", results[0].title) - Assertions.assertEquals("AAA", results[1].title) - Assertions.assertEquals("BBB", results[2].title) - entityAUpper.delete().await().indefinitely() - entityALower.delete().await().indefinitely() - entityB.delete().await().indefinitely() - - // count - Assertions.assertEquals(5, TestReactiveEntity.count("category", "category0").await().indefinitely()) - Assertions.assertEquals(5, TestReactiveEntity.count("category = ?1", "category0").await().indefinitely()) - Assertions.assertEquals(5, TestReactiveEntity.count("category = :category", - Parameters.with("category", "category1")).await().indefinitely()) - Assertions.assertEquals(5, TestReactiveEntity.count("{'category' : ?1}", "category0").await().indefinitely()) - Assertions.assertEquals(5, TestReactiveEntity.count("{'category' : :category}", - Parameters.with("category", "category1")).await().indefinitely()) - val countQuery: Document = Document().append("category", "category1") - Assertions.assertEquals(5, TestReactiveEntity.count(countQuery).await().indefinitely()) - - // update - val list: List = TestReactiveEntity.list("category = ?1", "category0").await() - .indefinitely() - Assertions.assertEquals(5, list.size) - for (entity in list) { - entity.category = "newCategory" - } - TestReactiveEntity.update(list).await().indefinitely() - TestReactiveEntity.update(list.stream()).await().indefinitely() - TestReactiveEntity.persistOrUpdate(list).await().indefinitely() - var updated: Long = TestReactiveEntity.update("category", "newCategory2").where("category", "newCategory").await() - .indefinitely() - Assertions.assertEquals(5, updated) - updated = TestReactiveEntity.update("category = ?1", "newCategory").where("category = ?1", "newCategory2").await() - .indefinitely() - Assertions.assertEquals(5, updated) - updated = TestReactiveEntity.update("{'category' : ?1}", "newCategory2").where("{'category' : ?1}", "newCategory") - .await().indefinitely() - Assertions.assertEquals(5, updated) - updated = TestReactiveEntity.update("category = :category", Parameters.with("category", "newCategory")) - .where("category = :category", Parameters.with("category", "newCategory2")).await().indefinitely() - Assertions.assertEquals(5, updated) - updated = TestReactiveEntity.update("{'category' : :category}", Parameters.with("category", "newCategory2")) - .where("{'category' : :category}", Parameters.with("category", "newCategory")).await().indefinitely() - Assertions.assertEquals(5, updated) - Assertions.assertEquals(5, TestReactiveEntity.count("category = ?1", "newCategory2").await().indefinitely()) - updated = TestReactiveEntity.update("newField", "newValue").all().await().indefinitely() - Assertions.assertEquals(10, updated) - - // delete - TestReactiveEntity.delete("category = ?1", "newCategory2").await().indefinitely() - TestReactiveEntity.delete("{'category' : ?1}", "category1").await().indefinitely() - Assertions.assertEquals(0, TestReactiveEntity.count().await().indefinitely()) - TestReactiveEntity.persist(entities.stream()).await().indefinitely() - TestReactiveEntity.delete("category = :category", Parameters.with("category", "category0")).await().indefinitely() - TestReactiveEntity.delete("{'category' : :category}", Parameters.with("category", "category1")).await().indefinitely() - Assertions.assertEquals(0, TestReactiveEntity.count().await().indefinitely()) - TestReactiveEntity.persistOrUpdate(entities.stream()).await().indefinitely() - TestReactiveEntity.delete("category", "category0").await().indefinitely() - TestReactiveEntity.delete("category", "category1").await().indefinitely() - Assertions.assertEquals(0, TestReactiveEntity.count().await().indefinitely()) - return Response.ok().build() - } - - @GET - @Path("reactive/repository") - fun testReactiveRepository(): Response { - val entities: List = testReactiveEntities - - // insert all - Assertions.assertEquals(0, testReactiveRepository.count().await().indefinitely()) - testReactiveRepository.persist(entities).await().indefinitely() - Assertions.assertEquals(10, testReactiveRepository.count().await().indefinitely()) - - // varargs - val entity11 = TestReactiveEntity("title11", "category", "desc") - val entity12 = TestReactiveEntity("title11", "category", "desc") - testReactiveRepository.persist(entity11, entity12).await().indefinitely() - Assertions.assertEquals(12, testReactiveRepository.count().await().indefinitely()) - entity11.category = "categoryUpdated" - entity12.category = "categoryUpdated" - testReactiveRepository.update(entity11, entity12).await().indefinitely() - entity11.delete().await().indefinitely() - entity12.delete().await().indefinitely() - testReactiveRepository.persistOrUpdate(entity11, entity12).await().indefinitely() - Assertions.assertEquals(12, testReactiveRepository.count().await().indefinitely()) - entity11.category = "categoryUpdated" - entity12.category = "categoryUpdated" - testReactiveRepository.persistOrUpdate(entity11, entity12).await().indefinitely() - entity11.delete().await().indefinitely() - entity12.delete().await().indefinitely() - Assertions.assertEquals(10, testReactiveRepository.count().await().indefinitely()) - - // paginate - testReactivePagination(testReactiveRepository.findAll()) - - // range - testReactiveRange(testReactiveRepository.findAll()) - - // query - Assertions.assertEquals(5, - testReactiveRepository.list("category", "category0").await().indefinitely().size) - Assertions.assertEquals(5, - testReactiveRepository.list("category = ?1", "category0").await().indefinitely().size) - Assertions.assertEquals(5, testReactiveRepository.list("category = :category", - Parameters.with("category", "category1")).await().indefinitely().size) - Assertions.assertEquals(5, - testReactiveRepository.list("{'category' : ?1}", "category0").await().indefinitely().size) - Assertions.assertEquals(5, testReactiveRepository.list("{'category' : :category}", - Parameters.with("category", "category1")).await().indefinitely().size) - val listQuery: Document = Document().append("category", "category1") - Assertions.assertEquals(5, testReactiveRepository.list(listQuery).await().indefinitely().size) - Assertions.assertEquals(0, testReactiveRepository.list("category", null).await().indefinitely().size) - Assertions.assertEquals(0, testReactiveRepository.list("category = :category", - Parameters.with("category", null)).await().indefinitely().size) - - // regex - val entityWithUpperCase = TestReactiveEntity("title11", "upperCaseCategory", "desc") - testReactiveRepository.persist(entityWithUpperCase).await().indefinitely() - Assertions.assertEquals(1, testReactiveRepository.list("category like ?1", "upperCase.*") - .await().indefinitely().size) - Assertions.assertEquals(1, testReactiveRepository.list("category like ?1", "/uppercase.*/i") - .await().indefinitely().size) - testReactiveRepository.delete(entityWithUpperCase).await().indefinitely() - - // sort - val entityA = TestReactiveEntity("aaa", "aaa", "aaa") - testReactiveRepository.persist(entityA).await().indefinitely() - val entityZ = TestReactiveEntity("zzz", "zzz", "zzz") - testReactiveRepository.persistOrUpdate(entityZ).await().indefinitely() - var result: TestReactiveEntity = testReactiveRepository.listAll(Sort.ascending("title")).await().indefinitely()[0] - Assertions.assertEquals("aaa", result.title) - result = testReactiveRepository.listAll(Sort.descending("title")).await().indefinitely()[0] - Assertions.assertEquals("zzz", result.title) - testReactiveRepository.delete(entityA).await().indefinitely() - testReactiveRepository.delete(entityZ).await().indefinitely() - - // collation - val entityALower = TestReactiveEntity("aaa", "aaa", "aaa") - testReactiveRepository.persist(entityALower).await().indefinitely() - val entityAUpper = TestReactiveEntity("AAA", "AAA", "AAA") - testReactiveRepository.persist(entityAUpper).await().indefinitely() - val entityB = TestReactiveEntity("BBB", "BBB", "BBB") - testReactiveRepository.persistOrUpdate(entityB).await().indefinitely() - var results: List = testReactiveRepository.listAll(Sort.ascending("title")).await().indefinitely() - Assertions.assertEquals("AAA", results[0].title) - Assertions.assertEquals("BBB", results[1].title) - Assertions.assertEquals("aaa", results[2].title) - val collation: Collation = Collation.builder().caseLevel(true).collationStrength(CollationStrength.PRIMARY).locale("fr") - .build() - results = testReactiveRepository.findAll(Sort.ascending("title")).withCollation(collation).list().await() - .indefinitely() - Assertions.assertEquals("aaa", results[0].title) - Assertions.assertEquals("AAA", results[1].title) - Assertions.assertEquals("BBB", results[2].title) - testReactiveRepository.delete(entityALower).await().indefinitely() - testReactiveRepository.delete(entityAUpper).await().indefinitely() - testReactiveRepository.delete(entityB).await().indefinitely() - - // count - Assertions.assertEquals(5, - testReactiveRepository.count("category", "category0").await().indefinitely()) - Assertions.assertEquals(5, - testReactiveRepository.count("category = ?1", "category0").await().indefinitely()) - Assertions.assertEquals(5, testReactiveRepository.count("category = :category", - Parameters.with("category", "category1")).await().indefinitely()) - Assertions.assertEquals(5, - testReactiveRepository.count("{'category' : ?1}", "category0").await().indefinitely()) - Assertions.assertEquals(5, testReactiveRepository.count("{'category' : :category}", - Parameters.with("category", "category1")).await().indefinitely()) - val countQuery: Document = Document().append("category", "category1") - Assertions.assertEquals(5, testReactiveRepository.count(countQuery).await().indefinitely()) - - // update - val list: List = testReactiveRepository.list("category = ?1", "category0").await().indefinitely() - Assertions.assertEquals(5, list.size) - for (entity in list) { - entity.category = "newCategory" - } - testReactiveRepository.update(list).await().indefinitely() - testReactiveRepository.update(list.stream()).await().indefinitely() - testReactiveRepository.persistOrUpdate(list).await().indefinitely() - var updated: Long = testReactiveRepository.update("category", "newCategory2").where("category", "newCategory").await() - .indefinitely() - Assertions.assertEquals(5, updated) - updated = testReactiveRepository.update("category = ?1", "newCategory").where("category = ?1", "newCategory2").await() - .indefinitely() - Assertions.assertEquals(5, updated) - updated = testReactiveRepository.update("{'category' : ?1}", "newCategory2").where("{'category' : ?1}", "newCategory") - .await().indefinitely() - Assertions.assertEquals(5, updated) - updated = testReactiveRepository.update("category = :category", Parameters.with("category", "newCategory")) - .where("category = :category", Parameters.with("category", "newCategory2")).await().indefinitely() - Assertions.assertEquals(5, updated) - updated = testReactiveRepository.update("{'category' : :category}", Parameters.with("category", "newCategory2")) - .where("{'category' : :category}", Parameters.with("category", "newCategory")).await().indefinitely() - Assertions.assertEquals(5, updated) - Assertions.assertEquals(5, testReactiveRepository.count("category = ?1", "newCategory2").await().indefinitely()) - updated = testReactiveRepository.update("newField", "newValue").all().await().indefinitely() - Assertions.assertEquals(10, updated) - - // delete - testReactiveRepository.delete("category = ?1", "newCategory2").await().indefinitely() - testReactiveRepository.delete("{'category' : ?1}", "category1").await().indefinitely() - Assertions.assertEquals(0, testReactiveRepository.count().await().indefinitely()) - testReactiveRepository.persist(entities.stream()).await().indefinitely() - testReactiveRepository.delete("category = :category", Parameters.with("category", "category0")).await().indefinitely() - testReactiveRepository.delete("{'category' : :category}", Parameters.with("category", "category1")).await() - .indefinitely() - Assertions.assertEquals(0, testReactiveRepository.count().await().indefinitely()) - testReactiveRepository.persistOrUpdate(entities.stream()).await().indefinitely() - testReactiveRepository.delete("category", "category0").await().indefinitely() - testReactiveRepository.delete("category", "category1").await().indefinitely() - Assertions.assertEquals(0, testReactiveRepository.count().await().indefinitely()) - return Response.ok().build() - } - - private val testReactiveEntities: List - get() { - return (0..9).map { - TestReactiveEntity("title$it", - "category" + it % 2, - "description$it") - } - } - - private fun testReactivePagination(query: ReactivePanacheQuery) { - query.page(0, 4) - Assertions.assertEquals(3, query.pageCount().await().indefinitely()) - var page: List = query.list().await().indefinitely() - Assertions.assertEquals(4, page.size) - Assertions.assertTrue(query.hasNextPage().await().indefinitely()) - Assertions.assertFalse(query.hasPreviousPage()) - query.nextPage() - page = query.list().await().indefinitely() - Assertions.assertEquals(4, page.size) - Assertions.assertTrue(query.hasNextPage().await().indefinitely()) - Assertions.assertTrue(query.hasPreviousPage()) - query.lastPage().await().indefinitely() - page = query.list().await().indefinitely() - Assertions.assertEquals(2, page.size) - Assertions.assertFalse(query.hasNextPage().await().indefinitely()) - Assertions.assertTrue(query.hasPreviousPage()) - query.firstPage() - page = query.list().await().indefinitely() - Assertions.assertEquals(4, page.size) - Assertions.assertTrue(query.hasNextPage().await().indefinitely()) - Assertions.assertFalse(query.hasPreviousPage()) - query.page(Page.of(1, 5)) - Assertions.assertEquals(2, query.pageCount().await().indefinitely()) - page = query.list().await().indefinitely() - Assertions.assertEquals(5, page.size) - Assertions.assertFalse(query.hasNextPage().await().indefinitely()) - Assertions.assertTrue(query.hasPreviousPage()) - - // mix page with range - page = query.page(0, 3).range(0, 1).list().await().indefinitely() - Assertions.assertEquals(2, page.size) - } - - private fun testReactiveRange(query: ReactivePanacheQuery) { - query.range(0, 3) - var range: List = query.list().await().indefinitely() - Assertions.assertEquals(4, range.size) - range = query.range(4, 7).list().await().indefinitely() - Assertions.assertEquals(4, range.size) - range = query.range(8, 12).list().await().indefinitely() - Assertions.assertEquals(2, range.size) - range = query.range(10, 12).list().await().indefinitely() - Assertions.assertEquals(0, range.size) - - // when using range, we cannot use any of the page related operations - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).nextPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).previousPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).pageCount() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).lastPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).firstPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).hasPreviousPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).hasNextPage() } - Assertions.assertThrows(UnsupportedOperationException::class.java) { query.range(0, 2).page() } - - // but this is valid to switch from range to page - range = query.range(0, 2).page(0, 3).list().await().indefinitely() - Assertions.assertEquals(3, range.size) - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/main/resources/application.properties b/integration-tests/mongodb-panache-kotlin/src/main/resources/application.properties deleted file mode 100644 index b8c6ae9b25bfb..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/main/resources/application.properties +++ /dev/null @@ -1,9 +0,0 @@ -quarkus.mongodb.connection-string=mongodb://localhost:27018 -quarkus.mongodb.write-concern.journal=false -quarkus.mongodb.database=books - -# fake a different MongoDB instance -quarkus.mongodb.cl2.connection-string=mongodb://localhost:27018 -quarkus.mongodb.cl2.write-concern.journal=false - -quarkus.log.category."io.quarkus.mongodb.panache.runtime".level=DEBUG diff --git a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/BookDTO.kt b/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/BookDTO.kt deleted file mode 100644 index 37149010476f5..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/BookDTO.kt +++ /dev/null @@ -1,73 +0,0 @@ -package io.quarkus.it.mongodb.panache - -import com.fasterxml.jackson.annotation.JsonFormat -import io.quarkus.it.mongodb.panache.book.BookDetail -import java.util.ArrayList -import java.util.Date - -/** - * The IT uses a DTO and not directly the Book object because it should avoid the usage of ObjectId. - */ -class BookDTO { - var title: String? = null - private set - var author: String? = null - private set - var id: String? = null - var transientDescription: String? = null - private set - - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") - private var creationDate: Date? = null - var categories: List = ArrayList() - private set - var details: BookDetail? = null - private set - - fun setTitle(title: String?): BookDTO { - this.title = title - return this - } - - fun setAuthor(author: String?): BookDTO { - this.author = author - return this - } - - fun setCategories(categories: List): BookDTO { - this.categories = categories - return this - } - - fun setDetails(details: BookDetail?): BookDTO { - this.details = details - return this - } - - fun setTransientDescription(transientDescription: String?): BookDTO { - this.transientDescription = transientDescription - return this - } - - fun getCreationDate(): Date? { - return creationDate - } - - fun setCreationDate(creationDate: Date?): BookDTO { - this.creationDate = creationDate - return this - } - - @Override - override fun toString(): String { - return "BookDTO{" + - "title='" + title + '\'' + - ", author='" + author + '\'' + - ", id='" + id + '\'' + - ", transientDescription='" + transientDescription + '\'' + - ", creationDate='" + creationDate + '\'' + - ", categories=" + categories + - ", details=" + details + - '}' - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongoTestResource.kt b/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongoTestResource.kt deleted file mode 100644 index 4edf887275b18..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongoTestResource.kt +++ /dev/null @@ -1,66 +0,0 @@ -package io.quarkus.it.mongodb.panache - -import de.flapdoodle.embed.mongo.MongodExecutable -import de.flapdoodle.embed.mongo.MongodStarter -import de.flapdoodle.embed.mongo.config.IMongodConfig -import de.flapdoodle.embed.mongo.config.MongodConfigBuilder -import de.flapdoodle.embed.mongo.config.Net -import de.flapdoodle.embed.mongo.distribution.Version -import de.flapdoodle.embed.process.runtime.Network -import io.quarkus.test.common.QuarkusTestResourceLifecycleManager -import org.jboss.logging.Logger - -class MongoTestResource : QuarkusTestResourceLifecycleManager { - companion object { - private val LOGGER: Logger = Logger.getLogger(MongoTestResource::class.java) - } - - private var mongod: MongodExecutable? = null - - override fun start(): Map { - return try { - val version: Version.Main = Version.Main.V4_0 - val port = 27018 - LOGGER.infof("Starting Mongo %s on port %s", version, port) - val config: IMongodConfig = MongodConfigBuilder() - .version(version) - .net(Net(port, Network.localhostIsIPv6())) - .build() - mongod = getMongodExecutable(config).also { - try { - it.start() - } catch (e: Exception) { - //every so often mongo fails to start on CI runs - //see if this helps - Thread.sleep(1000) - it.start() - } - - } - mapOf() - } catch (e: Exception) { - throw RuntimeException(e) - } - } - - private fun getMongodExecutable(config: IMongodConfig): MongodExecutable { - return try { - doGetExecutable(config) - } catch (e: Exception) { - // sometimes the download process can timeout so just sleep and try again - try { - Thread.sleep(1000) - } catch (ignored: InterruptedException) { - } - doGetExecutable(config) - } - } - - private fun doGetExecutable(config: IMongodConfig): MongodExecutable { - return MongodStarter.getDefaultInstance().prepare(config) - } - - override fun stop() { - mongod?.stop() - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongodbPanacheMockingTest.kt b/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongodbPanacheMockingTest.kt deleted file mode 100644 index 2fe71cd4e42b8..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongodbPanacheMockingTest.kt +++ /dev/null @@ -1,107 +0,0 @@ -package io.quarkus.it.mongodb.panache - -import io.quarkus.it.mongodb.panache.person.MockablePersonRepository -import io.quarkus.it.mongodb.panache.person.Person -import io.quarkus.it.mongodb.panache.person.PersonEntity -import io.quarkus.it.mongodb.panache.person.PersonRepository -import io.quarkus.mongodb.panache.kotlin.PanacheMongoRepositoryBase -import io.quarkus.test.common.QuarkusTestResource -import io.quarkus.test.junit.QuarkusTest -import io.quarkus.test.junit.mockito.InjectMock -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test -import org.mockito.Mockito -import java.util.Collections -import javax.inject.Inject -import javax.ws.rs.WebApplicationException - -@QuarkusTest -@QuarkusTestResource(MongoTestResource::class) -class MongodbPanacheMockingTest { - @Inject - lateinit var realPersonRepository: PersonRepository - - @InjectMock - lateinit var mockablePersonRepository: MockablePersonRepository - - // These mocks are trying to call methods against instances but kotlin doesn't allow these kinds of method calls. - // they must be called against the companion object (invoked against the type not a reference). removing these tests - // for now as I neither know how to correct this at this point nor am I convinced of the utility of these tests. -/* - @Test - @Order(1) - fun testPanacheMocking() { - PanacheMock.mock(PersonEntity::class.java) - Assertions.assertEquals(0, PersonEntity.count()) - Mockito.`when`(PersonEntity.count()).thenReturn(23L) - Assertions.assertEquals(23, PersonEntity.count()) - Mockito.`when`(PersonEntity.count()).thenReturn(42L) - Assertions.assertEquals(42, PersonEntity.count()) - Mockito.`when`(PersonEntity.count()).thenCallRealMethod() - Assertions.assertEquals(0, PersonEntity.count()) - Assertions.assertEquals(4, PersonEntity.count()) - - val p = PersonEntity() - Mockito.`when`(PersonEntity.findById(12L)).thenReturn(p) - Assertions.assertSame(p, PersonEntity.findById(12L)) - Assertions.assertNull(PersonEntity.findById(42L)) - Mockito.`when`(PersonEntity.findById(12L)).thenThrow(WebApplicationException()) - try { - PersonEntity.findById(12L) - Assertions.fail() - } catch (x: WebApplicationException) { - } - Mockito.`when`(PersonEntity.findOrdered()).thenReturn(Collections.emptyList()) - Assertions.assertTrue(PersonEntity.findOrdered().isEmpty()) - PanacheMock.verify(PersonEntity::class.java).findOrdered() - PanacheMock.verify(PersonEntity::class.java, Mockito.atLeastOnce()).findById(Mockito.any()) - PanacheMock.verifyNoMoreInteractions(PersonEntity::class.java) - } - - @Test - @Order(2) - fun testPanacheMockingWasCleared() { - Assertions.assertFalse(PanacheMock.IsMockEnabled) - } -*/ - - @Test - @Throws(Throwable::class) - fun testPanacheRepositoryMocking() { - Assertions.assertEquals(0, mockablePersonRepository.count()) - Mockito.`when`(mockablePersonRepository.count()).thenReturn(23L) - Assertions.assertEquals(23, mockablePersonRepository.count()) - Mockito.`when`(mockablePersonRepository.count()).thenReturn(42L) - Assertions.assertEquals(42, mockablePersonRepository.count()) - Mockito.`when`(mockablePersonRepository.count()).thenCallRealMethod() - Assertions.assertEquals(0, mockablePersonRepository.count()) - Mockito.verify(mockablePersonRepository, Mockito.times(4)).count() - val p = PersonEntity() - Mockito.`when`(mockablePersonRepository.findById(12L)).thenReturn(p) - Assertions.assertSame(p, mockablePersonRepository.findById(12L)) - Assertions.assertNull(mockablePersonRepository.findById(42L)) - Mockito.`when`(mockablePersonRepository.findById(12L)).thenThrow(WebApplicationException()) - try { - mockablePersonRepository.findById(12L) - Assertions.fail() - } catch (x: WebApplicationException) { - } - Mockito.`when`(mockablePersonRepository.findOrdered()).thenReturn(Collections.emptyList()) - Assertions.assertTrue(mockablePersonRepository.findOrdered()?.isEmpty() ?: false) - Mockito.verify(mockablePersonRepository).findOrdered() - Mockito.verify(mockablePersonRepository, Mockito.atLeastOnce()).findById(12L) - } - - @Test - fun testPanacheRepositoryBridges() { - // normal method call - Assertions.assertNull(realPersonRepository.findById(0L)) - // bridge call - Assertions.assertNull((realPersonRepository as PanacheMongoRepositoryBase).findById(0L)) - - // normal method call - Assertions.assertEquals(false, realPersonRepository.deleteById(0L)) - // bridge call - Assertions.assertEquals(false, (realPersonRepository as PanacheMongoRepositoryBase).deleteById(0L)) - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongodbPanacheResourceTest.kt b/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongodbPanacheResourceTest.kt deleted file mode 100644 index 8eaf4a5751b14..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/MongodbPanacheResourceTest.kt +++ /dev/null @@ -1,333 +0,0 @@ -package io.quarkus.it.mongodb.panache - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.SerializationFeature -import com.fasterxml.jackson.datatype.jdk8.Jdk8Module -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule -import io.quarkus.it.mongodb.panache.book.BookDetail -import io.quarkus.it.mongodb.panache.person.Person -import io.quarkus.test.common.QuarkusTestResource -import io.quarkus.test.junit.QuarkusTest -import io.restassured.RestAssured -import io.restassured.RestAssured.get -import io.restassured.common.mapper.TypeRef -import io.restassured.config.ObjectMapperConfig -import io.restassured.parsing.Parser -import io.restassured.response.Response -import org.hamcrest.Matchers.`is` -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test -import java.util.Calendar -import java.util.Collections -import java.util.Date -import java.util.GregorianCalendar - -@QuarkusTest -@QuarkusTestResource(MongoTestResource::class) -open class MongodbPanacheResourceTest { - @Test - fun testBookEntity() { - callBookEndpoint("/books/entity") - } - - @Test - fun testBookRepository() { - callBookEndpoint("/books/repository") - } - - @Test - fun testPersonEntity() { - callPersonEndpoint("/persons/entity") - } - - @Test - fun testPersonRepository() { - callPersonEndpoint("/persons/repository") - } - - private fun callBookEndpoint(endpoint: String) { - RestAssured.defaultParser = Parser.JSON - RestAssured.config - .objectMapperConfig(ObjectMapperConfig().jackson2ObjectMapperFactory { _, _ -> - ObjectMapper() - .registerModule(Jdk8Module()) - .registerModule(JavaTimeModule()) - .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) - }) - var list: List = get(endpoint).`as`(LIST_OF_BOOK_TYPE_REF) - Assertions.assertEquals(0, list.size) - val book1: BookDTO = BookDTO().setAuthor("Victor Hugo").setTitle("Les Misérables") - .setCreationDate(yearToDate(1886)) - .setCategories(listOf("long", "very long")) - .setDetails(BookDetail().setRating(3).setSummary("A very long book")) - var response: Response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(book1) - .post(endpoint) - .andReturn() - Assertions.assertEquals(201, response.statusCode()) - Assertions.assertTrue(response.header("Location").length > 20) //Assert that id has been populated - val book2: BookDTO = BookDTO().setAuthor("Victor Hugo").setTitle("Notre-Dame de Paris") - .setCreationDate(yearToDate(1831)) - .setCategories(listOf("long", "quasimodo")) - .setDetails(BookDetail().setRating(4).setSummary("quasimodo and esmeralda")) - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(book2) - .post(endpoint) - .andReturn() - Assertions.assertEquals(201, response.statusCode()) - list = get(endpoint).`as`(LIST_OF_BOOK_TYPE_REF) - Assertions.assertEquals(2, list.size) - val book3: BookDTO = BookDTO().setAuthor("Charles Baudelaire").setTitle("Les fleurs du mal") - .setCreationDate(yearToDate(1857)) - .setCategories(Collections.singletonList("poem")) - .setDetails(BookDetail().setRating(2).setSummary("Les Fleurs du mal is a volume of poetry.")) - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(book3) - .post(endpoint) - .andReturn() - Assertions.assertEquals(201, response.statusCode()) - val book4: BookDTO = BookDTO().setAuthor("Charles Baudelaire").setTitle("Le Spleen de Paris") - .setCreationDate(yearToDate(1869)) - .setCategories(Collections.singletonList("poem")) - .setDetails(BookDetail().setRating(2) - .setSummary("Le Spleen de Paris is a collection of 50 short prose poems.")) - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(book4) - .patch(endpoint) - .andReturn() - Assertions.assertEquals(202, response.statusCode()) - list = get(endpoint).`as`(LIST_OF_BOOK_TYPE_REF) - Assertions.assertEquals(4, list.size) - - //with sort - list = get("$endpoint?sort=author").`as`(LIST_OF_BOOK_TYPE_REF) - Assertions.assertEquals(4, list.size) - - // magic query find("author", author) - list = get("$endpoint/search/Victor Hugo").`as`(LIST_OF_BOOK_TYPE_REF) - Assertions.assertEquals(2, list.size) - // we have a projection so we should not have the details field but we should have the title thanks to @BsonProperty - Assertions.assertNotNull(list[0].title) - Assertions.assertNull(list[0].details) - - // magic query find("{'author':?1,'title':?1}", author, title) - var book: BookDTO = get("$endpoint/search?author=Victor Hugo&title=Notre-Dame de Paris").`as`(BookDTO::class.java) - Assertions.assertNotNull(book) - - // date - book = get("$endpoint/search?dateFrom=1885-01-01&dateTo=1887-01-01").`as`(BookDTO::class.java) - Assertions.assertNotNull(book) - book = get("$endpoint/search2?dateFrom=1885-01-01&dateTo=1887-01-01").`as`(BookDTO::class.java) - Assertions.assertNotNull(book) - - // magic query find("{'author'::author,'title'::title}", Parameters.with("author", author).and("title", title)) - book = get("$endpoint/search2?author=Victor Hugo&title=Notre-Dame de Paris").`as`(BookDTO::class.java) - Assertions.assertNotNull(book) - Assertions.assertNotNull(book.id) - Assertions.assertNotNull(book.details) - - //update a book - book.setTitle("Notre-Dame de Paris 2").setTransientDescription("should not be persisted") - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(book) - .put(endpoint) - .andReturn() - Assertions.assertEquals(202, response.statusCode()) - - //check that the title has been updated and the transient description ignored - book = get(endpoint + "/" + book.id.toString()).`as`(BookDTO::class.java) - Assertions.assertNotNull(book) - Assertions.assertEquals("Notre-Dame de Paris 2", book.title) - Assertions.assertNull(book.transientDescription) - - //delete a book - response = RestAssured - .given() - .delete(endpoint + "/" + book.id.toString()) - .andReturn() - Assertions.assertEquals(204, response.statusCode()) - list = get(endpoint).`as`(LIST_OF_BOOK_TYPE_REF) - Assertions.assertEquals(3, list.size) - - //test some special characters - list = get("$endpoint/search/Victor'\\ Hugo").`as`(LIST_OF_BOOK_TYPE_REF) - Assertions.assertEquals(0, list.size) - - //delete all - response = RestAssured - .given() - .delete(endpoint) - .andReturn() - Assertions.assertEquals(204, response.statusCode()) - } - - private fun callPersonEndpoint(endpoint: String) { - RestAssured.defaultParser = Parser.JSON - RestAssured.config - .objectMapperConfig(ObjectMapperConfig().jackson2ObjectMapperFactory { _, _ -> - ObjectMapper() - .registerModule(Jdk8Module()) - .registerModule(JavaTimeModule()) - .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) - }) - var list: List = get(endpoint).`as`(LIST_OF_PERSON_TYPE_REF) - Assertions.assertEquals(0, list.size) - val person1 = Person() - person1.id = 1L - person1.firstname = "John" - person1.lastname = "Doe" - var response: Response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(person1) - .post(endpoint) - .andReturn() - Assertions.assertEquals(201, response.statusCode()) - val person2 = Person() - person2.id = 2L - person2.firstname = "Jane" - person2.lastname = "Doe" - var person3 = Person() - person3.id = 3L - person3.firstname = "Victor" - person3.lastname = "Hugo" - val persons = mutableListOf() - persons.add(person2) - persons.add(person3) - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(persons) - .post("$endpoint/multiple") - .andReturn() - Assertions.assertEquals(204, response.statusCode()) - val person4 = Person() - person4.id = 4L - person4.firstname = "Charles" - person4.lastname = "Baudelaire" - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(person4) - .patch(endpoint) - .andReturn() - Assertions.assertEquals(202, response.statusCode()) - list = get(endpoint).`as`(LIST_OF_PERSON_TYPE_REF) - Assertions.assertEquals(4, list.size) - - //with sort - list = get("$endpoint?sort=firstname").`as`(LIST_OF_PERSON_TYPE_REF) - Assertions.assertEquals(4, list.size) - - //with project - list = get("$endpoint/search/Doe").`as`(LIST_OF_PERSON_TYPE_REF) - Assertions.assertEquals(1, list.size) - Assertions.assertNotNull(list[0].lastname) - //expected the firstname field to be null as we project on lastname only - Assertions.assertNull(list[0].firstname) - - //rename the Doe - RestAssured - .given() - .queryParam("previousName", "Doe").queryParam("newName", "Dupont") - .header("Content-Type", "application/json") - .`when`().post("$endpoint/rename") - .then().statusCode(200) - list = get("$endpoint/search/Dupont").`as`(LIST_OF_PERSON_TYPE_REF) - Assertions.assertEquals(1, list.size) - - //count - var count: Long = get("$endpoint/count").`as`(Long::class.java) - Assertions.assertEquals(4, count) - - //update a person - person3.lastname = "Webster" - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(person3) - .put(endpoint) - .andReturn() - Assertions.assertEquals(202, response.statusCode()) - - //check that the title has been updated - person3 = get("$endpoint/${person3.id}").`as`(Person::class.java) - Assertions.assertEquals(3L, person3.id ?: -1) - Assertions.assertEquals("Webster", person3.lastname) - - //delete a person - response = RestAssured - .given() - .delete("$endpoint/${person3.id}") - .andReturn() - Assertions.assertEquals(204, response.statusCode()) - count = get("$endpoint/count").`as`(Long::class.java) - Assertions.assertEquals(3, count) - - //delete all - response = RestAssured - .given() - .delete(endpoint) - .andReturn() - Assertions.assertEquals(204, response.statusCode()) - count = get("$endpoint/count").`as`(Long::class.java) - Assertions.assertEquals(0, count) - } - - private fun yearToDate(year: Int): Date { - val cal: Calendar = GregorianCalendar() - cal.set(year, 1, 1) - return cal.time - } - - @Test - fun testBug5274() { - get("/bugs/5274").then().body(`is`("OK")) - } - - @Test - fun testBug5885() { - get("/bugs/5885").then().body(`is`("OK")) - } - - @Test - fun testDatesFormat() { - get("/bugs/dates").then().statusCode(200) - } - - @Test - fun testNeedReflection() { - get("/bugs/6324").then().statusCode(200) - get("/bugs/6324/abstract").then().statusCode(200) - } - - @Test - fun testBug7415() { - get("/bugs/7415").then().statusCode(200) - } - - @Test - fun testMoreEntityFunctionalities() { - get("/test/imperative/entity").then().statusCode(200) - } - - @Test - fun testMoreRepositoryFunctionalities() { - get("/test/imperative/repository").then().statusCode(200) - } - - companion object { - private val LIST_OF_BOOK_TYPE_REF: TypeRef> = object : TypeRef>() {} - private val LIST_OF_PERSON_TYPE_REF: TypeRef> = object : TypeRef>() {} - } -} \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/NativeMongodbPanacheResourceIT.kt b/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/NativeMongodbPanacheResourceIT.kt deleted file mode 100644 index a688929f09b4d..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/NativeMongodbPanacheResourceIT.kt +++ /dev/null @@ -1,7 +0,0 @@ -package io.quarkus.it.mongodb.panache.reactive - -import io.quarkus.it.mongodb.panache.MongodbPanacheResourceTest -import io.quarkus.test.junit.NativeImageTest - -@NativeImageTest -internal class NativeMongodbPanacheResourceIT : MongodbPanacheResourceTest() \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/NativeReactiveMongodbPanacheResourceIT.kt b/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/NativeReactiveMongodbPanacheResourceIT.kt deleted file mode 100644 index fe3c384072837..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/NativeReactiveMongodbPanacheResourceIT.kt +++ /dev/null @@ -1,6 +0,0 @@ -package io.quarkus.it.mongodb.panache.reactive - -import io.quarkus.test.junit.NativeImageTest - -@NativeImageTest -internal class NativeReactiveMongodbPanacheResourceIT : ReactiveMongodbPanacheResourceTest() \ No newline at end of file diff --git a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/ReactiveMongodbPanacheResourceTest.kt b/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/ReactiveMongodbPanacheResourceTest.kt deleted file mode 100644 index 7221fb752add1..0000000000000 --- a/integration-tests/mongodb-panache-kotlin/src/test/kotlin/io/quarkus/it/mongodb/panache/reactive/ReactiveMongodbPanacheResourceTest.kt +++ /dev/null @@ -1,351 +0,0 @@ -package io.quarkus.it.mongodb.panache.reactive - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.SerializationFeature -import com.fasterxml.jackson.datatype.jdk8.Jdk8Module -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule -import io.quarkus.it.mongodb.panache.BookDTO -import io.quarkus.it.mongodb.panache.MongoTestResource -import io.quarkus.it.mongodb.panache.book.BookDetail -import io.quarkus.it.mongodb.panache.person.Person -import io.quarkus.test.common.QuarkusTestResource -import io.quarkus.test.junit.QuarkusTest -import io.restassured.RestAssured -import io.restassured.RestAssured.get -import io.restassured.common.mapper.TypeRef -import io.restassured.config.ObjectMapperConfig -import io.restassured.parsing.Parser -import io.restassured.response.Response -import org.awaitility.Awaitility.await -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertNotNull -import org.junit.jupiter.api.Test -import java.io.IOException -import java.time.Duration -import java.util.Calendar -import java.util.Collections -import java.util.Date -import java.util.GregorianCalendar -import javax.ws.rs.client.Client -import javax.ws.rs.client.ClientBuilder -import javax.ws.rs.client.WebTarget -import javax.ws.rs.sse.SseEventSource - -@QuarkusTest -@QuarkusTestResource(MongoTestResource::class) -internal open class ReactiveMongodbPanacheResourceTest { - companion object { - private val LIST_OF_BOOK_TYPE_REF: TypeRef> = object : TypeRef>() {} - private val LIST_OF_PERSON_TYPE_REF: TypeRef> = object : TypeRef>() {} - } - - @Test - @Throws(InterruptedException::class) - fun testReactiveBookEntity() { - callReactiveBookEndpoint("/reactive/books/entity") - } - - @Test - @Throws(InterruptedException::class) - fun testReactiveBookRepository() { - callReactiveBookEndpoint("/reactive/books/repository") - } - - @Test - fun testReactivePersonEntity() { - callReactivePersonEndpoint("/reactive/persons/entity") - } - - @Test - fun testReactivePersonRepository() { - callReactivePersonEndpoint("/reactive/persons/repository") - } - - @Throws(InterruptedException::class) - private fun callReactiveBookEndpoint(endpoint: String) { - RestAssured.defaultParser = Parser.JSON - val objectMapper: ObjectMapper = ObjectMapper() - .registerModule(Jdk8Module()) - .registerModule(JavaTimeModule()) - .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) - RestAssured.config - .objectMapperConfig(ObjectMapperConfig().jackson2ObjectMapperFactory { _, _ -> objectMapper }) - - var list: List = get(endpoint).`as`(LIST_OF_BOOK_TYPE_REF) - assertEquals(0, list.size) - - val book1: BookDTO = BookDTO().setAuthor("Victor Hugo").setTitle("Les Misérables") - .setCreationDate(yearToDate(1886)) - .setCategories(listOf("long", "very long")) - .setDetails(BookDetail().setRating(3).setSummary("A very long book")) - var response: Response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(book1) - .post(endpoint) - .andReturn() - assertEquals(201, response.statusCode()) - Assertions.assertTrue(response.header("Location").length > 20) //Assert that id has been populated - - val book2: BookDTO = BookDTO().setAuthor("Victor Hugo").setTitle("Notre-Dame de Paris") - .setCreationDate(yearToDate(1831)) - .setCategories(listOf("long", "quasimodo")) - .setDetails(BookDetail().setRating(4).setSummary("quasimodo and esmeralda")) - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(book2) - .post(endpoint) - .andReturn() - assertEquals(201, response.statusCode()) - - list = get(endpoint).`as`(LIST_OF_BOOK_TYPE_REF) - assertEquals(2, list.size) - - val book3: BookDTO = BookDTO().setAuthor("Charles Baudelaire").setTitle("Les fleurs du mal") - .setCreationDate(yearToDate(1857)) - .setCategories(Collections.singletonList("poem")) - .setDetails(BookDetail().setRating(2).setSummary("Les Fleurs du mal is a volume of poetry.")) - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(book3) - .post(endpoint) - .andReturn() - assertEquals(201, response.statusCode()) - - val book4: BookDTO = BookDTO().setAuthor("Charles Baudelaire").setTitle("Le Spleen de Paris") - .setCreationDate(yearToDate(1869)) - .setCategories(Collections.singletonList("poem")) - .setDetails(BookDetail().setRating(2) - .setSummary("Le Spleen de Paris is a collection of 50 short prose poems.")) - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(book4) - .patch(endpoint) - .andReturn() - assertEquals(202, response.statusCode()) - - list = get(endpoint).`as`(LIST_OF_BOOK_TYPE_REF) - assertEquals(4, list.size) - - //with sort - list = get("$endpoint?sort=author").`as`(LIST_OF_BOOK_TYPE_REF) - assertEquals(4, list.size) - - // magic query find("author", author) - list = get("$endpoint/search/Victor Hugo").`as`(LIST_OF_BOOK_TYPE_REF) - assertEquals(2, list.size) - - // magic query find("{'author':?1,'title':?1}", author, title) - var book: BookDTO = get("$endpoint/search?author=Victor Hugo&title=Notre-Dame de Paris").`as`(BookDTO::class.java) - assertNotNull(book) - - // date - book = get("$endpoint/search?dateFrom=1885-01-01&dateTo=1887-01-01").`as`(BookDTO::class.java) - assertNotNull(book) - - book = get("$endpoint/search2?dateFrom=1885-01-01&dateTo=1887-01-01").`as`(BookDTO::class.java) - assertNotNull(book) - - // magic query find("{'author'::author,'title'::title}", Parameters.with("author", author).and("title", title)) - book = get("$endpoint/search2?author=Victor Hugo&title=Notre-Dame de Paris").`as`(BookDTO::class.java) - assertNotNull(book) - assertNotNull(book.id) - assertNotNull(book.details) - - //update a book - book.setTitle("Notre-Dame de Paris 2").setTransientDescription("should not be persisted") - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(book) - .put(endpoint) - .andReturn() - assertEquals(202, response.statusCode()) - - //check that the title has been updated and the transient description ignored - book = get(endpoint + "/" + book.id.toString()).`as`(BookDTO::class.java) - assertEquals("Notre-Dame de Paris 2", book.title) - Assertions.assertNull(book.transientDescription) - - //delete a book - response = RestAssured - .given() - .delete(endpoint + "/" + book.id.toString()) - .andReturn() - assertEquals(204, response.statusCode()) - - list = get(endpoint).`as`(LIST_OF_BOOK_TYPE_REF) - assertEquals(3, list.size) - - //test some special characters - list = get("$endpoint/search/Victor'\\ Hugo").`as`(LIST_OF_BOOK_TYPE_REF) - assertEquals(0, list.size) - - //test SSE : there is no JSON serialization for SSE so the test is not very elegant ... - val client: Client = ClientBuilder.newClient() - val target: WebTarget = client.target("http://localhost:8081$endpoint/stream") - SseEventSource.target(target).build().use { source -> - val nbEvent = IntegerAdder() - source.register { inboundSseEvent -> - try { - val theBook: BookDTO = objectMapper.readValue(inboundSseEvent.readData(), BookDTO::class.java) - assertNotNull(theBook) - } catch (e: IOException) { - throw RuntimeException(e) - } - nbEvent.increment() - } - source.open() - await().atMost(Duration.ofSeconds(1)).until({ nbEvent.count() == 3 }) - } - - //delete all - response = RestAssured - .given() - .delete(endpoint) - .andReturn() - assertEquals(204, response.statusCode()) - } - - private fun callReactivePersonEndpoint(endpoint: String) { - RestAssured.defaultParser = Parser.JSON - RestAssured.config - .objectMapperConfig(ObjectMapperConfig().jackson2ObjectMapperFactory({ type, s -> - ObjectMapper() - .registerModule(Jdk8Module()) - .registerModule(JavaTimeModule()) - .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) - })) - var list: List = get(endpoint).`as`(LIST_OF_PERSON_TYPE_REF) - assertEquals(0, list.size) - val person1 = Person() - person1.id = 1L - person1.firstname = "John" - person1.lastname = "Doe" - var response: Response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(person1) - .post(endpoint) - .andReturn() - assertEquals(201, response.statusCode()) - val person2 = Person() - person2.id = 2L - person2.firstname = "Jane" - person2.lastname = "Doe" - var person3 = Person() - person3.id = 3L - person3.firstname = "Victor" - person3.lastname = "Hugo" - val persons = mutableListOf() - persons.add(person2) - persons.add(person3) - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(persons) - .post("$endpoint/multiple") - .andReturn() - assertEquals(204, response.statusCode()) - val person4 = Person() - person4.id = 4L - person4.firstname = "Charles" - person4.lastname = "Baudelaire" - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(person4) - .patch(endpoint) - .andReturn() - assertEquals(202, response.statusCode()) - list = get(endpoint).`as`(LIST_OF_PERSON_TYPE_REF) - assertEquals(4, list.size) - - //with sort - list = get("$endpoint?sort=firstname").`as`(LIST_OF_PERSON_TYPE_REF) - assertEquals(4, list.size) - - //with project - list = get("$endpoint/search/Doe").`as`(LIST_OF_PERSON_TYPE_REF) - assertEquals(1, list.size) - assertNotNull(list[0].lastname) - //expected the firstname field to be null as we project on lastname only - Assertions.assertNull(list[0].firstname) - - //rename the Doe - RestAssured - .given() - .queryParam("previousName", "Doe").queryParam("newName", "Dupont") - .header("Content-Type", "application/json") - .`when`().post("$endpoint/rename") - .then().statusCode(200) - list = get("$endpoint/search/Dupont").`as`(LIST_OF_PERSON_TYPE_REF) - assertEquals(1, list.size) - - //count - var count: Long = get("$endpoint/count").`as`(Long::class.java) - assertEquals(4, count) - - //update a person - person3.lastname = "Webster" - response = RestAssured - .given() - .header("Content-Type", "application/json") - .body(person3) - .put(endpoint) - .andReturn() - assertEquals(202, response.statusCode()) - - //check that the title has been updated - person3 = get("$endpoint/${person3.id}").`as`(Person::class.java) - assertEquals(3L, person3.id ?: -1L) - assertEquals("Webster", person3.lastname) - - //delete a person - response = RestAssured - .given() - .delete(endpoint + "/" + person3.id) - .andReturn() - assertEquals(204, response.statusCode()) - count = get("$endpoint/count").`as`(Long::class.java) - assertEquals(3, count) - - //delete all - response = RestAssured - .given() - .delete(endpoint) - .andReturn() - assertEquals(204, response.statusCode()) - count = get("$endpoint/count").`as`(Long::class.java) - assertEquals(0, count) - } - - private fun yearToDate(year: Int): Date { - val cal: Calendar = GregorianCalendar() - cal.set(year, 1, 1) - return cal.getTime() - } - - private class IntegerAdder { - var cpt = 0 - fun increment() { - cpt++ - } - - fun count(): Int = cpt - } - - @Test - fun testMoreEntityFunctionalities() { - get("/test/reactive/entity").then().statusCode(200) - } - - @Test - fun testMoreRepositoryFunctionalities() { - get("/test/reactive/repository").then().statusCode(200) - } -} \ No newline at end of file diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index b30942574b4d0..5aba651740779 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -104,7 +104,6 @@ scala kotlin mongodb-panache - mongodb-panache-kotlin narayana-stm narayana-jta elytron-security-jdbc