Skip to content

Commit c63d7d2

Browse files
committed
Implement sorting
1 parent f904ac7 commit c63d7d2

File tree

7 files changed

+217
-80
lines changed

7 files changed

+217
-80
lines changed

morphia/src/it/java/org/seedstack/mongodb/morphia/SpecificationIT.java

Lines changed: 84 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,52 @@
77
*/
88
package org.seedstack.mongodb.morphia;
99

10+
import static org.assertj.core.api.Assertions.assertThat;
11+
12+
import java.util.ArrayList;
13+
import java.util.Comparator;
14+
import java.util.List;
15+
import javax.inject.Inject;
1016
import org.junit.After;
1117
import org.junit.Before;
1218
import org.junit.Test;
1319
import org.junit.runner.RunWith;
20+
import org.seedstack.business.domain.IdentityService;
1421
import org.seedstack.business.domain.Repository;
22+
import org.seedstack.business.domain.SortOption;
23+
import org.seedstack.business.specification.Specification;
1524
import org.seedstack.business.specification.dsl.SpecificationBuilder;
25+
import org.seedstack.mongodb.morphia.fixtures.product.Picture;
1626
import org.seedstack.mongodb.morphia.fixtures.product.Product;
1727
import org.seedstack.seed.it.SeedITRunner;
1828

