From 65c7e5a7a80f50beeac2d7ac483b0471dc7d0b39 Mon Sep 17 00:00:00 2001 From: Adrien LAUER Date: Fri, 8 Sep 2017 12:14:59 +0200 Subject: [PATCH 1/8] Update for business 4.0 --- .travis.yml | 4 +- core/pom.xml | 2 +- .../mongodb/internal/AsyncMongoDbManager.java | 4 +- morphia/pom.xml | 2 +- .../seedstack/mongodb/morphia/MorphiaIT.java | 84 +++++- .../mongodb/morphia/MorphiaRepositoryIT.java | 183 +++---------- .../mongodb/morphia/SpecificationIT.java | 254 ++++++++++++++++++ .../morphia/fixtures/dummyobject/Dummy1.java | 2 +- .../morphia/fixtures/dummyobject/Dummy2.java | 2 +- .../morphia/fixtures/dummyobject/Dummy3.java | 2 +- .../morphia/fixtures/dummyobject/Dummy4.java | 2 +- .../morphia/fixtures/dummyobject/Dummy5.java | 2 +- .../morphia/fixtures/dummyobject/Dummy6.java | 2 +- .../morphia/fixtures/product/Picture.java | 47 ++++ .../morphia/fixtures/product/Product.java | 103 +++++++ .../morphia/fixtures/user/EntityStringId.java | 30 --- .../mongodb/morphia/fixtures/user/User.java | 15 +- morphia/src/it/resources/application.yaml | 28 +- .../morphia/BaseMorphiaRepository.java | 105 ++++++-- .../morphia/internal/DatastoreFactory.java | 53 ++++ ...aDatastoreImpl.java => DatastoreImpl.java} | 13 +- .../morphia/internal/DatastoreProvider.java | 27 +- .../internal/DefaultMorphiaRepository.java | 2 - .../morphia/internal/MorphiaModule.java | 4 +- .../morphia/internal/MorphiaPlugin.java | 4 +- .../morphia/internal/MorphiaUtils.java | 12 +- .../specification/MorphiaAndConverter.java | 26 ++ .../specification/MorphiaEqualConverter.java | 27 ++ .../specification/MorphiaFalseConverter.java | 22 ++ .../MorphiaGreaterThanConverter.java | 21 ++ .../MorphiaIdentityConverter.java | 24 ++ .../MorphiaLessThanConverter.java | 21 ++ .../specification/MorphiaNotConverter.java | 21 ++ .../specification/MorphiaOrConverter.java | 26 ++ .../MorphiaPropertyConverter.java | 21 ++ .../specification/MorphiaQueryContext.java | 49 ++++ .../MorphiaSpecificationTranslator.java | 19 ++ .../specification/MorphiaStringConverter.java | 56 ++++ .../MorphiaStringEqualConverter.java | 25 ++ .../MorphiaStringMatchingConverter.java | 25 ++ .../specification/MorphiaTrueConverter.java | 22 ++ morphia/src/test/resources/logback-test.xml | 20 -- pom.xml | 10 +- 43 files changed, 1107 insertions(+), 316 deletions(-) create mode 100644 morphia/src/it/java/org/seedstack/mongodb/morphia/SpecificationIT.java create mode 100644 morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/product/Picture.java create mode 100644 morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/product/Product.java delete mode 100644 morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/user/EntityStringId.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DatastoreFactory.java rename morphia/src/main/java/org/seedstack/mongodb/morphia/internal/{MorphiaDatastoreImpl.java => DatastoreImpl.java} (86%) create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaQueryContext.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java delete mode 100644 morphia/src/test/resources/logback-test.xml diff --git a/.travis.yml b/.travis.yml index bc62848..dd61a9f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,9 +12,9 @@ cache: install: - echo "bintray\${env.BINTRAY_USER}\${env.BINTRAY_KEY}" > ~/.m2/settings.xml - - if [[ $TRAVIS_PULL_REQUEST = false ]] && [[ $TRAVIS_BRANCH = master ]] || [[ $TRAVIS_TAG = v* ]]; then GOAL=deploy; else GOAL=install; fi + - if [[ $TRAVIS_PULL_REQUEST = false ]] && [[ $TRAVIS_BRANCH = master || $TRAVIS_BRANCH = dev-* ]] || [[ $TRAVIS_TAG = v* ]]; then GOAL=deploy; else GOAL=install; fi - if [[ $TRAVIS_TAG = v* ]]; then ADDITIONAL_PROFILES=release; mvn -q -U org.seedstack:seedstack-maven-plugin:release; else ADDITIONAL_PROFILES=snapshots; fi -script: mvn -q -U -T 2 -Pbuild-number,compatibility,bintray,javadoc,$ADDITIONAL_PROFILES $GOAL jacoco:report +script: mvn -q -U -Pbuild-number,compatibility,bintray,quality, javadoc,$ADDITIONAL_PROFILES $GOAL jacoco:report after_success: mvn -q coveralls:report -DrepoToken=$COVERALLS_TOKEN diff --git a/core/pom.xml b/core/pom.xml index 5da5a8f..083129e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -14,7 +14,7 @@ org.seedstack.addons.mongodb mongodb - 2.0.0-SNAPSHOT + 3.0.0-SNAPSHOT mongodb-core diff --git a/core/src/main/java/org/seedstack/mongodb/internal/AsyncMongoDbManager.java b/core/src/main/java/org/seedstack/mongodb/internal/AsyncMongoDbManager.java index 4a8ecf2..97c2249 100644 --- a/core/src/main/java/org/seedstack/mongodb/internal/AsyncMongoDbManager.java +++ b/core/src/main/java/org/seedstack/mongodb/internal/AsyncMongoDbManager.java @@ -21,8 +21,8 @@ import org.bson.codecs.configuration.CodecRegistry; import org.seedstack.coffig.BuilderSupplier; import org.seedstack.coffig.Coffig; -import org.seedstack.coffig.util.Utils; import org.seedstack.mongodb.MongoDbConfig; +import org.seedstack.shed.reflect.Classes; import java.util.List; import java.util.Optional; @@ -63,7 +63,7 @@ private MongoClientSettings buildMongoClientSettings(MongoDbConfig.ClientConfig // Apply global settings Optional.ofNullable(allSettings.readPreference).ifPresent(settingsBuilder::readPreference); Optional.ofNullable(allSettings.writeConcern).ifPresent(settingsBuilder::writeConcern); - Optional.ofNullable(allSettings.codecRegistry).map(Utils::instantiateDefault).ifPresent(settingsBuilder::codecRegistry); + Optional.ofNullable(allSettings.codecRegistry).map(Classes::instantiateDefault).ifPresent(settingsBuilder::codecRegistry); // Apply sub-settings settingsBuilder.clusterSettings(allSettings.cluster.get().build()); diff --git a/morphia/pom.xml b/morphia/pom.xml index de792c2..e5e067c 100644 --- a/morphia/pom.xml +++ b/morphia/pom.xml @@ -14,7 +14,7 @@ org.seedstack.addons.mongodb mongodb - 2.0.0-SNAPSHOT + 3.0.0-SNAPSHOT mongodb-morphia diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/MorphiaIT.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/MorphiaIT.java index e2c0411..2716b63 100644 --- a/morphia/src/it/java/org/seedstack/mongodb/morphia/MorphiaIT.java +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/MorphiaIT.java @@ -8,34 +8,114 @@ package org.seedstack.mongodb.morphia; import com.google.inject.Inject; +import com.google.inject.Injector; +import com.google.inject.ProvisionException; +import com.google.inject.TypeLiteral; +import com.google.inject.util.Types; import org.assertj.core.api.Assertions; import org.junit.Test; import org.mongodb.morphia.Datastore; import org.mongodb.morphia.Key; +import org.seedstack.business.domain.Repository; +import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy1; +import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy2; +import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy3; +import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy4; +import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy5; +import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy6; import org.seedstack.mongodb.morphia.fixtures.user.Address; import org.seedstack.mongodb.morphia.fixtures.user.User; +import org.seedstack.mongodb.morphia.internal.MorphiaErrorCode; +import org.seedstack.seed.SeedException; import org.seedstack.seed.it.AbstractSeedIT; import javax.validation.ConstraintViolationException; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Fail.fail; public class MorphiaIT extends AbstractSeedIT { @Inject @MorphiaDatastore(clientName = "client1", dbName = "db") private Datastore datastore; + @Inject + private Injector injector; @Test - public void datastore_test() { + public void datastoreAccess() { User user = new User(1L, "Gerard", "menvuça", new Address("France", "78300", "Poissy", "avenue de l'europe", 1)); Key keyUser = datastore.save(user); Assertions.assertThat(keyUser).isNotNull(); } @Test(expected = ConstraintViolationException.class) - public void validation_is_working() { + public void validationIsWorking() { User user = new User(1L, null, "menvuça", new Address("France", "78300", "Poissy", "avenue de l'europe", 1)); datastore.save(user); fail("should not have saved"); } + + @Test + public void repositoryInjectionTestNoClientForAggregate() { + try { + injector.getInstance(getMorphiaRepositoryOf(Dummy1.class)); + } catch (ProvisionException e) { + assertThat(e.getCause().getMessage()) + .isEqualTo(SeedException.createNew(MorphiaErrorCode.CLIENT_NAME_NOT_CONFIGURED).getMessage()); + } + } + + private com.google.inject.Key getMorphiaRepositoryOf(Class entity) { + return com.google.inject.Key.get(TypeLiteral.get(Types.newParameterizedType(Repository.class, entity, Long.class)), Morphia.class); + } + + @Test + public void repositoryInjectionTestNoDbNameForAggregate() { + try { + injector.getInstance(getMorphiaRepositoryOf(Dummy2.class)); + } catch (ProvisionException e) { + assertThat(e.getCause().getMessage()) + .isEqualTo(SeedException.createNew(MorphiaErrorCode.UNKNOWN_DATABASE).getMessage()); + } + } + + @Test + public void repositoryInjectionTestNoMongoDbClient() { + try { + injector.getInstance(getMorphiaRepositoryOf(Dummy3.class)); + } catch (ProvisionException e) { + assertThat(e.getCause().getMessage()) + .isEqualTo(SeedException.createNew(MorphiaErrorCode.UNKNOWN_CLIENT).getMessage()); + } + } + + @Test + public void repositoryInjectionTestNoMongoDbDatabase() { + try { + injector.getInstance(getMorphiaRepositoryOf(Dummy4.class)); + } catch (ProvisionException e) { + assertThat(e.getCause().getMessage()) + .isEqualTo(SeedException.createNew(MorphiaErrorCode.UNKNOWN_DATABASE).getMessage()); + } + } + + @Test + public void repositoryInjectionTestNoMongodbForAggregate() { + try { + injector.getInstance(getMorphiaRepositoryOf(Dummy5.class)); + } catch (ProvisionException e) { + assertThat(e.getCause().getMessage()) + .isEqualTo(SeedException.createNew(MorphiaErrorCode.PERSISTED_CLASS_NOT_CONFIGURED).getMessage()); + } + } + + @Test + public void repositoryInjectionAsyncClient() { + try { + injector.getInstance(getMorphiaRepositoryOf(Dummy6.class)); + } catch (ProvisionException e) { + assertThat(e.getCause().getMessage()) + .isEqualTo(SeedException.createNew(MorphiaErrorCode.ASYNC_CLIENT_NOT_SUPPORTED).getMessage()); + } + } } diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/MorphiaRepositoryIT.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/MorphiaRepositoryIT.java index 8e9c377..8864f7c 100644 --- a/morphia/src/it/java/org/seedstack/mongodb/morphia/MorphiaRepositoryIT.java +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/MorphiaRepositoryIT.java @@ -8,182 +8,87 @@ package org.seedstack.mongodb.morphia; import com.google.inject.Inject; -import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.ProvisionException; -import com.google.inject.TypeLiteral; -import com.google.inject.util.Types; +import org.junit.Before; import org.junit.Test; -import org.mongodb.morphia.mapping.MappingException; -import org.mongodb.morphia.query.UpdateException; +import org.seedstack.business.domain.AggregateNotFoundException; import org.seedstack.business.domain.Repository; -import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy1; -import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy2; -import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy3; -import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy4; -import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy5; -import org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy6; import org.seedstack.mongodb.morphia.fixtures.user.Address; -import org.seedstack.mongodb.morphia.fixtures.user.EntityStringId; import org.seedstack.mongodb.morphia.fixtures.user.User; -import org.seedstack.mongodb.morphia.internal.MorphiaErrorCode; -import org.seedstack.seed.SeedException; import org.seedstack.seed.it.AbstractSeedIT; +import java.util.Optional; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; public class MorphiaRepositoryIT extends AbstractSeedIT { - @Inject @Morphia private Repository userRepository; - @Inject - @Morphia - private Repository entityStringIdRepository; - - @Inject - private Injector injector; - - @Test - public void repository_injection_test_no_client_for_aggregate() { - try { - injector.getInstance(getMorphiaRepositoryOf(Dummy1.class)); - } catch (ProvisionException e) { - assertThat(e.getCause().getMessage()) - .isEqualTo(SeedException.createNew(MorphiaErrorCode.CLIENT_NAME_NOT_CONFIGURED).getMessage()); - } - } - - private Key getMorphiaRepositoryOf(Class entity) { - return Key.get(TypeLiteral.get(Types.newParameterizedType(Repository.class, entity, Long.class)), Morphia.class); - } - - @Test - public void repository_injection_test_no_dbName_for_aggregate() { - try { - injector.getInstance(getMorphiaRepositoryOf(Dummy2.class)); - } catch (ProvisionException e) { - assertThat(e.getCause().getMessage()) - .isEqualTo(SeedException.createNew(MorphiaErrorCode.UNKNOWN_DATABASE).getMessage()); - } - } - - @Test - public void repository_injection_test_no_mongoDb_client() { - try { - injector.getInstance(getMorphiaRepositoryOf(Dummy3.class)); - } catch (ProvisionException e) { - assertThat(e.getCause().getMessage()) - .isEqualTo(SeedException.createNew(MorphiaErrorCode.UNKNOWN_CLIENT).getMessage()); - } - } - - @Test - public void repository_injection_test_no_mongoDb_database() { - try { - injector.getInstance(getMorphiaRepositoryOf(Dummy4.class)); - } catch (ProvisionException e) { - assertThat(e.getCause().getMessage()) - .isEqualTo(SeedException.createNew(MorphiaErrorCode.UNKNOWN_DATABASE).getMessage()); - } - } - - @Test - public void repository_injection_test_no_mongodb_for_aggregate() { - try { - injector.getInstance(getMorphiaRepositoryOf(Dummy5.class)); - } catch (ProvisionException e) { - assertThat(e.getCause().getMessage()) - .isEqualTo(SeedException.createNew(MorphiaErrorCode.PERSISTED_CLASS_NOT_CONFIGURED).getMessage()); - } + @Before + public void setUp() throws Exception { + userRepository.clear(); } @Test - public void repository_injection_async_client() { - try { - injector.getInstance(getMorphiaRepositoryOf(Dummy6.class)); - } catch (ProvisionException e) { - assertThat(e.getCause().getMessage()) - .isEqualTo(SeedException.createNew(MorphiaErrorCode.ASYNC_CLIENT_NOT_SUPPORTED).getMessage()); - } + public void addAndGet() throws Exception { + User user1 = createUser(1L, "someFirstName", "someLastName"); + userRepository.add(user1); + Optional loaded = userRepository.get(1L); + assertThat(loaded).isPresent(); + assertThat(loaded.get().getName()).isEqualTo("someFirstName"); + assertThat(loaded.get().getLastname()).isEqualTo("someLastName"); } - @Test - public void mongodb_repository_test() { - assertThat(userRepository).isNotNull(); - User user1 = getUser(1L, "N°", "1"); - userRepository.persist(user1); - User user2 = userRepository.load(user1.getEntityId()); - assertThat(user1.getId()).isEqualTo(user2.getId()); - assertThat(user1.getEntityId()).isEqualTo(user2.getEntityId()); - userRepository.delete(user1); - User user3 = userRepository.load(user1.getEntityId()); - assertThat(user3).isEqualTo(null); - User user5 = getUser(2L, "N°", "2"); - userRepository.delete(user5); - userRepository.persist(user5); - User user6 = userRepository.load(user5.getEntityId()); - assertThat(user6.getId()).isEqualTo(user5.getId()); - userRepository.delete(user5); - user6 = userRepository.load(user5.getEntityId()); - assertThat(user6).isEqualTo(null); - userRepository.persist(user5); - assertThat(userRepository.load(2L)).isNotEqualTo(null); - } - - @Test(expected = MappingException.class) - public void mongodb_repository_save_without_id() { - EntityStringId saved = entityStringIdRepository.save(new EntityStringId(null)); - fail("should not have saved"); - } - - @Test(expected = UpdateException.class) - public void mongodb_repository_save_with_inexistent_id() { - userRepository.save(getUser(100L, "Robert", "SMITH")); - fail("should not have saved"); + public void addRemoveAndGet() throws Exception { + User user1 = createUser(1L, "someFirstName", "someLastName"); + userRepository.add(user1); + assertThat(userRepository.get(1L)).isPresent(); + userRepository.remove(user1); + assertThat(userRepository.get(1L)).isNotPresent(); } @Test - public void mongodb_repository_save() { - userRepository.persist(getUser(200L, "Robert", "SMITH")); - assertThat(userRepository.save(getUser(200L, "Jane", "SMITH")).getEntityId()).isEqualTo(200L); + public void update() { + userRepository.add(createUser(200L, "Robert", "SMITH")); + userRepository.update(createUser(200L, "Jane", "SMITH")); + assertThat(userRepository.get(200L).get().getName()).isEqualTo("Jane"); } - @Test - public void mongodb_repository_persist_load() { - userRepository.persist(getUser(300L, "Robert", "SMITH")); - assertThat(userRepository.load(300L).getEntityId()).isEqualTo(300L); + @Test(expected = AggregateNotFoundException.class) + public void updateNonExistent() { + userRepository.update(createUser(100L, "Robert", "SMITH")); + fail("should not have updated"); } @Test - public void mongodb_repository_clear() { - userRepository.persist(getUser(400L, "Robert", "SMITH")); - userRepository.persist(getUser(401L, "Jayne", "SMITH")); - assertThat(userRepository.load(400L).getEntityId()).isEqualTo(400L); - assertThat(userRepository.load(401L).getEntityId()).isEqualTo(401L); + public void clear() { + userRepository.add(createUser(400L, "Robert", "SMITH")); + userRepository.add(createUser(401L, "Jayne", "SMITH")); + assertThat(userRepository.get(400L)).isPresent(); + assertThat(userRepository.get(401L)).isPresent(); userRepository.clear(); - assertThat(userRepository.load(400L)).isNull(); - assertThat(userRepository.load(401L)).isNull(); + assertThat(userRepository.get(400L)).isNotPresent(); + assertThat(userRepository.get(401L)).isNotPresent(); } @Test - public void mongodb_repository_exists() { - userRepository.persist(getUser(300L, "Robert", "SMITH")); - assertThat(userRepository.exists(300L)).isTrue(); - assertThat(userRepository.exists(3010L)).isFalse(); + public void contains() { + userRepository.add(createUser(300L, "Robert", "SMITH")); + assertThat(userRepository.contains(300L)).isTrue(); + assertThat(userRepository.contains(3010L)).isFalse(); } @Test - public void mongodb_repository_count() { - userRepository.persist(getUser(300L, "Robert", "SMITH")); - userRepository.persist(getUser(301L, "Roberta", "SMITH")); - assertThat(userRepository.count()).isEqualTo(2); + public void size() { + userRepository.add(createUser(300L, "Robert", "SMITH")); + userRepository.add(createUser(301L, "Roberta", "SMITH")); + assertThat(userRepository.size()).isEqualTo(2); } - public User getUser(long id, String firstname, String lastName) { + private User createUser(long id, String firstname, String lastName) { return new User(id, firstname, lastName, new Address("France", "75001", "Paris", "Champ Elysee avenue", 1)); } } diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/SpecificationIT.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/SpecificationIT.java new file mode 100644 index 0000000..4427692 --- /dev/null +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/SpecificationIT.java @@ -0,0 +1,254 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.seedstack.business.domain.Repository; +import org.seedstack.business.specification.dsl.SpecificationBuilder; +import org.seedstack.mongodb.morphia.fixtures.product.Product; +import org.seedstack.seed.it.SeedITRunner; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(SeedITRunner.class) +public class SpecificationIT { + @Inject + @Morphia + private Repository repository; + @Inject + private SpecificationBuilder specificationBuilder; + private final Product product1 = createProduct(1L, "product1", "picture1", 2d); + private final Product product2 = createProduct(2L, "product2", "picture2", 2d); + private final Product product3 = createProduct(3L, "product3", "picture3", 2d); + private final Product product4 = createProduct(4L, "product4", " picture4", 2d); + private final Product product5 = createProduct(5L, "product5", "picture4 ", 2d); + private final Product product6 = createProduct(6L, "product6", "picture5", 5d); + + @Before + public void setUp() throws Exception { + repository.clear(); + repository.add(product1); + repository.add(product2); + repository.add(product3); + repository.add(product4); + repository.add(product5); + repository.add(product6); + } + + @After + public void tearDown() throws Exception { + repository.clear(); + } + + @Test + public void testTrue() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .all() + .build()) + ).containsExactly(product1, product2, product3, product4, product5, product6); + } + + @Test + public void testFalse() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .none() + .build()) + ).isEmpty(); + } + + @Test + public void testIdentity() throws Exception { + assertThat(repository.get(specificationBuilder.ofAggregate(Product.class) + .identity().is(3L) + .build()) + ).containsExactly(product3); + assertThat(repository.get(specificationBuilder.ofAggregate(Product.class) + .identity().isNot(3L) + .build()) + ).containsExactly(product1, product2, product4, product5, product6); + } + + @Test + public void testGreaterThan() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("id").greaterThan(3) + .build()) + ).containsExactly(product4, product5, product6); + } + + @Test + public void testLessThan() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("id").lessThan(3) + .build()) + ).containsExactly(product1, product2); + } + + @Test + public void testEquality() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("price").equalTo(2d) + .build()) + ).containsExactly(product1, product2, product3, product4, product5); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("price").equalTo(5d) + .build()) + ).containsExactly(product6); + } + + @Test + public void testStringEquality() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").equalTo("picture1") + .build()) + ).containsExactly(product1); + } + + @Test + public void testStringEqualityWithTrim() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").equalTo("picture4") + .build()) + ).isEmpty(); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").equalTo("picture4").leftTrimmed() + .build()) + ).containsExactly(product4); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").equalTo("picture4").rightTrimmed() + .build()) + ).containsExactly(product5); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").equalTo("picture4").trimmed() + .build()) + ).containsExactly(product4, product5); + } + + @Test + public void testStringEqualityIgnoringCase() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").equalTo("PICTurE3") + .build()) + ).isEmpty(); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").equalTo("PICTurE3").ignoringCase() + .build()) + ).containsExactly(product3); + } + + @Test + public void testStringMatching() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("picture?") + .build()) + ).containsExactly(product1, product2, product3, product6); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("picture*") + .build()) + ).containsExactly(product1, product2, product3, product5, product6); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("pict?re5") + .build()) + ).containsExactly(product6); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("pic*re5") + .build()) + ).containsExactly(product6); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("?ict?re5") + .build()) + ).containsExactly(product6); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("*cture5") + .build()) + ).containsExactly(product6); + } + + @Test + public void testStringMatchingWithTrim() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("pict?re4") + .build()) + ).isEmpty(); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("pict?re4").leftTrimmed() + .build()) + ).containsExactly(product4); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("pict?re4").rightTrimmed() + .build()) + ).containsExactly(product5); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("pict?re4").trimmed() + .build()) + ).containsExactly(product4, product5); + } + + @Test + public void testStringMatchingIgnoringCase() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("PI*urE3") + .build()) + ).isEmpty(); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").matching("PI*urE3").ignoringCase() + .build()) + ).containsExactly(product3); + } + + @Test + public void testNot() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").not().equalTo("picture2") + .build()) + ).containsExactly(product1, product3, product4, product5, product6); + } + + @Test + public void testOr() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").equalTo("picture2") + .or() + .property("designation").equalTo("product3") + .or() + .property("designation").equalTo("product4") + .build()) + ).containsExactly(product2, product3, product4); + } + + @Test + public void testAnd() throws Exception { + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").equalTo("picture2") + .and() + .property("designation").equalTo("product2") + .and() + .property("price").equalTo(2d) + .build()) + ).containsExactly(product2); + assertThat(repository.get(specificationBuilder.of(Product.class) + .property("pictures.name").equalTo("picture3") + .and() + .property("designation").equalTo("product2") + .build()) + ).isEmpty(); + } + + public Product createProduct(long id, String designation, String pictureUrl, double price) { + List pictures = new ArrayList<>(); + pictures.add(pictureUrl); + return new Product(id, designation, "summary", "details", pictures, price); + } +} diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy1.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy1.java index 88b6892..d66af4f 100644 --- a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy1.java +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy1.java @@ -12,7 +12,7 @@ public class Dummy1 extends BaseAggregateRoot { @Override - public Long getEntityId() { + public Long getId() { return null; } diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy2.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy2.java index 261d011..9acd302 100644 --- a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy2.java +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy2.java @@ -12,7 +12,7 @@ public class Dummy2 extends BaseAggregateRoot { @Override - public Long getEntityId() { + public Long getId() { return null; } diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy3.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy3.java index 8508d6e..4c4a39c 100644 --- a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy3.java +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy3.java @@ -12,7 +12,7 @@ public class Dummy3 extends BaseAggregateRoot { @Override - public Long getEntityId() { + public Long getId() { return null; } diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy4.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy4.java index 51780aa..7e4808b 100644 --- a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy4.java +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy4.java @@ -12,7 +12,7 @@ public class Dummy4 extends BaseAggregateRoot { @Override - public Long getEntityId() { + public Long getId() { return null; } diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy5.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy5.java index 33906be..4ba1689 100644 --- a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy5.java +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy5.java @@ -12,7 +12,7 @@ public class Dummy5 extends BaseAggregateRoot { @Override - public Long getEntityId() { + public Long getId() { return null; } diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy6.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy6.java index ed87007..16ddd11 100644 --- a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy6.java +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/dummyobject/Dummy6.java @@ -12,7 +12,7 @@ public class Dummy6 extends BaseAggregateRoot { @Override - public Long getEntityId() { + public Long getId() { return null; } diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/product/Picture.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/product/Picture.java new file mode 100644 index 0000000..2cbabed --- /dev/null +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/product/Picture.java @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +/** + * + */ +package org.seedstack.mongodb.morphia.fixtures.product; + +import org.mongodb.morphia.annotations.Embedded; +import org.seedstack.business.domain.BaseValueObject; + +@Embedded +public class Picture extends BaseValueObject { + private String name; + private Long productId; + + public Picture(String name, Long productId) { + super(); + this.name = name; + this.productId = productId; + } + + + public Picture() { + + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getProductId() { + return productId; + } + + public void setProductId(Long productId) { + this.productId = productId; + } +} diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/product/Product.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/product/Product.java new file mode 100644 index 0000000..9b33385 --- /dev/null +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/product/Product.java @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.fixtures.product; + +import org.mongodb.morphia.annotations.Entity; +import org.mongodb.morphia.annotations.Id; +import org.seedstack.business.domain.BaseAggregateRoot; + +import java.util.ArrayList; +import java.util.List; + +@Entity +public class Product extends BaseAggregateRoot { + @Id + private Long id; + private String designation; + private String summary; + private String details; + private List pictures; + private Double price; + + public Product() { + + } + + public Product(long productId, String designation, String summary, String details, List pictures, Double price) { + id = productId; + setDesignation(designation); + setSummary(summary); + setDetails(details); + List pics = null; + if (pictures != null && !pictures.isEmpty()) { + pics = new ArrayList<>(); + for (String picture : pictures) { + pics.add(new Picture(picture, productId)); + } + } + setPictures(pics); + setPrice(price); + } + + @Override + public Long getId() { + return id; + } + + public String getDesignation() { + return designation; + } + + public void setDesignation(String designation) { + this.designation = designation; + } + + public String getSummary() { + return summary; + } + + public void setSummary(String summary) { + this.summary = summary; + } + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public List getPictures() { + return pictures; + } + + public void setPictures(List pictures) { + this.pictures = pictures; + } + + @Override + public String toString() { + return "Product{" + + "id=" + id + + ", designation='" + designation + '\'' + + ", summary='" + summary + '\'' + + ", details='" + details + '\'' + + ", pictures=" + pictures + + ", price=" + price + + '}'; + } +} diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/user/EntityStringId.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/user/EntityStringId.java deleted file mode 100644 index 16ca9d9..0000000 --- a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/user/EntityStringId.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (c) 2013-2016, The SeedStack authors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package org.seedstack.mongodb.morphia.fixtures.user; - -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; -import org.seedstack.business.domain.AggregateRoot; - -@Entity -public class EntityStringId implements AggregateRoot { - @Id - private String id; - - public EntityStringId() { - } - - public EntityStringId(String id) { - this.id = id; - } - - @Override - public String getEntityId() { - return id; - } -} diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/user/User.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/user/User.java index cd82f20..1bf02d6 100644 --- a/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/user/User.java +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/user/User.java @@ -15,8 +15,6 @@ @Entity public class User implements AggregateRoot { - - public User() { } @@ -37,12 +35,12 @@ public User(long id, String name, String lastName, Address address) { private Address address; - - public long getId() { + @Override + public Long getId() { return id; } - public void setId(long id) { + public void setId(Long id) { this.id = id; } @@ -69,11 +67,4 @@ public Address getAddress() { public void setAddress(Address address) { this.address = address; } - - @Override - public Long getEntityId() { - return id; - } - - } diff --git a/morphia/src/it/resources/application.yaml b/morphia/src/it/resources/application.yaml index 383ae1b..5e2bb63 100644 --- a/morphia/src/it/resources/application.yaml +++ b/morphia/src/it/resources/application.yaml @@ -14,6 +14,7 @@ mongoDb: connectionsPerHost: 50 databases: db1: db + business: business client2: async: true hosts: localhost @@ -42,27 +43,6 @@ classes: Dummy6: mongoDbClient: client2 mongoDbDatabase: db2 - - -# -#[org.seedstack.mongodb.morphia.fixtures.user.*] -#morphia.clientName = client1 -#morphia.dbName = db -# -#[org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy1] -#morphia.dbName = db4 -# -#[org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy2] -#morphia.clientName = clien1 -# -#[org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy3] -#morphia.dbName = client7 -#morphia.dbName = db6 -# -#[org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy4] -#morphia.clientName = client1 -#morphia.dbName = db6 -# -#[org.seedstack.mongodb.morphia.fixtures.dummyobject.Dummy6] -#morphia.clientName = client2 -#morphia.dbName = db2 \ No newline at end of file + product: + mongoDbClient: client1 + mongoDbDatabase: business diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java index 4eb3a02..11ed1f5 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java @@ -7,33 +7,48 @@ */ package org.seedstack.mongodb.morphia; -import com.google.inject.Injector; -import com.google.inject.Key; import org.mongodb.morphia.Datastore; +import org.mongodb.morphia.mapping.Mapper; +import org.mongodb.morphia.query.CriteriaContainer; +import org.mongodb.morphia.query.Query; +import org.seedstack.business.domain.AggregateExistsException; +import org.seedstack.business.domain.AggregateNotFoundException; import org.seedstack.business.domain.AggregateRoot; import org.seedstack.business.domain.BaseRepository; -import org.seedstack.mongodb.morphia.internal.MorphiaUtils; -import org.seedstack.seed.Application; +import org.seedstack.business.specification.Specification; +import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.mongodb.morphia.internal.DatastoreFactory; +import org.seedstack.mongodb.morphia.internal.specification.MorphiaQueryContext; import javax.inject.Inject; +import java.util.Optional; +import java.util.stream.Stream; /** * This class can serve as a base class for Morphia repositories. It provides methods for common CRUD operations as * well as access to the data store through the {@link #getDatastore()} ()} protected method. * - * @param Aggregate root class - * @param Key class + * @param Aggregate root class. + * @param Identifier class. */ -public abstract class BaseMorphiaRepository, K> extends BaseRepository { +public abstract class BaseMorphiaRepository, ID> extends BaseRepository { private Datastore datastore; + private SpecificationTranslator specificationTranslator; public BaseMorphiaRepository() { + } - public BaseMorphiaRepository(Class aggregateRootClass, Class kClass) { + public BaseMorphiaRepository(Class aggregateRootClass, Class kClass) { super(aggregateRootClass, kClass); } + @Inject + private void init(DatastoreFactory datastoreFactory, SpecificationTranslator specificationTranslator) { + this.datastore = datastoreFactory.createDatastore(getAggregateRootClass()); + this.specificationTranslator = specificationTranslator; + } + /** * Provides access to the Morphia data store for implementing custom data access methods. * @@ -43,49 +58,83 @@ protected Datastore getDatastore() { return datastore; } - @Inject - private void initDatastore(Application application, Injector injector) { - datastore = injector.getInstance(Key.get(Datastore.class, MorphiaUtils.getMongoDatastore(application, getAggregateRootClass()))); + @Override + public void add(A aggregate) throws AggregateExistsException { + datastore.save(aggregate); } @Override - public A load(K id) { - return datastore.get(getAggregateRootClass(), id); + public Stream get(Specification specification, Option... options) { + Query query = datastore.createQuery(getAggregateRootClass()); + specificationTranslator.translate( + specification, + new MorphiaQueryContext<>(query) + ); + return query.asList().stream(); } @Override - public void clear() { - datastore.getCollection(getAggregateRootClass()).drop(); + public Optional get(ID id) { + return Optional.ofNullable(datastore.get(getAggregateRootClass(), id)); } @Override - public void delete(K id) { - datastore.delete(getAggregateRootClass(), id); + public boolean contains(Specification specification) { + // TODO + return false; } @Override - public void delete(A aggregate) { - datastore.delete(aggregate); + public boolean contains(ID id) { + return datastore.find(getAggregateRootClass()).filter(Mapper.ID_KEY, id).getKey() != null; } @Override - public void persist(A aggregate) { - datastore.save(aggregate); + public long count(Specification specification) { + // TODO + return 0; } @Override - public A save(A aggregate) { - datastore.merge(aggregate); - return aggregate; + public long size() { + return datastore.getCount(getAggregateRootClass()); } @Override - public boolean exists(K id) { - return load(id) != null; + public long remove(Specification specification) throws AggregateNotFoundException { + // TODO + return 0; } @Override - public long count() { - return datastore.getCount(getAggregateRootClass()); + public void remove(ID id) throws AggregateNotFoundException { + checkExactlyOneAggregateRemoved(datastore.delete(getAggregateRootClass(), id).getN(), id); + } + + @Override + public void remove(A aggregate) throws AggregateNotFoundException { + checkExactlyOneAggregateRemoved(datastore.delete(aggregate).getN(), aggregate.getId()); + } + + private void checkExactlyOneAggregateRemoved(int n, ID id) { + if (n == 0) { + throw new AggregateNotFoundException("Non-existent aggregate " + getAggregateRootClass().getSimpleName() + " identified with " + id + " cannot be removed"); + } else if (n > 1) { + throw new IllegalStateException("More than one aggregate " + getAggregateRootClass().getSimpleName() + " identified with " + id + " have been removed"); + } + } + + @Override + public void update(A aggregate) throws AggregateNotFoundException { + if (!contains(aggregate)) { + throw new AggregateNotFoundException("Non-existent aggregate " + getAggregateRootClass().getSimpleName() + " identified with " + aggregate.getId() + " cannot be updated"); + } + datastore.merge(aggregate); + } + + @Override + public void clear() { + datastore.getCollection(getAggregateRootClass()).drop(); + datastore.getCollection(getAggregateRootClass()).dropIndexes(); } } \ No newline at end of file diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DatastoreFactory.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DatastoreFactory.java new file mode 100644 index 0000000..c73ea8b --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DatastoreFactory.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal; + +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.name.Names; +import com.mongodb.MongoClient; +import org.mongodb.morphia.Datastore; +import org.mongodb.morphia.Morphia; +import org.seedstack.mongodb.morphia.MorphiaDatastore; +import org.seedstack.seed.Application; + +import javax.inject.Inject; + +import static org.seedstack.mongodb.morphia.internal.MorphiaUtils.createDatastoreAnnotation; +import static org.seedstack.mongodb.morphia.internal.MorphiaUtils.getMongoClientConfig; + +public class DatastoreFactory { + private final Application application; + private final Injector injector; + private final Morphia morphia; + + @Inject + DatastoreFactory(Application application, Injector injector, Morphia morphia) { + this.application = application; + this.injector = injector; + this.morphia = morphia; + } + + public Datastore createDatastore(Class morphiaClass) { + MorphiaDatastore datastoreAnnotation = createDatastoreAnnotation(application, morphiaClass); + return createDatastore(datastoreAnnotation.clientName(), datastoreAnnotation.dbName()); + } + + public Datastore createDatastore(String clientName, String dbName) { + Datastore datastore = morphia.createDatastore( + injector.getInstance(Key.get(MongoClient.class, Names.named(clientName))), + MorphiaUtils.resolveDatabaseAlias( + getMongoClientConfig(application, clientName), + dbName + ) + ); + datastore.ensureIndexes(true); + datastore.ensureCaps(); + return datastore; + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaDatastoreImpl.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DatastoreImpl.java similarity index 86% rename from morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaDatastoreImpl.java rename to morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DatastoreImpl.java index 057f0bd..28b4abc 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaDatastoreImpl.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DatastoreImpl.java @@ -12,13 +12,12 @@ import java.io.Serializable; import java.lang.annotation.Annotation; -class MorphiaDatastoreImpl implements MorphiaDatastore, Serializable { - +class DatastoreImpl implements MorphiaDatastore, Serializable { private static final long serialVersionUID = 3861460142806494075L; - private String clientName; - private String dbName; + private final String clientName; + private final String dbName; - MorphiaDatastoreImpl(String clientName, String dbName) { + DatastoreImpl(String clientName, String dbName) { this.clientName = clientName; this.dbName = dbName; } @@ -52,7 +51,7 @@ public boolean equals(Object obj) { return false; if (!(obj instanceof MorphiaDatastore)) return false; - MorphiaDatastoreImpl other = (MorphiaDatastoreImpl) obj; + DatastoreImpl other = (DatastoreImpl) obj; if (clientName == null) { if (other.clientName != null) return false; @@ -65,6 +64,4 @@ public boolean equals(Object obj) { return false; return true; } - - } \ No newline at end of file diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DatastoreProvider.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DatastoreProvider.java index 43b7481..1f8fe21 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DatastoreProvider.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DatastoreProvider.java @@ -7,44 +7,23 @@ */ package org.seedstack.mongodb.morphia.internal; -import com.google.inject.Injector; -import com.google.inject.Key; import com.google.inject.Provider; -import com.google.inject.name.Names; -import com.mongodb.MongoClient; import org.mongodb.morphia.Datastore; -import org.mongodb.morphia.Morphia; import org.seedstack.mongodb.morphia.MorphiaDatastore; -import org.seedstack.seed.Application; import javax.inject.Inject; class DatastoreProvider implements Provider { private final MorphiaDatastore morphiaDatastore; - private final Morphia morphia; @Inject - private Injector injector; - @Inject - private Application application; + private DatastoreFactory datastoreFactory; - DatastoreProvider(MorphiaDatastore morphiaDatastore, Morphia morphia) { - super(); + DatastoreProvider(MorphiaDatastore morphiaDatastore) { this.morphiaDatastore = morphiaDatastore; - this.morphia = morphia; } @Override public Datastore get() { - String resolvedDbName = MorphiaUtils.resolveDatabaseAlias( - MorphiaUtils.getMongoClientConfig(application, morphiaDatastore.clientName()), - morphiaDatastore.dbName() - ); - Datastore datastore = morphia.createDatastore( - injector.getInstance(Key.get(MongoClient.class, Names.named(morphiaDatastore.clientName()))), - resolvedDbName - ); - datastore.ensureIndexes(true); - datastore.ensureCaps(); - return datastore; + return datastoreFactory.createDatastore(morphiaDatastore.clientName(), morphiaDatastore.dbName()); } } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DefaultMorphiaRepository.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DefaultMorphiaRepository.java index 385190a..9563ef7 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DefaultMorphiaRepository.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/DefaultMorphiaRepository.java @@ -12,7 +12,6 @@ import org.seedstack.business.spi.GenericImplementation; import org.seedstack.mongodb.morphia.BaseMorphiaRepository; import org.seedstack.mongodb.morphia.Morphia; -import org.seedstack.seed.Application; import javax.inject.Inject; @@ -33,7 +32,6 @@ @Morphia @GenericImplementation public class DefaultMorphiaRepository, KEY> extends BaseMorphiaRepository { - /** * Constructs a DefaultMongodbRepository. * diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaModule.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaModule.java index 2cbc880..c4c4fd1 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaModule.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaModule.java @@ -31,9 +31,11 @@ class MorphiaModule extends AbstractModule { @Override protected void configure() { + bind(Morphia.class).toInstance(morphia); + bind(DatastoreFactory.class); if (morphiaDatastoresAnnotation != null && !morphiaDatastoresAnnotation.isEmpty()) { for (MorphiaDatastore morphiaDatastore : morphiaDatastoresAnnotation) { - DatastoreProvider datastoreProvider = new DatastoreProvider(morphiaDatastore, morphia); + DatastoreProvider datastoreProvider = new DatastoreProvider(morphiaDatastore); requestInjection(datastoreProvider); bind(Key.get(Datastore.class, morphiaDatastore)).toProvider(datastoreProvider).in(Scopes.SINGLETON); } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaPlugin.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaPlugin.java index 01d6743..b9f1a6b 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaPlugin.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaPlugin.java @@ -12,7 +12,6 @@ import io.nuun.kernel.api.plugin.context.InitContext; import io.nuun.kernel.api.plugin.request.ClasspathScanRequest; import org.mongodb.morphia.Morphia; -import org.seedstack.mongodb.internal.MongoDbPlugin; import org.seedstack.mongodb.morphia.MorphiaDatastore; import org.seedstack.seed.Application; import org.seedstack.seed.core.SeedRuntime; @@ -32,7 +31,6 @@ public class MorphiaPlugin extends AbstractSeedPlugin { private static final Logger LOGGER = LoggerFactory.getLogger(MorphiaPlugin.class); private final Collection morphiaDatastores = new HashSet<>(); private final Morphia morphia = new Morphia(); - private MongoDbPlugin mongoDbPlugin; private ValidatorFactory validatorFactory; @Override @@ -68,7 +66,7 @@ public InitState initialize(InitContext initContext) { if (morphiaScannedClasses != null && !morphiaScannedClasses.isEmpty()) { morphia.map(new HashSet<>(morphiaScannedClasses)); for (Class morphiaClass : morphiaScannedClasses) { - MorphiaDatastore morphiaDatastore = MorphiaUtils.getMongoDatastore(application, morphiaClass); + MorphiaDatastore morphiaDatastore = MorphiaUtils.createDatastoreAnnotation(application, morphiaClass); if (!morphiaDatastores.contains(morphiaDatastore)) { morphiaDatastores.add(morphiaDatastore); } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaUtils.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaUtils.java index 0723171..4a17909 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaUtils.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/MorphiaUtils.java @@ -17,7 +17,7 @@ public final class MorphiaUtils { private MorphiaUtils() { - + // no instantiation allowed } /** @@ -27,7 +27,7 @@ private MorphiaUtils() { * @param morphiaClass persistent morphia object * @return MorphiaDatastore */ - public static MorphiaDatastore getMongoDatastore(Application application, Class morphiaClass) { + static MorphiaDatastore createDatastoreAnnotation(Application application, Class morphiaClass) { ClassConfiguration morphiaEntityConfiguration = application.getConfiguration(morphiaClass); if (morphiaEntityConfiguration.isEmpty()) { throw SeedException.createNew(MorphiaErrorCode.PERSISTED_CLASS_NOT_CONFIGURED) @@ -48,7 +48,7 @@ public static MorphiaDatastore getMongoDatastore(Application application, Class< checkMongoClient(getMongoClientConfig(application, clientName), morphiaClass, clientName, dbName); - return new MorphiaDatastoreImpl(clientName, dbName); + return new DatastoreImpl(clientName, dbName); } /** @@ -58,7 +58,7 @@ public static MorphiaDatastore getMongoDatastore(Application application, Class< * @param dbName the name of the alias or the database. * @return the resolved database name (may be the provided database name if no alias is defined). */ - public static String resolveDatabaseAlias(MongoDbConfig.ClientConfig clientConfig, String dbName) { + static String resolveDatabaseAlias(MongoDbConfig.ClientConfig clientConfig, String dbName) { for (Map.Entry databaseEntry : clientConfig.getDatabases().entrySet()) { if (dbName.equals(databaseEntry.getValue().getAlias())) { return databaseEntry.getKey(); @@ -74,7 +74,7 @@ public static String resolveDatabaseAlias(MongoDbConfig.ClientConfig clientConfi * @param clientName The name of the configured MongoDb client. * @return the client configuration. */ - public static MongoDbConfig.ClientConfig getMongoClientConfig(Application application, String clientName) { + static MongoDbConfig.ClientConfig getMongoClientConfig(Application application, String clientName) { MongoDbConfig.ClientConfig clientConfig = application.getConfiguration().get(MongoDbConfig.class).getClients().get(clientName); if (clientConfig == null) { throw SeedException.createNew(MorphiaErrorCode.UNKNOWN_CLIENT) @@ -83,7 +83,7 @@ public static MongoDbConfig.ClientConfig getMongoClientConfig(Application applic return clientConfig; } - private static void checkMongoClient(MongoDbConfig.ClientConfig clientConfig, Class mappedClass, String clientName, String dbName) { + static void checkMongoClient(MongoDbConfig.ClientConfig clientConfig, Class mappedClass, String clientName, String dbName) { boolean async = clientConfig.isAsync(); if (async) { throw SeedException.createNew(MorphiaErrorCode.ASYNC_CLIENT_NOT_SUPPORTED) diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java new file mode 100644 index 0000000..e5c89b1 --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.AndSpecification; +import org.seedstack.business.spi.specification.SpecificationConverter; +import org.seedstack.business.spi.specification.SpecificationTranslator; + +import java.util.Arrays; + +public class MorphiaAndConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { + @Override + public CriteriaContainer convert(AndSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + return context.getQuery().and( + Arrays.stream(specification.getSpecifications()) + .map(spec -> translator.translate(spec, context)) + .toArray(CriteriaContainer[]::new) + ); + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java new file mode 100644 index 0000000..b9a6ecb --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.EqualSpecification; +import org.seedstack.business.spi.specification.SpecificationConverter; +import org.seedstack.business.spi.specification.SpecificationTranslator; + + +public class MorphiaEqualConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { + @Override + public CriteriaContainer convert(EqualSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + if (specification.getExpectedValue() == null) { + return context.pickFieldEnd().doesNotExist(); + } else { + // We avoid using equal() because Morphia optimizes it without operator ("someAttr": "someVal") + // Thus generating an invalid query when trying to negate it ("$not": "someVal") + return context.pickFieldEnd().not().notEqual(specification.getExpectedValue()); + } + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java new file mode 100644 index 0000000..b4a997c --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.FalseSpecification; +import org.seedstack.business.spi.specification.SpecificationConverter; +import org.seedstack.business.spi.specification.SpecificationTranslator; + + +public class MorphiaFalseConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { + @Override + public CriteriaContainer convert(FalseSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + // Always false + return context.getQuery().criteria("_id").doesNotExist(); + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java new file mode 100644 index 0000000..5850b9f --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.GreaterThanSpecification; +import org.seedstack.business.spi.specification.SpecificationConverter; +import org.seedstack.business.spi.specification.SpecificationTranslator; + + +public class MorphiaGreaterThanConverter> implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { + @Override + public CriteriaContainer convert(GreaterThanSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + return context.pickFieldEnd().greaterThan(specification.getExpectedValue()); + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java new file mode 100644 index 0000000..b0ad178 --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.domain.AggregateRoot; +import org.seedstack.business.specification.IdentitySpecification; +import org.seedstack.business.spi.specification.SpecificationConverter; +import org.seedstack.business.spi.specification.SpecificationTranslator; + +public class MorphiaIdentityConverter, ID> implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { + @Override + public CriteriaContainer convert(IdentitySpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + context.setFieldEnd("_id"); + // We avoid using equal() because Morphia optimizes it without operator ("someAttr": "someVal") + // Thus generating an invalid query when trying to negate it ("$not": "someVal") + return context.pickFieldEnd().not().notEqual(specification.getExpectedIdentifier()); + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java new file mode 100644 index 0000000..63fa62d --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.LessThanSpecification; +import org.seedstack.business.spi.specification.SpecificationConverter; +import org.seedstack.business.spi.specification.SpecificationTranslator; + + +public class MorphiaLessThanConverter> implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { + @Override + public CriteriaContainer convert(LessThanSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + return context.pickFieldEnd().lessThan(specification.getExpectedValue()); + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java new file mode 100644 index 0000000..c8aa540 --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.NotSpecification; +import org.seedstack.business.spi.specification.SpecificationConverter; +import org.seedstack.business.spi.specification.SpecificationTranslator; + +public class MorphiaNotConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { + @Override + public CriteriaContainer convert(NotSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + context.not(); + return translator.translate(specification.getSpecification(), context); + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java new file mode 100644 index 0000000..779445e --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java @@ -0,0 +1,26 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.OrSpecification; +import org.seedstack.business.spi.specification.SpecificationConverter; +import org.seedstack.business.spi.specification.SpecificationTranslator; + +import java.util.Arrays; + +public class MorphiaOrConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { + @Override + public CriteriaContainer convert(OrSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + return context.getQuery().or( + Arrays.stream(specification.getSpecifications()) + .map(spec -> translator.translate(spec, context)) + .toArray(CriteriaContainer[]::new) + ); + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java new file mode 100644 index 0000000..2487e79 --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.PropertySpecification; +import org.seedstack.business.spi.specification.SpecificationConverter; +import org.seedstack.business.spi.specification.SpecificationTranslator; + +public class MorphiaPropertyConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { + @Override + public CriteriaContainer convert(PropertySpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + context.setFieldEnd(specification.getPath()); + return translator.translate(specification.getValueSpecification(), context); + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaQueryContext.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaQueryContext.java new file mode 100644 index 0000000..9013afb --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaQueryContext.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.mongodb.morphia.query.FieldEnd; +import org.mongodb.morphia.query.Query; + +import static com.google.common.base.Preconditions.checkState; + +public class MorphiaQueryContext { + private final Query query; + private FieldEnd fieldEnd; + private boolean not; + + public MorphiaQueryContext(Query query) { + this.query = query; + } + + FieldEnd pickFieldEnd() { + checkState(this.fieldEnd != null, "No field has been set"); + FieldEnd result = this.fieldEnd; + this.fieldEnd = null; + return result; + } + + void setFieldEnd(String property) { + checkState(this.fieldEnd == null, "A field is already set"); + if (not) { + this.fieldEnd = query.criteria(property).not(); + } else { + this.fieldEnd = query.criteria(property); + } + this.not = false; + } + + void not() { + not = !not; + } + + Query getQuery() { + return query; + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java new file mode 100644 index 0000000..7b5a2c0 --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.Specification; +import org.seedstack.business.spi.specification.BaseSpecificationTranslator; + +public class MorphiaSpecificationTranslator extends BaseSpecificationTranslator { + @Override + public CriteriaContainer translate(Specification specification, MorphiaQueryContext query) { + return convert(specification, query); + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java new file mode 100644 index 0000000..dd7d578 --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.StringSpecification; +import org.seedstack.business.spi.specification.SpecificationConverter; +import org.seedstack.business.spi.specification.SpecificationTranslator; + +import java.util.regex.Pattern; + +public abstract class MorphiaStringConverter implements SpecificationConverter, CriteriaContainer> { + @Override + public CriteriaContainer convert(S specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + if (specification.getExpectedString() == null) { + return context.pickFieldEnd().doesNotExist(); + } else { + StringSpecification.Options options = specification.getOptions(); + if (hasNoOption(options) && !isRegex()) { + // We avoid using equal() because Morphia optimizes it without operator ("someAttr": "someVal") + // Thus generating an invalid query when trying to negate it ("$not": "someVal") + return context.pickFieldEnd().not().notEqual(specification.getExpectedString()); + } else { + return context.pickFieldEnd().equal(buildRegex(options, specification.getExpectedString())); + } + + } + } + + private Pattern buildRegex(StringSpecification.Options options, String expectedString) { + StringBuilder sb = new StringBuilder(); + sb.append("^"); + if (options.isTrimmed() || options.isLeftTrimmed()) { + sb.append("\\s*"); + } + sb.append(buildRegexMatchingPart(expectedString)); + if (options.isTrimmed() || options.isRightTrimmed()) { + sb.append("\\s*"); + } + sb.append("$"); + return Pattern.compile(sb.toString(), options.isIgnoringCase() ? Pattern.CASE_INSENSITIVE : 0); + } + + private boolean hasNoOption(StringSpecification.Options options) { + return !options.isLeftTrimmed() && !options.isRightTrimmed() && !options.isTrimmed() && !options.isIgnoringCase(); + } + + protected abstract String buildRegexMatchingPart(String value); + + protected abstract boolean isRegex(); +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java new file mode 100644 index 0000000..cce28d5 --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.seedstack.business.specification.StringEqualSpecification; + +import java.util.regex.Pattern; + + +public class MorphiaStringEqualConverter extends MorphiaStringConverter { + @Override + protected String buildRegexMatchingPart(String value) { + return Pattern.quote(value); + } + + @Override + protected boolean isRegex() { + return false; + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java new file mode 100644 index 0000000..8393d9d --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.seedstack.business.specification.StringMatchingSpecification; + + +public class MorphiaStringMatchingConverter extends MorphiaStringConverter { + @Override + protected String buildRegexMatchingPart(String value) { + return value + .replace(StringMatchingSpecification.SINGLE_CHARACTER_WILDCARD, ".") + .replace(StringMatchingSpecification.MULTI_CHARACTER_WILDCARD, ".*"); + } + + @Override + protected boolean isRegex() { + return true; + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java new file mode 100644 index 0000000..f9f237c --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.TrueSpecification; +import org.seedstack.business.spi.specification.SpecificationConverter; +import org.seedstack.business.spi.specification.SpecificationTranslator; + + +public class MorphiaTrueConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { + @Override + public CriteriaContainer convert(TrueSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + // Always true + return context.getQuery().criteria("_id").not().doesNotExist(); + } +} diff --git a/morphia/src/test/resources/logback-test.xml b/morphia/src/test/resources/logback-test.xml deleted file mode 100644 index 06dda42..0000000 --- a/morphia/src/test/resources/logback-test.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 96953d7..0519d5e 100644 --- a/pom.xml +++ b/pom.xml @@ -14,19 +14,19 @@ org.seedstack.poms parent-internal - 3.0.0 + 3.1.0 org.seedstack.addons.mongodb mongodb - 2.0.0-SNAPSHOT + 3.0.0-SNAPSHOT pom - 3.0.1 + 3.3.0 3.0.3 - 1.1.1 - 3.0.1 + 1.3.2 + 4.0.0-SNAPSHOT true From 99a4314202457760efae5a2493e509bbb59d99c8 Mon Sep 17 00:00:00 2001 From: Adrien LAUER Date: Tue, 12 Sep 2017 17:45:50 +0200 Subject: [PATCH 2/8] Fix travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index dd61a9f..bb79839 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,6 @@ install: - if [[ $TRAVIS_PULL_REQUEST = false ]] && [[ $TRAVIS_BRANCH = master || $TRAVIS_BRANCH = dev-* ]] || [[ $TRAVIS_TAG = v* ]]; then GOAL=deploy; else GOAL=install; fi - if [[ $TRAVIS_TAG = v* ]]; then ADDITIONAL_PROFILES=release; mvn -q -U org.seedstack:seedstack-maven-plugin:release; else ADDITIONAL_PROFILES=snapshots; fi -script: mvn -q -U -Pbuild-number,compatibility,bintray,quality, javadoc,$ADDITIONAL_PROFILES $GOAL jacoco:report +script: mvn -q -U -Pbuild-number,compatibility,bintray,quality,javadoc,$ADDITIONAL_PROFILES $GOAL jacoco:report after_success: mvn -q coveralls:report -DrepoToken=$COVERALLS_TOKEN From 9f691c5974e70783206d9a8e5ba024f08dcbacc9 Mon Sep 17 00:00:00 2001 From: Adrien LAUER Date: Tue, 12 Sep 2017 17:57:53 +0200 Subject: [PATCH 3/8] Fix dependency inconsistency --- morphia/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/morphia/pom.xml b/morphia/pom.xml index e5e067c..c3a10cd 100644 --- a/morphia/pom.xml +++ b/morphia/pom.xml @@ -40,6 +40,12 @@ org.mongodb.morphia morphia-logging-slf4j ${morphia.version} + + + org.slf4j + slf4j-api + + From 9779f5abc2ddec87e48369ba50595162451d9c93 Mon Sep 17 00:00:00 2001 From: Adrien LAUER Date: Wed, 13 Sep 2017 21:20:09 +0200 Subject: [PATCH 4/8] Fully implemented base repository --- .../morphia/BaseMorphiaRepository.java | 38 +++++++++---------- .../specification/MorphiaAndConverter.java | 4 +- .../specification/MorphiaEqualConverter.java | 4 +- .../specification/MorphiaFalseConverter.java | 7 ++-- .../MorphiaGreaterThanConverter.java | 4 +- .../MorphiaIdentityConverter.java | 8 ++-- .../MorphiaLessThanConverter.java | 4 +- .../specification/MorphiaNotConverter.java | 4 +- .../specification/MorphiaOrConverter.java | 4 +- .../MorphiaPropertyConverter.java | 4 +- .../MorphiaSpecificationTranslator.java | 4 +- .../specification/MorphiaStringConverter.java | 4 +- .../MorphiaStringEqualConverter.java | 2 +- .../MorphiaStringMatchingConverter.java | 2 +- ...xt.java => MorphiaTranslationContext.java} | 4 +- .../specification/MorphiaTrueConverter.java | 7 ++-- 16 files changed, 51 insertions(+), 53 deletions(-) rename morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/{MorphiaQueryContext.java => MorphiaTranslationContext.java} (93%) diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java index 11ed1f5..ad07c5a 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java @@ -8,7 +8,6 @@ package org.seedstack.mongodb.morphia; import org.mongodb.morphia.Datastore; -import org.mongodb.morphia.mapping.Mapper; import org.mongodb.morphia.query.CriteriaContainer; import org.mongodb.morphia.query.Query; import org.seedstack.business.domain.AggregateExistsException; @@ -18,7 +17,7 @@ import org.seedstack.business.specification.Specification; import org.seedstack.business.spi.specification.SpecificationTranslator; import org.seedstack.mongodb.morphia.internal.DatastoreFactory; -import org.seedstack.mongodb.morphia.internal.specification.MorphiaQueryContext; +import org.seedstack.mongodb.morphia.internal.specification.MorphiaTranslationContext; import javax.inject.Inject; import java.util.Optional; @@ -33,7 +32,7 @@ */ public abstract class BaseMorphiaRepository, ID> extends BaseRepository { private Datastore datastore; - private SpecificationTranslator specificationTranslator; + private SpecificationTranslator specificationTranslator; public BaseMorphiaRepository() { @@ -44,7 +43,7 @@ public BaseMorphiaRepository(Class aggregateRootClass, Class kClass) { } @Inject - private void init(DatastoreFactory datastoreFactory, SpecificationTranslator specificationTranslator) { + private void init(DatastoreFactory datastoreFactory, SpecificationTranslator specificationTranslator) { this.datastore = datastoreFactory.createDatastore(getAggregateRootClass()); this.specificationTranslator = specificationTranslator; } @@ -65,12 +64,7 @@ public void add(A aggregate) throws AggregateExistsException { @Override public Stream get(Specification specification, Option... options) { - Query query = datastore.createQuery(getAggregateRootClass()); - specificationTranslator.translate( - specification, - new MorphiaQueryContext<>(query) - ); - return query.asList().stream(); + return buildQuery(specification).asList().stream(); } @Override @@ -78,21 +72,14 @@ public Optional get(ID id) { return Optional.ofNullable(datastore.get(getAggregateRootClass(), id)); } - @Override - public boolean contains(Specification specification) { - // TODO - return false; - } - @Override public boolean contains(ID id) { - return datastore.find(getAggregateRootClass()).filter(Mapper.ID_KEY, id).getKey() != null; + return datastore.exists(id) != null; } @Override public long count(Specification specification) { - // TODO - return 0; + return buildQuery(specification).count(); } @Override @@ -102,8 +89,8 @@ public long size() { @Override public long remove(Specification specification) throws AggregateNotFoundException { - // TODO - return 0; + Query query = buildQuery(specification); + return datastore.delete(query).getN(); } @Override @@ -137,4 +124,13 @@ public void clear() { datastore.getCollection(getAggregateRootClass()).drop(); datastore.getCollection(getAggregateRootClass()).dropIndexes(); } + + private Query buildQuery(Specification specification) { + Query query = datastore.createQuery(getAggregateRootClass()); + specificationTranslator.translate( + specification, + new MorphiaTranslationContext<>(query) + ); + return query; + } } \ No newline at end of file diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java index e5c89b1..e739568 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java @@ -14,9 +14,9 @@ import java.util.Arrays; -public class MorphiaAndConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { +public class MorphiaAndConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override - public CriteriaContainer convert(AndSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + public CriteriaContainer convert(AndSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { return context.getQuery().and( Arrays.stream(specification.getSpecifications()) .map(spec -> translator.translate(spec, context)) diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java index b9a6ecb..d8edd8a 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java @@ -13,9 +13,9 @@ import org.seedstack.business.spi.specification.SpecificationTranslator; -public class MorphiaEqualConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { +public class MorphiaEqualConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override - public CriteriaContainer convert(EqualSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + public CriteriaContainer convert(EqualSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { if (specification.getExpectedValue() == null) { return context.pickFieldEnd().doesNotExist(); } else { diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java index b4a997c..fd24b9e 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java @@ -7,16 +7,17 @@ */ package org.seedstack.mongodb.morphia.internal.specification; +import org.mongodb.morphia.mapping.Mapper; import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.FalseSpecification; import org.seedstack.business.spi.specification.SpecificationConverter; import org.seedstack.business.spi.specification.SpecificationTranslator; -public class MorphiaFalseConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { +public class MorphiaFalseConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override - public CriteriaContainer convert(FalseSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + public CriteriaContainer convert(FalseSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { // Always false - return context.getQuery().criteria("_id").doesNotExist(); + return context.getQuery().criteria(Mapper.ID_KEY).doesNotExist(); } } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java index 5850b9f..f270638 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java @@ -13,9 +13,9 @@ import org.seedstack.business.spi.specification.SpecificationTranslator; -public class MorphiaGreaterThanConverter> implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { +public class MorphiaGreaterThanConverter> implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override - public CriteriaContainer convert(GreaterThanSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + public CriteriaContainer convert(GreaterThanSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { return context.pickFieldEnd().greaterThan(specification.getExpectedValue()); } } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java index b0ad178..a278a04 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java @@ -7,16 +7,16 @@ */ package org.seedstack.mongodb.morphia.internal.specification; +import org.mongodb.morphia.mapping.Mapper; import org.mongodb.morphia.query.CriteriaContainer; -import org.seedstack.business.domain.AggregateRoot; import org.seedstack.business.specification.IdentitySpecification; import org.seedstack.business.spi.specification.SpecificationConverter; import org.seedstack.business.spi.specification.SpecificationTranslator; -public class MorphiaIdentityConverter, ID> implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { +public class MorphiaIdentityConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override - public CriteriaContainer convert(IdentitySpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { - context.setFieldEnd("_id"); + public CriteriaContainer convert(IdentitySpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { + context.setFieldEnd(Mapper.ID_KEY); // We avoid using equal() because Morphia optimizes it without operator ("someAttr": "someVal") // Thus generating an invalid query when trying to negate it ("$not": "someVal") return context.pickFieldEnd().not().notEqual(specification.getExpectedIdentifier()); diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java index 63fa62d..b89a9b6 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java @@ -13,9 +13,9 @@ import org.seedstack.business.spi.specification.SpecificationTranslator; -public class MorphiaLessThanConverter> implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { +public class MorphiaLessThanConverter> implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override - public CriteriaContainer convert(LessThanSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + public CriteriaContainer convert(LessThanSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { return context.pickFieldEnd().lessThan(specification.getExpectedValue()); } } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java index c8aa540..9fc3365 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java @@ -12,9 +12,9 @@ import org.seedstack.business.spi.specification.SpecificationConverter; import org.seedstack.business.spi.specification.SpecificationTranslator; -public class MorphiaNotConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { +public class MorphiaNotConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override - public CriteriaContainer convert(NotSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + public CriteriaContainer convert(NotSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { context.not(); return translator.translate(specification.getSpecification(), context); } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java index 779445e..27fe0c3 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java @@ -14,9 +14,9 @@ import java.util.Arrays; -public class MorphiaOrConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { +public class MorphiaOrConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override - public CriteriaContainer convert(OrSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + public CriteriaContainer convert(OrSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { return context.getQuery().or( Arrays.stream(specification.getSpecifications()) .map(spec -> translator.translate(spec, context)) diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java index 2487e79..521542b 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java @@ -12,9 +12,9 @@ import org.seedstack.business.spi.specification.SpecificationConverter; import org.seedstack.business.spi.specification.SpecificationTranslator; -public class MorphiaPropertyConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { +public class MorphiaPropertyConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override - public CriteriaContainer convert(PropertySpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + public CriteriaContainer convert(PropertySpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { context.setFieldEnd(specification.getPath()); return translator.translate(specification.getValueSpecification(), context); } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java index 7b5a2c0..f03c4bc 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java @@ -11,9 +11,9 @@ import org.seedstack.business.specification.Specification; import org.seedstack.business.spi.specification.BaseSpecificationTranslator; -public class MorphiaSpecificationTranslator extends BaseSpecificationTranslator { +public class MorphiaSpecificationTranslator extends BaseSpecificationTranslator { @Override - public CriteriaContainer translate(Specification specification, MorphiaQueryContext query) { + public > CriteriaContainer translate(S specification, MorphiaTranslationContext query) { return convert(specification, query); } } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java index dd7d578..80e5bff 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java @@ -14,9 +14,9 @@ import java.util.regex.Pattern; -public abstract class MorphiaStringConverter implements SpecificationConverter, CriteriaContainer> { +public abstract class MorphiaStringConverter implements SpecificationConverter, CriteriaContainer> { @Override - public CriteriaContainer convert(S specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + public CriteriaContainer convert(S specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { if (specification.getExpectedString() == null) { return context.pickFieldEnd().doesNotExist(); } else { diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java index cce28d5..2441539 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java @@ -12,7 +12,7 @@ import java.util.regex.Pattern; -public class MorphiaStringEqualConverter extends MorphiaStringConverter { +public class MorphiaStringEqualConverter extends MorphiaStringConverter { @Override protected String buildRegexMatchingPart(String value) { return Pattern.quote(value); diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java index 8393d9d..dc2535c 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java @@ -10,7 +10,7 @@ import org.seedstack.business.specification.StringMatchingSpecification; -public class MorphiaStringMatchingConverter extends MorphiaStringConverter { +public class MorphiaStringMatchingConverter extends MorphiaStringConverter { @Override protected String buildRegexMatchingPart(String value) { return value diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaQueryContext.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTranslationContext.java similarity index 93% rename from morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaQueryContext.java rename to morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTranslationContext.java index 9013afb..eb76fa6 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaQueryContext.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTranslationContext.java @@ -13,12 +13,12 @@ import static com.google.common.base.Preconditions.checkState; -public class MorphiaQueryContext { +public class MorphiaTranslationContext { private final Query query; private FieldEnd fieldEnd; private boolean not; - public MorphiaQueryContext(Query query) { + public MorphiaTranslationContext(Query query) { this.query = query; } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java index f9f237c..e1eb921 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java @@ -7,16 +7,17 @@ */ package org.seedstack.mongodb.morphia.internal.specification; +import org.mongodb.morphia.mapping.Mapper; import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.TrueSpecification; import org.seedstack.business.spi.specification.SpecificationConverter; import org.seedstack.business.spi.specification.SpecificationTranslator; -public class MorphiaTrueConverter implements SpecificationConverter, MorphiaQueryContext, CriteriaContainer> { +public class MorphiaTrueConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override - public CriteriaContainer convert(TrueSpecification specification, MorphiaQueryContext context, SpecificationTranslator, CriteriaContainer> translator) { + public CriteriaContainer convert(TrueSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { // Always true - return context.getQuery().criteria("_id").not().doesNotExist(); + return context.getQuery().criteria(Mapper.ID_KEY).not().doesNotExist(); } } From 85f1895645801033044b3d0efd1bb02439e38bda Mon Sep 17 00:00:00 2001 From: Adrien LAUER Date: Wed, 13 Sep 2017 21:48:12 +0200 Subject: [PATCH 5/8] Fix BaseMorphiaRepository contains --- .../mongodb/morphia/BaseMorphiaRepository.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java index ad07c5a..76a7d41 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java @@ -8,6 +8,8 @@ package org.seedstack.mongodb.morphia; import org.mongodb.morphia.Datastore; +import org.mongodb.morphia.mapping.Mapper; +import org.mongodb.morphia.query.CountOptions; import org.mongodb.morphia.query.CriteriaContainer; import org.mongodb.morphia.query.Query; import org.seedstack.business.domain.AggregateExistsException; @@ -72,9 +74,14 @@ public Optional get(ID id) { return Optional.ofNullable(datastore.get(getAggregateRootClass(), id)); } + @Override + public boolean contains(Specification specification) { + return buildQuery(specification).count(new CountOptions().limit(1)) > 0; + } + @Override public boolean contains(ID id) { - return datastore.exists(id) != null; + return datastore.find(getAggregateRootClass()).filter(Mapper.ID_KEY, id).count(new CountOptions().limit(1)) > 0; } @Override @@ -89,8 +96,7 @@ public long size() { @Override public long remove(Specification specification) throws AggregateNotFoundException { - Query query = buildQuery(specification); - return datastore.delete(query).getN(); + return datastore.delete(buildQuery(specification)).getN(); } @Override @@ -98,11 +104,6 @@ public void remove(ID id) throws AggregateNotFoundException { checkExactlyOneAggregateRemoved(datastore.delete(getAggregateRootClass(), id).getN(), id); } - @Override - public void remove(A aggregate) throws AggregateNotFoundException { - checkExactlyOneAggregateRemoved(datastore.delete(aggregate).getN(), aggregate.getId()); - } - private void checkExactlyOneAggregateRemoved(int n, ID id) { if (n == 0) { throw new AggregateNotFoundException("Non-existent aggregate " + getAggregateRootClass().getSimpleName() + " identified with " + id + " cannot be removed"); From c07ed8b0b8e6787136350339333827e1ecc148e0 Mon Sep 17 00:00:00 2001 From: Adrien LAUER Date: Fri, 15 Sep 2017 16:21:33 +0200 Subject: [PATCH 6/8] Update trimming method names --- .../seedstack/mongodb/morphia/SpecificationIT.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/morphia/src/it/java/org/seedstack/mongodb/morphia/SpecificationIT.java b/morphia/src/it/java/org/seedstack/mongodb/morphia/SpecificationIT.java index 4427692..df88ecc 100644 --- a/morphia/src/it/java/org/seedstack/mongodb/morphia/SpecificationIT.java +++ b/morphia/src/it/java/org/seedstack/mongodb/morphia/SpecificationIT.java @@ -123,15 +123,15 @@ public void testStringEqualityWithTrim() throws Exception { .build()) ).isEmpty(); assertThat(repository.get(specificationBuilder.of(Product.class) - .property("pictures.name").equalTo("picture4").leftTrimmed() + .property("pictures.name").equalTo("picture4").trimmingLead() .build()) ).containsExactly(product4); assertThat(repository.get(specificationBuilder.of(Product.class) - .property("pictures.name").equalTo("picture4").rightTrimmed() + .property("pictures.name").equalTo("picture4").trimmingTail() .build()) ).containsExactly(product5); assertThat(repository.get(specificationBuilder.of(Product.class) - .property("pictures.name").equalTo("picture4").trimmed() + .property("pictures.name").equalTo("picture4").trimming() .build()) ).containsExactly(product4, product5); } @@ -183,15 +183,15 @@ public void testStringMatchingWithTrim() throws Exception { .build()) ).isEmpty(); assertThat(repository.get(specificationBuilder.of(Product.class) - .property("pictures.name").matching("pict?re4").leftTrimmed() + .property("pictures.name").matching("pict?re4").trimmingLead() .build()) ).containsExactly(product4); assertThat(repository.get(specificationBuilder.of(Product.class) - .property("pictures.name").matching("pict?re4").rightTrimmed() + .property("pictures.name").matching("pict?re4").trimmingTail() .build()) ).containsExactly(product5); assertThat(repository.get(specificationBuilder.of(Product.class) - .property("pictures.name").matching("pict?re4").trimmed() + .property("pictures.name").matching("pict?re4").trimming() .build()) ).containsExactly(product4, product5); } From da43d2f73989aef4f15130e9b8b91bf74e7120d1 Mon Sep 17 00:00:00 2001 From: Adrien LAUER Date: Thu, 21 Sep 2017 10:55:40 +0200 Subject: [PATCH 7/8] Update after business refactor --- .../morphia/BaseMorphiaRepository.java | 2 +- .../specification/MorphiaAndConverter.java | 6 +++--- .../MorphiaAttributeConverter.java | 21 +++++++++++++++++++ .../specification/MorphiaEqualConverter.java | 6 +++--- .../specification/MorphiaFalseConverter.java | 6 +++--- .../MorphiaGreaterThanConverter.java | 6 +++--- .../MorphiaIdentityConverter.java | 6 +++--- .../MorphiaLessThanConverter.java | 6 +++--- .../specification/MorphiaNotConverter.java | 6 +++--- .../specification/MorphiaOrConverter.java | 6 +++--- .../MorphiaPropertyConverter.java | 21 ------------------- .../MorphiaSpecificationTranslator.java | 4 ++-- .../specification/MorphiaStringConverter.java | 16 +++++++------- .../MorphiaStringEqualConverter.java | 6 +++--- .../MorphiaStringMatchingConverter.java | 6 +++--- .../MorphiaTranslationContext.java | 8 +++---- .../specification/MorphiaTrueConverter.java | 6 +++--- 17 files changed, 69 insertions(+), 69 deletions(-) create mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAttributeConverter.java delete mode 100644 morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java index 76a7d41..71f4b27 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/BaseMorphiaRepository.java @@ -17,7 +17,7 @@ import org.seedstack.business.domain.AggregateRoot; import org.seedstack.business.domain.BaseRepository; import org.seedstack.business.specification.Specification; -import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.business.spi.SpecificationTranslator; import org.seedstack.mongodb.morphia.internal.DatastoreFactory; import org.seedstack.mongodb.morphia.internal.specification.MorphiaTranslationContext; diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java index e739568..94f263e 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAndConverter.java @@ -9,12 +9,12 @@ import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.AndSpecification; -import org.seedstack.business.spi.specification.SpecificationConverter; -import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.business.spi.SpecificationConverter; +import org.seedstack.business.spi.SpecificationTranslator; import java.util.Arrays; -public class MorphiaAndConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { +class MorphiaAndConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override public CriteriaContainer convert(AndSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { return context.getQuery().and( diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAttributeConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAttributeConverter.java new file mode 100644 index 0000000..8de6d2d --- /dev/null +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaAttributeConverter.java @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2013-2016, The SeedStack authors + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.seedstack.mongodb.morphia.internal.specification; + +import org.mongodb.morphia.query.CriteriaContainer; +import org.seedstack.business.specification.AttributeSpecification; +import org.seedstack.business.spi.SpecificationConverter; +import org.seedstack.business.spi.SpecificationTranslator; + +class MorphiaAttributeConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { + @Override + public CriteriaContainer convert(AttributeSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { + context.setFieldEnd(specification.getPath()); + return translator.translate(specification.getValueSpecification(), context); + } +} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java index d8edd8a..36d478d 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaEqualConverter.java @@ -9,11 +9,11 @@ import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.EqualSpecification; -import org.seedstack.business.spi.specification.SpecificationConverter; -import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.business.spi.SpecificationConverter; +import org.seedstack.business.spi.SpecificationTranslator; -public class MorphiaEqualConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { +class MorphiaEqualConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override public CriteriaContainer convert(EqualSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { if (specification.getExpectedValue() == null) { diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java index fd24b9e..eb06272 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaFalseConverter.java @@ -10,11 +10,11 @@ import org.mongodb.morphia.mapping.Mapper; import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.FalseSpecification; -import org.seedstack.business.spi.specification.SpecificationConverter; -import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.business.spi.SpecificationConverter; +import org.seedstack.business.spi.SpecificationTranslator; -public class MorphiaFalseConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { +class MorphiaFalseConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override public CriteriaContainer convert(FalseSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { // Always false diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java index f270638..d797b0b 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaGreaterThanConverter.java @@ -9,11 +9,11 @@ import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.GreaterThanSpecification; -import org.seedstack.business.spi.specification.SpecificationConverter; -import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.business.spi.SpecificationConverter; +import org.seedstack.business.spi.SpecificationTranslator; -public class MorphiaGreaterThanConverter> implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { +class MorphiaGreaterThanConverter> implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override public CriteriaContainer convert(GreaterThanSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { return context.pickFieldEnd().greaterThan(specification.getExpectedValue()); diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java index a278a04..f523e4a 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaIdentityConverter.java @@ -10,10 +10,10 @@ import org.mongodb.morphia.mapping.Mapper; import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.IdentitySpecification; -import org.seedstack.business.spi.specification.SpecificationConverter; -import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.business.spi.SpecificationConverter; +import org.seedstack.business.spi.SpecificationTranslator; -public class MorphiaIdentityConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { +class MorphiaIdentityConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override public CriteriaContainer convert(IdentitySpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { context.setFieldEnd(Mapper.ID_KEY); diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java index b89a9b6..76e092a 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaLessThanConverter.java @@ -9,11 +9,11 @@ import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.LessThanSpecification; -import org.seedstack.business.spi.specification.SpecificationConverter; -import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.business.spi.SpecificationConverter; +import org.seedstack.business.spi.SpecificationTranslator; -public class MorphiaLessThanConverter> implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { +class MorphiaLessThanConverter> implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override public CriteriaContainer convert(LessThanSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { return context.pickFieldEnd().lessThan(specification.getExpectedValue()); diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java index 9fc3365..364ff4c 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaNotConverter.java @@ -9,10 +9,10 @@ import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.NotSpecification; -import org.seedstack.business.spi.specification.SpecificationConverter; -import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.business.spi.SpecificationConverter; +import org.seedstack.business.spi.SpecificationTranslator; -public class MorphiaNotConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { +class MorphiaNotConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override public CriteriaContainer convert(NotSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { context.not(); diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java index 27fe0c3..c0b059e 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaOrConverter.java @@ -9,12 +9,12 @@ import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.OrSpecification; -import org.seedstack.business.spi.specification.SpecificationConverter; -import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.business.spi.SpecificationConverter; +import org.seedstack.business.spi.SpecificationTranslator; import java.util.Arrays; -public class MorphiaOrConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { +class MorphiaOrConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override public CriteriaContainer convert(OrSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { return context.getQuery().or( diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java deleted file mode 100644 index 521542b..0000000 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaPropertyConverter.java +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Copyright (c) 2013-2016, The SeedStack authors - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package org.seedstack.mongodb.morphia.internal.specification; - -import org.mongodb.morphia.query.CriteriaContainer; -import org.seedstack.business.specification.PropertySpecification; -import org.seedstack.business.spi.specification.SpecificationConverter; -import org.seedstack.business.spi.specification.SpecificationTranslator; - -public class MorphiaPropertyConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { - @Override - public CriteriaContainer convert(PropertySpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { - context.setFieldEnd(specification.getPath()); - return translator.translate(specification.getValueSpecification(), context); - } -} diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java index f03c4bc..07a3c01 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaSpecificationTranslator.java @@ -9,9 +9,9 @@ import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.Specification; -import org.seedstack.business.spi.specification.BaseSpecificationTranslator; +import org.seedstack.business.spi.BaseSpecificationTranslator; -public class MorphiaSpecificationTranslator extends BaseSpecificationTranslator { +class MorphiaSpecificationTranslator extends BaseSpecificationTranslator { @Override public > CriteriaContainer translate(S specification, MorphiaTranslationContext query) { return convert(specification, query); diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java index 80e5bff..c74c1c0 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringConverter.java @@ -9,12 +9,12 @@ import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.StringSpecification; -import org.seedstack.business.spi.specification.SpecificationConverter; -import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.business.spi.SpecificationConverter; +import org.seedstack.business.spi.SpecificationTranslator; import java.util.regex.Pattern; -public abstract class MorphiaStringConverter implements SpecificationConverter, CriteriaContainer> { +abstract class MorphiaStringConverter implements SpecificationConverter, CriteriaContainer> { @Override public CriteriaContainer convert(S specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { if (specification.getExpectedString() == null) { @@ -35,11 +35,11 @@ public CriteriaContainer convert(S specification, MorphiaTranslationContext c private Pattern buildRegex(StringSpecification.Options options, String expectedString) { StringBuilder sb = new StringBuilder(); sb.append("^"); - if (options.isTrimmed() || options.isLeftTrimmed()) { + if (options.isTrimmed() || options.isLeadTrimmed()) { sb.append("\\s*"); } sb.append(buildRegexMatchingPart(expectedString)); - if (options.isTrimmed() || options.isRightTrimmed()) { + if (options.isTrimmed() || options.isTailTrimmed()) { sb.append("\\s*"); } sb.append("$"); @@ -47,10 +47,10 @@ private Pattern buildRegex(StringSpecification.Options options, String expectedS } private boolean hasNoOption(StringSpecification.Options options) { - return !options.isLeftTrimmed() && !options.isRightTrimmed() && !options.isTrimmed() && !options.isIgnoringCase(); + return !options.isLeadTrimmed() && !options.isTailTrimmed() && !options.isTrimmed() && !options.isIgnoringCase(); } - protected abstract String buildRegexMatchingPart(String value); + abstract String buildRegexMatchingPart(String value); - protected abstract boolean isRegex(); + abstract boolean isRegex(); } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java index 2441539..6477c5d 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringEqualConverter.java @@ -12,14 +12,14 @@ import java.util.regex.Pattern; -public class MorphiaStringEqualConverter extends MorphiaStringConverter { +class MorphiaStringEqualConverter extends MorphiaStringConverter { @Override - protected String buildRegexMatchingPart(String value) { + String buildRegexMatchingPart(String value) { return Pattern.quote(value); } @Override - protected boolean isRegex() { + boolean isRegex() { return false; } } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java index dc2535c..9807fb7 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaStringMatchingConverter.java @@ -10,16 +10,16 @@ import org.seedstack.business.specification.StringMatchingSpecification; -public class MorphiaStringMatchingConverter extends MorphiaStringConverter { +class MorphiaStringMatchingConverter extends MorphiaStringConverter { @Override - protected String buildRegexMatchingPart(String value) { + String buildRegexMatchingPart(String value) { return value .replace(StringMatchingSpecification.SINGLE_CHARACTER_WILDCARD, ".") .replace(StringMatchingSpecification.MULTI_CHARACTER_WILDCARD, ".*"); } @Override - protected boolean isRegex() { + boolean isRegex() { return true; } } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTranslationContext.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTranslationContext.java index eb76fa6..a86b15d 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTranslationContext.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTranslationContext.java @@ -22,14 +22,14 @@ public MorphiaTranslationContext(Query query) { this.query = query; } - FieldEnd pickFieldEnd() { + public FieldEnd pickFieldEnd() { checkState(this.fieldEnd != null, "No field has been set"); FieldEnd result = this.fieldEnd; this.fieldEnd = null; return result; } - void setFieldEnd(String property) { + public void setFieldEnd(String property) { checkState(this.fieldEnd == null, "A field is already set"); if (not) { this.fieldEnd = query.criteria(property).not(); @@ -39,11 +39,11 @@ void setFieldEnd(String property) { this.not = false; } - void not() { + public void not() { not = !not; } - Query getQuery() { + public Query getQuery() { return query; } } diff --git a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java index e1eb921..46f8bc3 100644 --- a/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java +++ b/morphia/src/main/java/org/seedstack/mongodb/morphia/internal/specification/MorphiaTrueConverter.java @@ -10,11 +10,11 @@ import org.mongodb.morphia.mapping.Mapper; import org.mongodb.morphia.query.CriteriaContainer; import org.seedstack.business.specification.TrueSpecification; -import org.seedstack.business.spi.specification.SpecificationConverter; -import org.seedstack.business.spi.specification.SpecificationTranslator; +import org.seedstack.business.spi.SpecificationConverter; +import org.seedstack.business.spi.SpecificationTranslator; -public class MorphiaTrueConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { +class MorphiaTrueConverter implements SpecificationConverter, MorphiaTranslationContext, CriteriaContainer> { @Override public CriteriaContainer convert(TrueSpecification specification, MorphiaTranslationContext context, SpecificationTranslator, CriteriaContainer> translator) { // Always true From e4359973b8483d2d2fd6402d93d05d91b10de775 Mon Sep 17 00:00:00 2001 From: Adrien LAUER Date: Thu, 21 Sep 2017 11:01:12 +0200 Subject: [PATCH 8/8] Fix dependencies --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0519d5e..a272bef 100644 --- a/pom.xml +++ b/pom.xml @@ -23,7 +23,7 @@ pom - 3.3.0 + 3.3.2-SNAPSHOT 3.0.3 1.3.2 4.0.0-SNAPSHOT