19-
import javax.inject.Inject;
20-
import java.util.ArrayList;
21-
import java.util.List;
22-
23-
import static org.assertj.core.api.Assertions.assertThat;
24-
2529
@RunWith(SeedITRunner.class)
2630
public class SpecificationIT {
31+
private Product product1;
32+
private Product product2;
33+
private Product product3;
34+
private Product product4;
35+
private Product product5;
36+
private Product product6;
2737
@Inject
2838
@Morphia
2939
private Repository<Product, Long> repository;
3040
@Inject
3141
private SpecificationBuilder specificationBuilder;
32-
private final Product product1 = createProduct(1L, "product1", "picture1", 2d);
33-
private final Product product2 = createProduct(2L, "product2", "picture2", 2d);
34-
private final Product product3 = createProduct(3L, "product3", "picture3", 2d);
35-
private final Product product4 = createProduct(4L, "product4", " picture4", 2d);
36-
private final Product product5 = createProduct(5L, "product5", "picture4 ", 2d);
37-
private final Product product6 = createProduct(6L, "product6", "picture5", 5d);
42+
@Inject
43+
private IdentityService identityService;
3844

3945
@Before
4046
public void setUp() throws Exception {
47+
product1 = createProduct(1L, "product1", "url1", "picture1", 2d);
48+
product2 = createProduct(2L, "product2", "url2", "picture2", 2d);
49+
product3 = createProduct(3L, "product3", "url3", "picture3", 2d);
50+
product4 = createProduct(4L, "product4", "url2", " picture4", 6d);
51+
product5 = createProduct(5L, "product5", "url5", "picture4 ", 1d);
52+
product6 = createProduct(6L, "product6", "url6", "picture5", 5d);
53+
4154
repository.clear();
55+
4256
repository.add(product1);
4357
repository.add(product2);
4458
repository.add(product3);
@@ -101,7 +115,7 @@ public void testEquality() throws Exception {
101115
assertThat(repository.get(specificationBuilder.of(Product.class)
102116
.property("price").equalTo(2d)
103117
.build())
104-
).containsExactly(product1, product2, product3, product4, product5);
118+
).containsExactly(product1, product2, product3);
105119
assertThat(repository.get(specificationBuilder.of(Product.class)
106120
.property("price").equalTo(5d)
107121
.build())
@@ -111,115 +125,115 @@ public void testEquality() throws Exception {
111125
@Test
112126
public void testStringEquality() throws Exception {
113127
assertThat(repository.get(specificationBuilder.of(Product.class)
114-
.property("pictures.name").equalTo("picture1")
128+
.property("pictures.url.url").equalTo("picture1")
115129
.build())
116130
).containsExactly(product1);
117131
}
118132

119133
@Test
120134
public void testStringEqualityWithTrim() throws Exception {
121135
assertThat(repository.get(specificationBuilder.of(Product.class)
122-
.property("pictures.name").equalTo("picture4")
136+
.property("pictures.url.url").equalTo("picture4")
123137
.build())
124138
).isEmpty();
125139
assertThat(repository.get(specificationBuilder.of(Product.class)
126-
.property("pictures.name").equalTo("picture4").trimmingLead()
140+
.property("pictures.url.url").equalTo("picture4").trimmingLead()
127141
.build())
128142
).containsExactly(product4);
129143
assertThat(repository.get(specificationBuilder.of(Product.class)
130-
.property("pictures.name").equalTo("picture4").trimmingTail()
144+
.property("pictures.url.url").equalTo("picture4").trimmingTail()
131145
.build())
132146
).containsExactly(product5);
133147
assertThat(repository.get(specificationBuilder.of(Product.class)
134-
.property("pictures.name").equalTo("picture4").trimming()
148+
.property("pictures.url.url").equalTo("picture4").trimming()
135149
.build())
136150
).containsExactly(product4, product5);
137151
}
138152

139153
@Test
140154
public void testStringEqualityIgnoringCase() throws Exception {
141155
assertThat(repository.get(specificationBuilder.of(Product.class)
142-
.property("pictures.name").equalTo("PICTurE3")
156+
.property("pictures.url.url").equalTo("PICTurE3")
143157
.build())
144158
).isEmpty();
145159
assertThat(repository.get(specificationBuilder.of(Product.class)
146-
.property("pictures.name").equalTo("PICTurE3").ignoringCase()
160+
.property("pictures.url.url").equalTo("PICTurE3").ignoringCase()
147161
.build())
148162
).containsExactly(product3);
149163
}
150164

151165
@Test
152166
public void testStringMatching() throws Exception {
153167
assertThat(repository.get(specificationBuilder.of(Product.class)
154-
.property("pictures.name").matching("picture?")
168+
.property("pictures.url.url").matching("picture?")
155169
.build())
156170
).containsExactly(product1, product2, product3, product6);
157171
assertThat(repository.get(specificationBuilder.of(Product.class)
158-
.property("pictures.name").matching("picture*")
172+
.property("pictures.url.url").matching("picture*")
159173
.build())
160174
).containsExactly(product1, product2, product3, product5, product6);
161175
assertThat(repository.get(specificationBuilder.of(Product.class)
162-
.property("pictures.name").matching("pict?re5")
176+
.property("pictures.url.url").matching("pict?re5")
163177
.build())
164178
).containsExactly(product6);
165179
assertThat(repository.get(specificationBuilder.of(Product.class)
166-
.property("pictures.name").matching("pic*re5")
180+
.property("pictures.url.url").matching("pic*re5")
167181
.build())
168182
).containsExactly(product6);
169183
assertThat(repository.get(specificationBuilder.of(Product.class)
170-
.property("pictures.name").matching("?ict?re5")
184+
.property("pictures.url.url").matching("?ict?re5")
171185
.build())
172186
).containsExactly(product6);
173187
assertThat(repository.get(specificationBuilder.of(Product.class)
174-
.property("pictures.name").matching("*cture5")
188+
.property("pictures.url.url").matching("*cture5")
175189
.build())
176190
).containsExactly(product6);
177191
}
178192

179193
@Test
180194
public void testStringMatchingWithTrim() throws Exception {
181195
assertThat(repository.get(specificationBuilder.of(Product.class)
182-
.property("pictures.name").matching("pict?re4")
196+
.property("pictures.url.url").matching("pict?re4")
183197
.build())
184198
).isEmpty();
185199
assertThat(repository.get(specificationBuilder.of(Product.class)
186-
.property("pictures.name").matching("pict?re4").trimmingLead()
200+
.property("pictures.url.url").matching("pict?re4").trimmingLead()
187201
.build())
188202
).containsExactly(product4);
189203
assertThat(repository.get(specificationBuilder.of(Product.class)
190-
.property("pictures.name").matching("pict?re4").trimmingTail()
204+
.property("pictures.url.url").matching("pict?re4").trimmingTail()
191205
.build())
192206
).containsExactly(product5);
193207
assertThat(repository.get(specificationBuilder.of(Product.class)
194-
.property("pictures.name").matching("pict?re4").trimming()
208+
.property("pictures.url.url").matching("pict?re4").trimming()
195209
.build())
196210
).containsExactly(product4, product5);
197211
}
198212

199213
@Test
200214
public void testStringMatchingIgnoringCase() throws Exception {
201215
assertThat(repository.get(specificationBuilder.of(Product.class)
202-
.property("pictures.name").matching("PI*urE3")
216+
.property("pictures.url.url").matching("PI*urE3")
203217
.build())
204218
).isEmpty();
205219
assertThat(repository.get(specificationBuilder.of(Product.class)
206-
.property("pictures.name").matching("PI*urE3").ignoringCase()
220+
.property("pictures.url.url").matching("PI*urE3").ignoringCase()
207221
.build())
208222
).containsExactly(product3);
209223
}
210224

211225
@Test
212226
public void testNot() throws Exception {
213227
assertThat(repository.get(specificationBuilder.of(Product.class)
214-
.property("pictures.name").not().equalTo("picture2")
228+
.property("pictures.url.url").not().equalTo("picture2")
215229
.build())
216230
).containsExactly(product1, product3, product4, product5, product6);
217231
}
218232

219233
@Test
220234
public void testOr() throws Exception {
221235
assertThat(repository.get(specificationBuilder.of(Product.class)
222-
.property("pictures.name").equalTo("picture2")
236+
.property("pictures.url.url").equalTo("picture2")
223237
.or()
224238
.property("designation").equalTo("product3")
225239
.or()
@@ -231,24 +245,54 @@ public void testOr() throws Exception {
231245
@Test
232246
public void testAnd() throws Exception {
233247
assertThat(repository.get(specificationBuilder.of(Product.class)
234-
.property("pictures.name").equalTo("picture2")
248+
.property("pictures.url.url").equalTo("picture2")
235249
.and()
236250
.property("designation").equalTo("product2")
237251
.and()
238252
.property("price").equalTo(2d)
239253
.build())
240254
).containsExactly(product2);
241255
assertThat(repository.get(specificationBuilder.of(Product.class)
242-
.property("pictures.name").equalTo("picture3")
256+
.property("pictures.url.url").equalTo("picture3")
243257
.and()
244258
.property("designation").equalTo("product2")
245259
.build())
246260
).isEmpty();
247261
}
248262

249-
public Product createProduct(long id, String designation, String pictureUrl, double price) {
250-
List<String> pictures = new ArrayList<>();
251-
pictures.add(pictureUrl);
252-
return new Product(id, designation, "summary", "details", pictures, price);
263+
@Test
264+
public void testSort() throws Exception {
265+
assertThat(repository.get(Specification.any(),
266+
new SortOption()
267+
.add("id", SortOption.Direction.DESCENDING)
268+
)
269+
).isSortedAccordingTo(Comparator.comparing(Product::getId).reversed());
270+
}
271+
272+
@Test
273+
public void testNestedSort() throws Exception {
274+
assertThat(repository.get(Specification.any(),
275+
new SortOption()
276+
.add("mainPicture.url", SortOption.Direction.DESCENDING)
277+
)
278+
).isSortedAccordingTo(Comparator.comparing((Product p) -> p.getMainPicture().getUrl()).reversed());
279+
}
280+
281+
@Test
282+
public void testMultiSort() throws Exception {
283+
assertThat(repository.get(Specification.any(),
284+
new SortOption()
285+
.add("price", SortOption.Direction.ASCENDING)
286+
.add("mainPicture.url", SortOption.Direction.DESCENDING)
287+
)
288+
).isSortedAccordingTo(Comparator.comparing(Product::getPrice)
289+
.thenComparing(
290+
Comparator.comparing((Product product) -> product.getMainPicture().getUrl()).reversed()));
291+
}
292+
293+
public Product createProduct(long id, String designation, String mainPictureUrl, String pictureUrl, double price) {
294+
List<Picture> pictures = new ArrayList<>();
295+
pictures.add(identityService.identify(new Picture(pictureUrl, id)));
296+
return new Product(id, designation, "summary", "details", mainPictureUrl, pictures, price);
253297
}
254298
}

morphia/src/it/java/org/seedstack/mongodb/morphia/fixtures/product/Picture.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,49 @@
88
/**
99
*
1010
*/
11+
1112
package org.seedstack.mongodb.morphia.fixtures.product;
1213

1314
import org.mongodb.morphia.annotations.Embedded;
14-
import org.seedstack.business.domain.BaseValueObject;
15-
16-
@Embedded
17-
public class Picture extends BaseValueObject {
18-
private String name;
15+
import org.mongodb.morphia.annotations.Entity;
16+
import org.mongodb.morphia.annotations.Id;
17+
import org.seedstack.business.domain.BaseEntity;
18+
import org.seedstack.business.domain.Identity;
19+
import org.seedstack.business.util.SequenceGenerator;
20+
import org.seedstack.business.util.inmemory.InMemory;
21+
22+
@Entity
23+
public class Picture extends BaseEntity<Long> {
24+
25+
@Id
26+
@Identity(generator = SequenceGenerator.class)
27+
@InMemory
28+
private Long id;
29+
@Embedded
30+
private PictureURL url;
1931
private Long productId;
2032

21-
public Picture(String name, Long productId) {
33+
public Picture(String url, Long productId) {
2234
super();
23-
this.name = name;
35+
this.url = new PictureURL(url);
2436
this.productId = productId;
2537
}
2638

27-
2839
public Picture() {
2940

3041
}
3142

32-
public String getName() {
33-
return name;
43+
@Override
44+
public Long getId() {
45+
return id;
46+
}
47+
48+
public PictureURL getUrl() {
49+
return url;
3450
}
3551

36-
public void setName(String name) {
37-
this.name = name;
52+
public void setUrl(PictureURL url) {
53+
this.url = url;
3854
}
3955

4056
public Long getProductId() {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org>
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
package org.seedstack.mongodb.morphia.fixtures.product;
9+
10+
import org.mongodb.morphia.annotations.Embedded;
11+
import org.seedstack.business.domain.BaseValueObject;
12+
13+
@Embedded
14+
public class PictureURL extends BaseValueObject {
15+
private String url;
16+
private boolean secured = false;
17+
18+
public PictureURL() {
19+
}
20+
21+
public PictureURL(String url) {
22+
this.url = url;
23+
}
24+
25+
public String getUrl() {
26+
return url;
27+
}
28+
29+
public void setUrl(String url) {
30+
this.url = url;
31+
}
32+
33+
public boolean isSecured() {
34+
return secured;
35+
}
36+
37+
public void setSecured(boolean secured) {
38+
this.secured = secured;
39+
}
40+
}

0 commit comments

Comments
 (0)