Merge branch 'release/5.18.0'
[cdmlib.git] / cdmlib-services / src / test / java / eu / etaxonomy / cdm / api / service / TaxonServiceSearchTest.java
1 /**
2 * Copyright (C) 2009 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.cdm.api.service;
11
12 import static org.junit.Assert.assertNotNull;
13
14 import java.io.FileNotFoundException;
15 import java.io.IOException;
16 import java.util.ArrayList;
17 import java.util.Arrays;
18 import java.util.EnumSet;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Set;
23 import java.util.UUID;
24
25 import org.apache.commons.lang.RandomStringUtils;
26 import org.apache.log4j.Level;
27 import org.apache.log4j.Logger;
28 import org.apache.lucene.document.Document;
29 import org.junit.Assert;
30 import org.junit.Before;
31 import org.junit.Ignore;
32 import org.junit.Test;
33 import org.unitils.dbunit.annotation.DataSet;
34 import org.unitils.spring.annotation.SpringBeanByType;
35
36 import eu.etaxonomy.cdm.api.service.config.FindTaxaAndNamesConfiguratorImpl;
37 import eu.etaxonomy.cdm.api.service.config.IFindTaxaAndNamesConfigurator;
38 import eu.etaxonomy.cdm.api.service.pager.Pager;
39 import eu.etaxonomy.cdm.api.service.search.ICdmMassIndexer;
40 import eu.etaxonomy.cdm.api.service.search.LuceneMultiSearchException;
41 import eu.etaxonomy.cdm.api.service.search.LuceneParseException;
42 import eu.etaxonomy.cdm.api.service.search.SearchResult;
43 import eu.etaxonomy.cdm.common.UTF8;
44 import eu.etaxonomy.cdm.common.monitor.DefaultProgressMonitor;
45 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
46 import eu.etaxonomy.cdm.model.common.CdmBase;
47 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
48 import eu.etaxonomy.cdm.model.common.Language;
49 import eu.etaxonomy.cdm.model.description.CategoricalData;
50 import eu.etaxonomy.cdm.model.description.CommonTaxonName;
51 import eu.etaxonomy.cdm.model.description.DescriptionBase;
52 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
53 import eu.etaxonomy.cdm.model.description.Distribution;
54 import eu.etaxonomy.cdm.model.description.Feature;
55 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
56 import eu.etaxonomy.cdm.model.description.State;
57 import eu.etaxonomy.cdm.model.description.StateData;
58 import eu.etaxonomy.cdm.model.description.TaxonDescription;
59 import eu.etaxonomy.cdm.model.description.TextData;
60 import eu.etaxonomy.cdm.model.location.Country;
61 import eu.etaxonomy.cdm.model.location.NamedArea;
62 import eu.etaxonomy.cdm.model.name.IBotanicalName;
63 import eu.etaxonomy.cdm.model.name.Rank;
64 import eu.etaxonomy.cdm.model.name.TaxonName;
65 import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
66 import eu.etaxonomy.cdm.model.reference.Reference;
67 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
68 import eu.etaxonomy.cdm.model.taxon.Classification;
69 import eu.etaxonomy.cdm.model.taxon.Synonym;
70 import eu.etaxonomy.cdm.model.taxon.SynonymType;
71 import eu.etaxonomy.cdm.model.taxon.Taxon;
72 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
73 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
74 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
75 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
76 import eu.etaxonomy.cdm.model.term.DefinedTermBase;
77 import eu.etaxonomy.cdm.persistence.query.MatchMode;
78 import eu.etaxonomy.cdm.persistence.query.OrderHint;
79 import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
80 import eu.etaxonomy.cdm.test.unitils.CleanSweepInsertLoadStrategy;
81
82 /**
83 * @author a.babadshanjan, a.kohlbecker
84 * @since 04.02.2009
85 */
86 public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
87
88 private static Logger logger = Logger.getLogger(TaxonServiceSearchTest.class);
89
90 private static final UUID ABIES_BALSAMEA_UUID = UUID.fromString("f65d47bd-4f49-4ab1-bc4a-bc4551eaa1a8");
91 private static final UUID ABIES_ALBA_UUID = UUID.fromString("7dbd5810-a3e5-44b6-b563-25152b8867f4");
92 private static final UUID CLASSIFICATION_UUID = UUID.fromString("2a5ceebb-4830-4524-b330-78461bf8cb6b");
93 private static final UUID CLASSIFICATION_ALT_UUID = UUID.fromString("d7c741e3-ae9e-4a7d-a566-9e3a7a0b51ce");
94 private static final UUID ABIES_SUBALPINA_UUID = UUID.fromString("9fee273c-c819-4f1f-913a-cd910465df51");
95 private static final UUID ABIES_LASIOCARPA_UUID = UUID.fromString("9ce1fecf-c1ad-4127-be01-85d5d9f847ce");
96
97 private static final UUID ROOTNODE_CLASSIFICATION_5000 = UUID.fromString("a8266e45-091f-432f-87ae-c625e6aa9bbc");
98
99 private static final UUID DESC_ABIES_BALSAMEA_UUID = UUID.fromString("900108d8-e6ce-495e-b32e-7aad3099135e");
100 private static final UUID DESC_ABIES_ALBA_UUID = UUID.fromString("ec8bba03-d993-4c85-8472-18b14942464b");
101 private static final UUID DESC_ABIES_KAWAKAMII_SEC_KOMAROV_UUID = UUID.fromString("e9d8c2fd-6409-46d5-9c2e-14a2bbb1b2b1");
102
103
104 private static final int NUM_OF_NEW_RADOM_ENTITIES = 1000;
105
106 private boolean includeUnpublished = true;
107
108
109
110 @SpringBeanByType
111 private ITaxonService taxonService;
112 @SpringBeanByType
113 private ITermService termService;
114 @SpringBeanByType
115 private IClassificationService classificationService;
116 @SpringBeanByType
117 private IReferenceService referenceService;
118 @SpringBeanByType
119 private IDescriptionService descriptionService;
120 @SpringBeanByType
121 private INameService nameService;
122 @SpringBeanByType
123 private ITaxonNodeService nodeService;
124
125 @SpringBeanByType
126 private ICdmMassIndexer indexer;
127
128
129 private static final int BENCHMARK_ROUNDS = 300;
130
131 private Set<Class<? extends CdmBase>> typesToIndex = null;
132
133 private NamedArea germany;
134 private NamedArea france ;
135 private NamedArea russia ;
136 private NamedArea canada ;
137
138 @Before
139 public void setUp() throws Exception {
140 typesToIndex = new HashSet<>();
141 typesToIndex.add(DescriptionElementBase.class);
142 typesToIndex.add(TaxonBase.class);
143 typesToIndex.add(TaxonRelationship.class);
144
145 germany = Country.GERMANY();
146 france = Country.FRANCEFRENCHREPUBLIC();
147 russia = Country.RUSSIANFEDERATION();
148 canada = Country.CANADA();
149
150 includeUnpublished = true;
151 }
152
153 @Test
154 public void testDbUnitUsageTest() throws Exception {
155 assertNotNull("taxonService should exist", taxonService);
156 assertNotNull("nameService should exist", nameService);
157 }
158
159
160 @SuppressWarnings("rawtypes")
161 @Test
162 @DataSet
163 public final void testPurgeAndReindex() throws IOException, LuceneParseException {
164
165 refreshLuceneIndex();
166 TaxonNode subtree = null;
167
168 Pager<SearchResult<TaxonBase>> pager = taxonService.findByFullText(null, "Abies", null, subtree,
169 includeUnpublished, null, true, null, null, null, null); // --> 8
170 Assert.assertEquals("Expecting 8 entities", 8, pager.getCount().intValue());
171
172 indexer.purge(null);
173 commitAndStartNewTransaction(null);
174
175 pager = taxonService.findByFullText(null, "Abies", null, subtree, includeUnpublished, null, true, null, null, null, null); // --> 0
176 Assert.assertEquals("Expecting no entities since the index has been purged", 0, pager.getCount().intValue());
177
178 indexer.reindex(indexer.indexedClasses(), null);
179 commitAndStartNewTransaction(null);
180
181 pager = taxonService.findByFullText(null, "Abies", null, subtree, includeUnpublished, null, true, null, null, null, null); // --> 8
182 Assert.assertEquals("Expecting 8 entities", 8, pager.getCount().intValue());
183 }
184
185
186 @SuppressWarnings("rawtypes")
187 @Test
188 @DataSet
189 public final void testFindByDescriptionElementFullText_CommonName() throws IOException,
190 LuceneParseException {
191
192 TaxonNode subtree = null;
193 refreshLuceneIndex();
194
195 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"tanne",
196 null, subtree, null, null,
197 false, null, null, null, null);
198 Assert.assertEquals("Expecting one entity when searching for CommonTaxonName", 1,
199 pager.getCount().intValue());
200
201 // the description containing the Nulltanne has no taxon attached,
202 // taxon.id = null
203 pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Nulltanne", null, subtree, null, null,
204 false, null, null, null, null);
205 Assert.assertEquals("Expecting no entity when searching for 'Nulltanne' ", 0, pager.getCount().intValue());
206
207 pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"tanne", null, subtree, null,
208 Arrays.asList(new Language[] { Language.GERMAN() }), false, null, null, null, null);
209 Assert.assertEquals("Expecting one entity when searching in German", 1, pager.getCount().intValue());
210
211 pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"tanne", null, subtree, null,
212 Arrays.asList(new Language[] { Language.RUSSIAN() }), false, null, null, null, null);
213 Assert.assertEquals("Expecting no entity when searching in Russian", 0, pager.getCount().intValue());
214
215 }
216
217 @SuppressWarnings("rawtypes")
218 @Test
219 @DataSet
220 public final void testFindByDescriptionElementFullText_Distribution() throws IOException, LuceneParseException {
221
222 refreshLuceneIndex();
223 TaxonNode subtree = null;
224
225 // by Area
226 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(null, "Canada", null, subtree, null, null, false, null, null, null, null);
227 Assert.assertEquals("Expecting one entity when searching for arae 'Canada'", 1, pager.getCount().intValue());
228 // by Status
229 pager = taxonService.findByDescriptionElementFullText(null, "present", null, subtree, null, null, false, null, null, null, null);
230 Assert.assertEquals("Expecting one entity when searching for status 'present'", 1, pager.getCount().intValue());
231 }
232
233 @SuppressWarnings("rawtypes")
234 @Test
235 @DataSet
236 public final void testFindByDescriptionElementFullText_wildcard() throws IOException, LuceneParseException {
237
238 refreshLuceneIndex();
239 TaxonNode subtree = null;
240
241 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"*", null, subtree, null, null, false, null, null, null, null);
242 Assert.assertEquals("Expecting one entity when searching for CommonTaxonName", 1, pager.getCount().intValue());
243 }
244
245 /**
246 * Regression test for #3113 (hibernate search: wildcard query can cause BooleanQuery$TooManyClauses: maxClauseCount is set to 1024)
247 *
248 * @throws IOException
249 * @throws LuceneParseException
250 */
251 @SuppressWarnings("rawtypes")
252 @Test
253 @DataSet
254 public final void testFindByDescriptionElementFullText_TooManyClauses() throws IOException, LuceneParseException {
255
256 TaxonNode subtree = null;
257
258 // generate 1024 terms to reproduce the bug
259 TaxonDescription description = (TaxonDescription) descriptionService.find(DESC_ABIES_ALBA_UUID);
260 Set<String> uniqueRandomStrs = new HashSet<>(1024);
261 while(uniqueRandomStrs.size() < 1024){
262 uniqueRandomStrs.add(RandomStringUtils.random(10, true, false));
263 }
264 for(String rndStr: uniqueRandomStrs){
265 description.addElement(CommonTaxonName.NewInstance("Rot" + rndStr, Language.DEFAULT()));
266 }
267 descriptionService.saveOrUpdate(description);
268 commitAndStartNewTransaction(null);
269
270 refreshLuceneIndex();
271
272 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Rot*", null, subtree, null, null, false, null, null, null, null);
273 Assert.assertEquals("Expecting all 1024 entities grouped into one SearchResult item when searching for Rot*", 1, pager.getCount().intValue());
274 }
275
276 /**
277 * Regression test for #3116 (fulltext search: always only one page of results)
278 *
279 * @throws IOException
280 * @throws LuceneParseException
281 */
282 @SuppressWarnings("rawtypes")
283 @Test
284 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
285 public final void testFullText_Paging() throws IOException, LuceneParseException {
286
287 TaxonNode subtree = null;
288 Reference sec = ReferenceFactory.newDatabase();
289 referenceService.save(sec);
290
291 Set<String> uniqueRandomStrs = new HashSet<>(1024);
292 int numOfItems = 100;
293 while(uniqueRandomStrs.size() < numOfItems){
294 uniqueRandomStrs.add(RandomStringUtils.random(5, true, false));
295 }
296
297 for(String rndStr: uniqueRandomStrs){
298
299 Taxon taxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.SERIES()), sec);
300 taxon.setTitleCache("Tax" + rndStr, true);
301 taxonService.save(taxon);
302
303 TaxonDescription description = TaxonDescription.NewInstance(taxon);
304 description.addElement(CommonTaxonName.NewInstance("Rot" + rndStr, Language.DEFAULT()));
305 descriptionService.saveOrUpdate(description);
306 }
307
308 commitAndStartNewTransaction(new String[]{/*"TAXONBASE"*/});
309 refreshLuceneIndex();
310
311 int pageSize = 10;
312
313 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Rot*", null, subtree, null, null, false, pageSize, null, null, null);
314 Assert.assertEquals("unexpeted number of pages", Integer.valueOf(numOfItems / pageSize), pager.getPagesAvailable());
315 pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Rot*", null, subtree, null, null, false, pageSize, 9, null, null);
316 Assert.assertNotNull("last page must have records", pager.getRecords());
317 Assert.assertNotNull("last item on last page must exist", pager.getRecords().get(0));
318 pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Rot*", null, subtree, null, null, false, pageSize, 10, null, null);
319 Assert.assertNotNull("last page + 1 must not have any records", pager.getRecords());
320 }
321
322 /**
323 * test for max score and sort by score of hit groups
324 * with all matches per taxon in a single TextData element
325 * see {@link #testFullText_ScoreAndOrder_2()} for the complement
326 * test with matches in multiple TextData per taxon
327 *
328 * @throws IOException
329 * @throws LuceneParseException
330 */
331 @SuppressWarnings("rawtypes")
332 @Test
333 @DataSet
334 @Ignore // test fails, maybe the assumptions made here are not compatible with the lucene scoring mechanism see http://lucene.apache.org/core/3_6_1/scoring.html
335 public final void testFullText_ScoreAndOrder_1() throws IOException, LuceneParseException {
336
337 TaxonNode subtree = null;
338 int numOfTaxa = 3;
339
340 UUID[] taxonUuids = new UUID[numOfTaxa];
341 StringBuilder text = new StringBuilder();
342
343 for(int i = 0; i < numOfTaxa; i++){
344
345 Taxon taxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(null), null);
346 taxon.setTitleCache("Taxon_" + i, true);
347 taxonUuids[i] = taxon.getUuid();
348 taxonService.save(taxon);
349
350 text.append(" ").append("Rot");
351 TaxonDescription description = TaxonDescription.NewInstance(taxon);
352 description.addElement(TextData.NewInstance(text.toString(), Language.DEFAULT(), null));
353 descriptionService.saveOrUpdate(description);
354 }
355
356 commitAndStartNewTransaction(null);
357 refreshLuceneIndex();
358
359 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(TextData.class, "Rot", null, subtree, null, null, false, null, null, null, null);
360 for(int i = 0; i < numOfTaxa; i++){
361 Assert.assertEquals("taxa should be orderd by relevance (= score)", taxonUuids[numOfTaxa - i - 1], pager.getRecords().get(i).getEntity().getUuid());
362 }
363 Assert.assertEquals("max score should be equal to the score of the first element", pager.getRecords().get(0).getMaxScore(), pager.getRecords().get(0).getScore(), 0);
364 }
365
366 /**
367 * test for max score and sort by score of hit groups
368 * with all matches per taxon in a multiple TextData elements
369 * see {@link #testFullText_ScoreAndOrder_1()} for the complement
370 * test with matches in a single TextData per taxon
371 *
372 * @throws IOException
373 * @throws LuceneParseException
374 */
375 @SuppressWarnings("rawtypes")
376 @Test
377 @DataSet
378 @Ignore // test fails, maybe the assumptions made here are not compatible with the lucene scoring mechanism see http://lucene.apache.org/core/3_6_1/scoring.html
379 public final void testFullText_ScoreAndOrder_2() throws IOException, LuceneParseException {
380
381 TaxonNode subtree = null;
382 int numOfTaxa = 3;
383
384 UUID[] taxonUuids = new UUID[numOfTaxa];
385
386 for(int i = 0; i < numOfTaxa; i++){
387
388 Taxon taxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(null), null);
389 taxon.setTitleCache("Taxon_" + i, true);
390 taxonUuids[i] = taxon.getUuid();
391 taxonService.save(taxon);
392
393 TaxonDescription description = TaxonDescription.NewInstance(taxon);
394 for(int k = 0; k < i; k++){
395 description.addElement(TextData.NewInstance("Rot", Language.DEFAULT(), null));
396 }
397 descriptionService.saveOrUpdate(description);
398 }
399
400 commitAndStartNewTransaction(null);
401 refreshLuceneIndex();
402
403 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(TextData.class, "Rot", null, subtree, null, null, false, null, null, null, null);
404 for(int i = 0; i < numOfTaxa; i++){
405 Assert.assertEquals("taxa should be orderd by relevance (= score)", taxonUuids[numOfTaxa - i - 1], pager.getRecords().get(i).getEntity().getUuid());
406 }
407 Assert.assertEquals("max score should be equal to the score of the first element", pager.getRecords().get(0).getMaxScore(), pager.getRecords().get(0).getScore(), 0);
408 }
409
410
411 /**
412 * @throws IOException
413 * @throws LuceneParseException
414 * @throws LuceneMultiSearchException
415 */
416 @Test
417 @DataSet
418 public final void testFullText_Grouping() throws IOException, LuceneParseException, LuceneMultiSearchException {
419
420 TaxonNode subtree = null;
421 TaxonDescription description = (TaxonDescription) descriptionService.find(DESC_ABIES_ALBA_UUID);
422 Set<String> uniqueRandomStrs = new HashSet<>(1024);
423 int numOfItems = 100;
424 while(uniqueRandomStrs.size() < numOfItems){
425 uniqueRandomStrs.add(RandomStringUtils.random(5, true, false));
426 }
427 for(String rndStr: uniqueRandomStrs){
428 description.addElement(CommonTaxonName.NewInstance("Rot" + rndStr, Language.DEFAULT()));
429 }
430 descriptionService.saveOrUpdate(description);
431
432 commitAndStartNewTransaction(new String[]{"DESCRIPTIONELEMENTBASE"});
433
434 refreshLuceneIndex();
435
436 int pageSize = 10;
437
438 boolean highlightFragments = true;
439
440 // test with findByDescriptionElementFullText
441 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Rot*", null, subtree, null, null, highlightFragments, pageSize, null, null, null);
442 logFreeTextSearchResults(pager, Level.DEBUG, null);
443 Assert.assertEquals("All matches should be grouped into a single SearchResult element", 1, pager.getRecords().size());
444 Assert.assertEquals("The count property of the pager must be set correctly", 1, pager.getCount().intValue());
445 Map<String, String[]> highlightMap = pager.getRecords().get(0).getFieldHighlightMap();
446 // maxDocsPerGroup is defined in LuceneSearch and defaults to 10
447 int maxDocsPerGroup = 10;
448 Assert.assertEquals("expecting 10 highlighted fragments of field 'name'", maxDocsPerGroup, highlightMap.get("name").length);
449
450 // test with findByEverythingFullText
451 pager = taxonService.findByEverythingFullText( "Rot*", null, subtree, includeUnpublished, null, highlightFragments, pageSize, null, null, null);
452 logFreeTextSearchResults(pager, Level.DEBUG, null);
453 Assert.assertEquals("All matches should be grouped into a single SearchResult element", 1, pager.getRecords().size());
454 Assert.assertEquals("The count property of the pager must be set correctly", 1, pager.getCount().intValue());
455 highlightMap = pager.getRecords().get(0).getFieldHighlightMap();
456 // maxDocsPerGroup is defined in LuceneSearch and defaults to 10
457 maxDocsPerGroup = 10;
458 Assert.assertEquals("expecting 10 highlighted fragments of field 'name'", maxDocsPerGroup, highlightMap.get("name").length);
459
460 }
461
462 @SuppressWarnings("rawtypes")
463 @Test
464 @DataSet
465 public final void testFindByDescriptionElementFullText_TextData() throws IOException, LuceneParseException {
466
467 refreshLuceneIndex();
468 TaxonNode subtree = null;
469
470 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(TextData.class, "Abies", null, subtree, null, null, false, null, null, null, null);
471 logFreeTextSearchResults(pager, Level.DEBUG, null);
472 Assert.assertEquals("Expecting one entity when searching for any TextData", 1, pager.getCount().intValue());
473 Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());
474 Assert.assertTrue("Expecting two docs, one for RUSSIAN and one for GERMAN", pager.getRecords().get(0).getDocs().size() == 2);
475 Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getDocs().iterator().next().get("inDescription.taxon.titleCache"));
476
477
478 pager = taxonService.findByDescriptionElementFullText(null, "Abies", null, subtree, null, null, false, null, null, null, null);
479 Assert.assertEquals("Expecting one entity when searching for any type", 1, pager.getCount().intValue());
480
481 pager = taxonService.findByDescriptionElementFullText(null, "Abies", null, subtree, Arrays.asList(new Feature[]{Feature.UNKNOWN()}), null, false, null, null, null, null);
482 Assert.assertEquals("Expecting one entity when searching for any type and for Feature DESCRIPTION", 1, pager.getCount().intValue());
483
484 pager = taxonService.findByDescriptionElementFullText(null, "Abies", null, subtree, Arrays.asList(new Feature[]{Feature.CHROMOSOME_NUMBER()}), null, false, null, null, null, null);
485 Assert.assertEquals("Expecting no entity when searching for any type and for Feature CHROMOSOME_NUMBER", 0, pager.getCount().intValue());
486
487 pager = taxonService.findByDescriptionElementFullText(null, "Abies", null, subtree, Arrays.asList(new Feature[]{Feature.CHROMOSOME_NUMBER(), Feature.UNKNOWN()}), null, false, null, null, null, null);
488 Assert.assertEquals("Expecting no entity when searching for any type and for Feature DESCRIPTION or CHROMOSOME_NUMBER", 1, pager.getCount().intValue());
489
490 pager = taxonService.findByDescriptionElementFullText(Distribution.class, "Abies", null, subtree, null, null, false, null, null, null, null);
491 Assert.assertEquals("Expecting no entity when searching for Distribution", 0, pager.getCount().intValue());
492
493 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Бальзам", null, subtree, null, Arrays.asList(new Language[]{}), false, null, null, null, null);
494 Assert.assertEquals("Expecting one entity", 1, pager.getCount().intValue());
495 Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());
496
497 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Бальзам", null, subtree, null, Arrays.asList(new Language[]{Language.RUSSIAN()}), false, null, null, null, null);
498 Assert.assertEquals("Expecting one entity", 1, pager.getCount().intValue());
499 Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());
500
501 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Бальзам", null, subtree, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
502 Assert.assertEquals("Expecting no entity", 0, pager.getCount().intValue());
503
504 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, subtree, null, Arrays.asList(new Language[]{Language.GERMAN(), Language.RUSSIAN()}), false, null, null, null, null);
505 Assert.assertEquals("Expecting one entity", 1, pager.getCount().intValue());
506 Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());
507 }
508
509 @SuppressWarnings("rawtypes")
510 @Test
511 @DataSet
512 public final void testFindByDescriptionElementFullText_MultipleWords() throws IOException, LuceneParseException {
513
514 refreshLuceneIndex();
515 TaxonNode subtree = null;
516
517 // Pflanzenart aus der Gattung der Tannen
518 long start = System.currentTimeMillis();
519
520 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(TextData.class, "Pflanzenart Tannen", null, subtree, null, null, false, null, null, null, null);
521 Assert.assertEquals("OR search : Expecting one entity", 1, pager.getCount().intValue());
522
523 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Pflanzenart Wespen", null, subtree, null, null, false, null, null, null, null);
524 Assert.assertEquals("OR search : Expecting one entity", 1, pager.getCount().intValue());
525
526 pager = taxonService.findByDescriptionElementFullText(TextData.class, "+Pflanzenart +Tannen", null, subtree, null, null, false, null, null, null, null);
527 Assert.assertEquals("AND search : Expecting one entity", 1, pager.getCount().intValue());
528
529 pager = taxonService.findByDescriptionElementFullText(TextData.class, "+Pflanzenart +Wespen", null, subtree, null, null, false, null, null, null, null);
530 Assert.assertEquals("AND search : Expecting no entity", 0, pager.getCount().intValue());
531
532 pager = taxonService.findByDescriptionElementFullText(TextData.class, "\"Pflanzenart aus der Gattung der Tannen\"", null, subtree, null, null, false, null, null, null, null);
533 Assert.assertEquals("Phrase search : Expecting one entity", 1, pager.getCount().intValue());
534
535 pager = taxonService.findByDescriptionElementFullText(TextData.class, "\"Pflanzenart aus der Gattung der Wespen\"", null, subtree, null, null, false, null, null, null, null);
536 Assert.assertEquals("Phrase search : Expecting one entity", 0, pager.getCount().intValue());
537
538 logger.info("testFindByDescriptionElementFullText_MultipleWords() duration: " + (System.currentTimeMillis() - start) + "ms");
539
540 }
541
542
543 @SuppressWarnings("rawtypes")
544 @Test
545 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
546 public final void testFindByDescriptionElementFullText_modify_DescriptionElement() throws IOException, LuceneParseException {
547
548 refreshLuceneIndex();
549 TaxonNode subtree = null;
550
551 //
552 // modify the DescriptionElement
553 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, subtree, null, Arrays.asList(new Language[]{Language.GERMAN(), Language.RUSSIAN()}), false, null, null, null, null);
554 Assert.assertTrue("Search did not return any results", pager.getRecords().size() > 0);
555 Assert.assertTrue("Expecting only one doc", pager.getRecords().get(0).getDocs().size() == 1);
556 Document indexDocument = pager.getRecords().get(0).getDocs().iterator().next();
557 String[] descriptionElementUuidStr = indexDocument.getValues("uuid");
558 String[] inDescriptionUuidStr = indexDocument.getValues("inDescription.uuid");
559 // is only one uuid!
560 DescriptionElementBase textData = descriptionService.getDescriptionElementByUuid(UUID.fromString(descriptionElementUuidStr[0]));
561
562 ((TextData)textData).removeText(Language.GERMAN());
563 ((TextData)textData).putText(Language.SPANISH_CASTILIAN(), "abeto bals"+UTF8.SMALL_A_ACUTE+"mico");
564
565 descriptionService.saveDescriptionElement(textData);
566 commitAndStartNewTransaction(null);
567 // printDataSet(System.out, new String[] {
568 // "DESCRIPTIONELEMENTBASE", "LANGUAGESTRING", "DESCRIPTIONELEMENTBASE_LANGUAGESTRING" }
569 // );
570
571 //
572 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, subtree, null, Arrays.asList(new Language[]{Language.GERMAN(), Language.RUSSIAN()}), false, null, null, null, null);
573 Assert.assertEquals("The german 'Balsam-Tanne' TextData should no longer be indexed", 0, pager.getCount().intValue());
574 pager = taxonService.findByDescriptionElementFullText(TextData.class, "abeto", null, subtree, null, Arrays.asList(new Language[]{Language.SPANISH_CASTILIAN()}), false, null, null, null, null);
575 Assert.assertEquals("expecting to find the SPANISH_CASTILIAN 'abeto bals"+UTF8.SMALL_A_ACUTE+"mico'", 1, pager.getCount().intValue());
576 pager = taxonService.findByDescriptionElementFullText(TextData.class, "bals"+UTF8.SMALL_A_ACUTE+"mico", null, subtree, null, null, false, null, null, null, null);
577 Assert.assertEquals("expecting to find the SPANISH_CASTILIAN 'abeto bals"+UTF8.SMALL_A_ACUTE+"mico'", 1, pager.getCount().intValue());
578
579 //
580 // modify the DescriptionElement via the Description object
581 DescriptionBase<?> description = descriptionService.find(UUID.fromString(inDescriptionUuidStr[0]));
582 Set<DescriptionElementBase> elements = description.getElements();
583 for( DescriptionElementBase elm : elements){
584 if(elm.getUuid().toString().equals(descriptionElementUuidStr[0])){
585 ((TextData)elm).removeText(Language.SPANISH_CASTILIAN());
586 ((TextData)elm).putText(Language.POLISH(), "Jod"+UTF8.POLISH_L+"a balsamiczna");
587 }
588 }
589 descriptionService.saveOrUpdate(description);
590 commitAndStartNewTransaction(null);
591 pager = taxonService.findByDescriptionElementFullText(TextData.class, "abeto", null, subtree, null, Arrays.asList(new Language[]{Language.SPANISH_CASTILIAN()}), false, null, null, null, null);
592 Assert.assertEquals("The spanish 'abeto bals"+UTF8.SMALL_A_ACUTE+"mico' TextData should no longer be indexed", 0, pager.getCount().intValue());
593 pager = taxonService.findByDescriptionElementFullText(TextData.class, "balsamiczna", null, subtree, null, Arrays.asList(new Language[]{Language.POLISH()}), false, null, null, null, null);
594 Assert.assertEquals("expecting to find the POLISH 'Jod"+UTF8.POLISH_L+"a balsamiczna'", 1, pager.getCount().intValue());
595 }
596
597 @SuppressWarnings("rawtypes")
598 @Test
599 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
600 public final void testFindByDescriptionElementFullText_modify_Taxon() throws IOException, LuceneParseException {
601
602 refreshLuceneIndex();
603 TaxonNode subtree = null;
604
605 Taxon t_abies_balsamea = (Taxon)taxonService.find(ABIES_BALSAMEA_UUID);
606 TaxonDescription d_abies_balsamea = (TaxonDescription)descriptionService.find(DESC_ABIES_BALSAMEA_UUID);
607
608 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne",
609 null, subtree, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
610 Assert.assertEquals("expecting to find the GERMAN 'Balsam-Tanne'", 1, pager.getCount().intValue());
611
612 // exchange the Taxon with another one via the Taxon object
613 // 1.) remove existing description:
614 t_abies_balsamea.removeDescription(d_abies_balsamea);
615
616 taxonService.saveOrUpdate(t_abies_balsamea);
617 commitAndStartNewTransaction(null);
618
619 t_abies_balsamea = (Taxon)taxonService.find(t_abies_balsamea.getUuid());
620
621 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne",
622 null, subtree, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
623 Assert.assertEquals("'Balsam-Tanne' should no longer be found", 0, pager.getCount().intValue());
624
625 // 2.) create new description and add to taxon:
626 TaxonDescription d_abies_balsamea_new = TaxonDescription.NewInstance();
627 d_abies_balsamea_new
628 .addElement(TextData
629 .NewInstance(
630 "Die Balsamtanne ist mit bis zu 30 m Höhe ein mittelgro"+UTF8.SHARP_S+"er Baum und kann bis zu 200 Jahre alt werden",
631 Language.GERMAN(), null));
632 t_abies_balsamea.addDescription(d_abies_balsamea_new);
633 // set authorshipCache to null to avoid validation exception,
634 // this is maybe not needed in future, see ticket #3344
635 IBotanicalName abies_balsamea = CdmBase.deproxy(t_abies_balsamea.getName(), TaxonName.class);
636 abies_balsamea.setAuthorshipCache(null);
637 printDataSet(System.err, new String[] {"LANGUAGESTRING_AUD"});
638 taxonService.saveOrUpdate(t_abies_balsamea);
639 commitAndStartNewTransaction(null);
640
641 // printDataSet(System.out, new String[] {
642 // "DESCRIPTIONBASE"
643 // });
644
645 pager = taxonService.findByDescriptionElementFullText(TextData.class, "mittelgro"+UTF8.SHARP_S+"er Baum",
646 null, subtree, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
647 Assert.assertEquals("the taxon should be found via the new Description", 1, pager.getCount().intValue());
648 }
649
650 @SuppressWarnings("rawtypes")
651 @Test
652 @DataSet
653 public final void testFindByDescriptionElementFullText_modify_Classification() throws IOException, LuceneParseException {
654
655 refreshLuceneIndex();
656 TaxonNode subtree = null;
657
658 // put taxon into other classification, new taxon node
659 Classification classification = classificationService.find(CLASSIFICATION_UUID);
660 Classification alternateClassification = classificationService.find(CLASSIFICATION_ALT_UUID);
661
662 // TODO: why is the test failing when the childNode is already retrieved here, and not after the following four lines?
663 //TaxonNode childNode = classification.getChildNodes().iterator().next();
664
665 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, subtree, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
666 Assert.assertEquals("expecting to find the GERMAN 'Balsam-Tanne' even if filtering by classification", 1, pager.getCount().intValue());
667 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", alternateClassification, subtree, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
668 Assert.assertEquals("GERMAN 'Balsam-Tanne' should NOT be found in other classification", 0, pager.getCount().intValue());
669
670 // check for the right taxon node
671 TaxonNode childNode = classification.getChildNodes().iterator().next();
672 Assert.assertEquals("expecting Abies balsamea sec.", childNode.getTaxon().getUuid(), ABIES_BALSAMEA_UUID);
673 Assert.assertEquals("expecting default classification", childNode.getClassification().getUuid(), CLASSIFICATION_UUID);
674
675 // moving the taxon around, the rootnode is only a proxy
676 alternateClassification.setRootNode(HibernateProxyHelper.deproxy(alternateClassification.getRootNode(), TaxonNode.class));
677 alternateClassification.addChildNode(childNode, null, null);
678
679 classificationService.saveOrUpdate(alternateClassification);
680 commitAndStartNewTransaction(null);
681
682 // printDataSet(System.out, new String[] {
683 // "TAXONBASE", "TAXONNODE", "CLASSIFICATION"
684 // });
685
686 // reload classification
687 classification = classificationService.find(CLASSIFICATION_UUID);
688 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne",
689 alternateClassification, subtree, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
690 Assert.assertEquals("GERMAN 'Balsam-Tanne' should now be found in other classification", 1, pager.getCount().intValue());
691
692 classification.getChildNodes().clear();
693 classificationService.saveOrUpdate(classification);
694 commitAndStartNewTransaction(null);
695
696 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne",
697 classification, subtree, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
698 Assert.assertEquals("Now the GERMAN 'Balsam-Tanne' should NOT be found in original classification", 0, pager.getCount().intValue());
699
700 }
701
702 @SuppressWarnings("rawtypes")
703 @Test
704 @DataSet
705 public final void testFindByDescriptionElementFullText_CategoricalData() throws IOException, LuceneParseException {
706
707 TaxonNode subtree = null;
708 // add CategoricalData
709 DescriptionBase d_abies_balsamea = descriptionService.find(DESC_ABIES_BALSAMEA_UUID);
710 // Categorical data
711 CategoricalData cdata = CategoricalData.NewInstance();
712 cdata.setFeature(Feature.DESCRIPTION());
713 State state = State.NewInstance("green", "green", "gn");
714
715 StateData statedata = StateData.NewInstance(state);
716 statedata.putModifyingText(Language.ENGLISH(), "always, even during winter");
717 cdata.addStateData(statedata);
718 d_abies_balsamea.addElement(cdata);
719
720 UUID termUUID = termService.save(state).getUuid();
721 descriptionService.save(d_abies_balsamea);
722
723 commitAndStartNewTransaction(null);
724
725 // printDataSet(System.out, new String[] {
726 // "STATEDATA", "STATEDATA_DEFINEDTERMBASE", "STATEDATA_LANGUAGESTRING", "LANGUAGESTRING"});
727
728 refreshLuceneIndex();
729
730 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(CategoricalData.class, "green", null, subtree, null, null, false, null, null, null, null);
731 Assert.assertEquals("Expecting one entity", 1, pager.getCount().intValue());
732 Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());
733 Assert.assertTrue("Expecting only one doc", pager.getRecords().get(0).getDocs().size() == 1);
734 Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getDocs().iterator().next().get("inDescription.taxon.titleCache"));
735
736
737 //TODO modify the StateData
738 TaxonBase taxon = pager.getRecords().get(0).getEntity();
739
740 String newName = "Quercus robur";
741 taxon.setTitleCache(newName + " sec. ", true);
742
743 taxonService.saveOrUpdate(taxon);
744 commitAndStartNewTransaction(null);
745
746 taxon = taxonService.find(taxon.getUuid());
747 Assert.assertEquals(newName + " sec. ", taxon.getTitleCache());
748 DefinedTermBase term = termService.find(termUUID);
749
750 termService.delete(term);
751
752 }
753
754 @SuppressWarnings("rawtypes")
755 @Test
756 @DataSet
757 public final void testFindByDescriptionElementFullText_Highlighting() throws IOException, LuceneParseException {
758
759 refreshLuceneIndex();
760 TaxonNode subtree = null;
761
762 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDescriptionElementFullText(TextData.class, "Abies", null, subtree, null, null, true, null, null, null, null);
763 Assert.assertEquals("Expecting one entity when searching for any TextData", 1, pager.getCount().intValue());
764 SearchResult<TaxonBase> searchResult = pager.getRecords().get(0);
765 Assert.assertTrue("the map of highlighted fragments should contain at least one item", searchResult.getFieldHighlightMap().size() > 0);
766 String[] fragments = searchResult.getFieldHighlightMap().values().iterator().next();
767 Assert.assertTrue("first fragments should contains serch term", fragments[0].contains("<B>Abies</B>"));
768
769 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Pflanzenart Tannen", null, subtree, null, null, true, null, null, null, null);
770 searchResult = pager.getRecords().get(0);
771 Assert.assertTrue("Phrase search : Expecting at least one item in highlighted fragments", searchResult.getFieldHighlightMap().size() > 0);
772 fragments = searchResult.getFieldHighlightMap().values().iterator().next();
773 Assert.assertTrue("first fragments should contains serch term", fragments[0].contains("<B>Pflanzenart</B>") || fragments[0].contains("<B>Tannen</B>"));
774
775 pager = taxonService.findByDescriptionElementFullText(TextData.class, "+Pflanzenart +Tannen", null, subtree, null, null, true, null, null, null, null);
776 searchResult = pager.getRecords().get(0);
777 Assert.assertTrue("Phrase search : Expecting at least one item in highlighted fragments", searchResult.getFieldHighlightMap().size() > 0);
778 fragments = searchResult.getFieldHighlightMap().values().iterator().next();
779 Assert.assertTrue("first fragments should contains serch term", fragments[0].contains("<B>Pflanzenart</B>") && fragments[0].contains("<B>Tannen</B>"));
780
781 pager = taxonService.findByDescriptionElementFullText(TextData.class, "\"Pflanzenart aus der Gattung der Tannen\"", null, subtree, null, null, true, null, null, null, null);
782 searchResult = pager.getRecords().get(0);
783 Assert.assertTrue("Phrase search : Expecting at least one item in highlighted fragments", searchResult.getFieldHighlightMap().size() > 0);
784 fragments = searchResult.getFieldHighlightMap().values().iterator().next();
785 Assert.assertTrue("first fragments should contains serch term", fragments[0].contains("<B>Pflanzenart</B> <B>aus</B> <B>der</B> <B>Gattung</B> <B>der</B> <B>Tannen</B>"));
786
787 pager = taxonService.findByDescriptionElementFullText(TextData.class, "Gatt*", null, subtree, null, null, true, null, null, null, null);
788 searchResult = pager.getRecords().get(0);
789 Assert.assertTrue("Wildcard search : Expecting at least one item in highlighted fragments", searchResult.getFieldHighlightMap().size() > 0);
790 fragments = searchResult.getFieldHighlightMap().values().iterator().next();
791 Assert.assertTrue("first fragments should contains serch term", fragments[0].contains("<B>Gatt"));
792 }
793
794
795 @Test
796 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
797 public final void testFindByFullText() throws IOException, LuceneParseException {
798
799 refreshLuceneIndex();
800
801 classificationService.find(CLASSIFICATION_UUID);
802 TaxonNode subtree = null;
803
804 boolean NO_UNPUBLISHED = false;
805
806 Pager<SearchResult<TaxonBase>> pager = taxonService.findByFullText(null, "Abies", null, subtree, includeUnpublished, null, true, null, null, null, null); // --> 7
807 // logFreeTextSearchResults(pager, Level.DEBUG, null);
808 Assert.assertEquals("Expecting 8 entities", 8, pager.getCount().intValue());
809
810 //subtree
811 subtree = nodeService.find(ROOTNODE_CLASSIFICATION_5000);
812 pager = taxonService.findByFullText(null, "Abies", null, subtree, includeUnpublished, null, true, null, null, null, null); // --> 0
813 Assert.assertEquals("Expecting 2 entities", 2, pager.getCount().intValue());
814 subtree = null;
815
816 pager = taxonService.findByFullText(null, "Abies", null, subtree, NO_UNPUBLISHED, null, true, null, null, null, null); // --> 7
817 // logFreeTextSearchResults(pager, Level.DEBUG, null);
818 Assert.assertEquals("Expecting 6 entities", 6, pager.getCount().intValue());
819 Synonym abiesSubalpina = (Synonym)taxonService.find(ABIES_SUBALPINA_UUID);
820
821 //accepted published, syn not published
822 abiesSubalpina.getAcceptedTaxon().setPublish(true);
823 commitAndStartNewTransaction();
824 pager = taxonService.findByFullText(null, "Abies", null, subtree, NO_UNPUBLISHED, null, true, null, null, null, null); // --> 7
825 Assert.assertEquals("Expecting 7 entities", 7, pager.getCount().intValue());
826
827 //accepted published, syn published
828 abiesSubalpina = (Synonym)taxonService.find(abiesSubalpina.getUuid());
829 abiesSubalpina.setPublish(true);
830 commitAndStartNewTransaction();
831 pager = taxonService.findByFullText(null, "Abies", null, subtree, NO_UNPUBLISHED, null, true, null, null, null, null); // --> 7
832 Assert.assertEquals("Expecting 8 entities", 8, pager.getCount().intValue());
833
834 //accepted not published, syn published
835 abiesSubalpina = (Synonym)taxonService.find(abiesSubalpina.getUuid());
836 abiesSubalpina.getAcceptedTaxon().setPublish(false);
837 commitAndStartNewTransaction();
838 pager = taxonService.findByFullText(null, "Abies", null, subtree, NO_UNPUBLISHED, null, true, null, null, null, null); // --> 7
839 Assert.assertEquals("Expecting 6 entities. Synonym and accepted should not be found, though synonym is published",
840 6, pager.getCount().intValue());
841
842 pager = taxonService.findByFullText(Taxon.class, "Abies", null, subtree, includeUnpublished, null, true, null, null, null, null); // --> 6
843 Assert.assertEquals("Expecting 7 entities", 7, pager.getCount().intValue());
844
845 pager = taxonService.findByFullText(Synonym.class, "Abies", null, subtree, includeUnpublished, null, true, null, null, null, null); // --> 1
846 Assert.assertEquals("Expecting 1 entity", 1, pager.getCount().intValue());
847 pager = taxonService.findByFullText(Synonym.class, "Abies", null, subtree, NO_UNPUBLISHED, null, true, null, null, null, null); // --> 1
848 Assert.assertEquals("Expecting 0 entity", 0, pager.getCount().intValue());
849
850 pager = taxonService.findByFullText(TaxonBase.class, "sec", null, subtree, includeUnpublished, null, true, null, null, null, null); // --> 7
851 Assert.assertEquals("Expecting 8 entities", 9, pager.getCount().intValue());
852
853 pager = taxonService.findByFullText(null, "genus", null, subtree, includeUnpublished, null, true, null, null, null, null); // --> 1
854 Assert.assertEquals("Expecting 1 entity", 1, pager.getCount().intValue());
855
856 pager = taxonService.findByFullText(Taxon.class, "subalpina", null, subtree, includeUnpublished, null, true, null, null, null, null); // --> 0
857 Assert.assertEquals("Expecting 0 entities", 0, pager.getCount().intValue());
858
859
860 // synonym in classification ???
861 }
862
863 @Test
864 @DataSet
865 public final void testPrepareByAreaSearch() throws IOException, LuceneParseException {
866
867 List<PresenceAbsenceTerm> statusFilter = new ArrayList<>();
868 List<NamedArea> areaFilter = new ArrayList<>();
869 areaFilter.add(germany);
870 areaFilter.add(canada);
871 areaFilter.add(russia);
872
873 Pager<SearchResult<TaxonBase>> pager = taxonService.findByDistribution(areaFilter, statusFilter, null, null, 20, 0, null, null);
874 Assert.assertEquals("Expecting 2 entities", Integer.valueOf(2), Integer.valueOf(pager.getRecords().size()));
875
876 }
877
878 @Test
879 @DataSet
880 public final void testFindTaxaAndNamesByFullText_synonymClassificationSubtree() throws IOException, LuceneParseException, LuceneMultiSearchException {
881
882 refreshLuceneIndex();
883 Classification classification = null;
884 TaxonNode subtree = null;
885
886 //
887 Pager<SearchResult<TaxonBase>> pager;
888 EnumSet<TaxaAndNamesSearchMode> taxaAndSynonyms = EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished);
889 pager = taxonService.findTaxaAndNamesByFullText(
890 taxaAndSynonyms, "Abies", classification, subtree, null, null, null, true, null, null, null, null);
891 Assert.assertEquals("doTaxa & doSynonyms & unpublished", 8, pager.getCount().intValue());
892
893 EnumSet<TaxaAndNamesSearchMode> taxaOnly = EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.includeUnpublished);
894
895 //classification
896 classification = classificationService.find(CLASSIFICATION_UUID);
897 pager = taxonService.findTaxaAndNamesByFullText(
898 taxaAndSynonyms, "Abies", classification, subtree, null, null, null, true, null, null, null, null);
899 Assert.assertEquals("doTaxa & doSynonyms & unpublished", 2, pager.getCount().intValue());
900 //taxa only
901 pager = taxonService.findTaxaAndNamesByFullText(
902 taxaOnly, "Abies", classification, subtree, null, null, null, true, null, null, null, null);
903 Assert.assertEquals("doTaxa & unpublished", 1, pager.getCount().intValue());
904 //synonyms only
905 pager = taxonService.findTaxaAndNamesByFullText(
906 taxaOnly, "Abies", classification, subtree, null, null, null, true, null, null, null, null);
907 Assert.assertEquals("doSynonyms & unpublished", 1, pager.getCount().intValue());
908
909 classification = null;
910
911 //subtree
912 subtree = nodeService.find(ROOTNODE_CLASSIFICATION_5000);
913 pager = taxonService.findTaxaAndNamesByFullText(
914 taxaAndSynonyms, "Abies", classification, subtree, null, null, null, true, null, null, null, null);
915 Assert.assertEquals("doTaxa & doSynonyms & unpublished", 2, pager.getCount().intValue());
916 //taxa only
917 pager = taxonService.findTaxaAndNamesByFullText(
918 taxaOnly, "Abies", classification, subtree, null, null, null, true, null, null, null, null);
919 Assert.assertEquals("doTaxa & unpublished", 1, pager.getCount().intValue());
920 subtree = null;
921
922 }
923
924 @Test
925 @DataSet
926 public final void testFindTaxaAndNamesByFullText() throws IOException, LuceneParseException, LuceneMultiSearchException {
927
928 refreshLuceneIndex();
929 TaxonNode subtree = null;
930
931 Classification alternateClassification = classificationService.find(CLASSIFICATION_ALT_UUID);
932 Synonym abiesSubalpina = (Synonym)taxonService.find(ABIES_SUBALPINA_UUID);
933
934 Pager<SearchResult<TaxonBase>> pager;
935 EnumSet<TaxaAndNamesSearchMode> modes = EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished);
936 pager = taxonService.findTaxaAndNamesByFullText(
937 modes, "Abies", null, subtree, null, null, null, true, null, null, null, null);
938 Assert.assertEquals("doTaxa & doSynonyms & unpublished", 8, pager.getCount().intValue());
939 // logPagerRecords(pager, Level.DEBUG);
940
941 //unpublished
942 pager = taxonService.findTaxaAndNamesByFullText(TaxaAndNamesSearchMode.taxaAndSynonyms(),
943 "Abies", null, subtree, null, null, null, true, null, null, null, null);
944 Assert.assertEquals("doTaxa & doSynonyms, published only", 6, pager.getCount().intValue());
945
946 //accepted published, syn not published
947 abiesSubalpina.getAcceptedTaxon().setPublish(true);
948 commitAndStartNewTransaction();
949 pager = taxonService.findTaxaAndNamesByFullText(TaxaAndNamesSearchMode.taxaAndSynonyms(),
950 "Abies", null, subtree, null, null, null, true, null, null, null, null);
951 Assert.assertEquals("doTaxa & doSynonyms, accepted published", 7, pager.getCount().intValue());
952
953 //accepted published, syn published
954 abiesSubalpina = (Synonym)taxonService.find(abiesSubalpina.getUuid());
955 abiesSubalpina.setPublish(true);
956 commitAndStartNewTransaction();
957 pager = taxonService.findTaxaAndNamesByFullText(TaxaAndNamesSearchMode.taxaAndSynonyms(),
958 "Abies", null, subtree, null, null, null, true, null, null, null, null);
959 Assert.assertEquals("Expecting 8 entities", 8, pager.getCount().intValue());
960
961 //accepted not published, syn published
962 abiesSubalpina = (Synonym)taxonService.find(abiesSubalpina.getUuid());
963 abiesSubalpina.getAcceptedTaxon().setPublish(false);
964 commitAndStartNewTransaction();
965 pager = taxonService.findTaxaAndNamesByFullText(TaxaAndNamesSearchMode.taxaAndSynonyms(),
966 "Abies", null, subtree, null, null, null, true, null, null, null, null);
967 Assert.assertEquals("Expecting 6 entities. Synonym and accepted should not be found, though synonym is published",
968 6, pager.getCount().intValue());
969
970 EnumSet<TaxaAndNamesSearchMode> searchMode = EnumSet.allOf(TaxaAndNamesSearchMode.class);
971 pager = taxonService.findTaxaAndNamesByFullText(
972 searchMode, "Abies", null, subtree, null, null, null, true, null, null, null, null);
973 // logPagerRecords(pager, Level.DEBUG);
974 Assert.assertEquals("all search modes", 8, pager.getCount().intValue());
975 searchMode.remove(TaxaAndNamesSearchMode.includeUnpublished);
976 pager = taxonService.findTaxaAndNamesByFullText(
977 searchMode, "Abies", null, subtree, null, null, null, true, null, null, null, null);
978 Assert.assertEquals("all search modes except unpublished", 6, pager.getCount().intValue());
979
980 pager = taxonService.findTaxaAndNamesByFullText(EnumSet.allOf(TaxaAndNamesSearchMode.class),
981 "Abies", alternateClassification, subtree, null, null, null, true, null, null, null, null);
982 // logPagerRecords(pager, Level.DEBUG);
983 Assert.assertEquals("all search modes, filtered by alternateClassification", 1, pager.getCount().intValue());
984
985 pager = taxonService.findTaxaAndNamesByFullText(
986 EnumSet.of(TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
987 "Abies", null, subtree, null, null, null, true, null, null, null, null);
988 Assert.assertEquals("Expecting 2 entity", 2, pager.getCount().intValue());
989 Set<UUID> uuids = getTaxonUuidSet(pager);
990 Assert.assertTrue("The real synonym should be contained", uuids.contains(ABIES_SUBALPINA_UUID));
991 Assert.assertTrue("The pro parte synonym should be contained",uuids.contains(ABIES_LASIOCARPA_UUID));
992 //without published
993 pager = taxonService.findTaxaAndNamesByFullText(EnumSet.of(TaxaAndNamesSearchMode.doSynonyms),
994 "Abies", null, subtree, null, null, null, true, null, null, null, null);
995 Assert.assertEquals("Expecting 0 entities", 0, pager.getCount().intValue());
996
997
998 pager = taxonService.findTaxaAndNamesByFullText(
999 EnumSet.of(TaxaAndNamesSearchMode.doTaxaByCommonNames, TaxaAndNamesSearchMode.includeUnpublished),
1000 "Abies", null, subtree, null, null, null, true, null, null, null, null);
1001 Assert.assertEquals("Expecting 0 entity", 0, pager.getCount().intValue());
1002
1003 pager = taxonService.findTaxaAndNamesByFullText(
1004 EnumSet.of(TaxaAndNamesSearchMode.doTaxaByCommonNames, TaxaAndNamesSearchMode.includeUnpublished),
1005 "Tanne", null, subtree, null, null, null, true, null, null, null, null);
1006 Assert.assertEquals("Expecting 1 entity", 1, pager.getRecords().size());
1007 Assert.assertEquals("Expecting 1 entity", 1, pager.getCount().intValue());
1008 pager = taxonService.findTaxaAndNamesByFullText(
1009 EnumSet.of(TaxaAndNamesSearchMode.doTaxaByCommonNames),
1010 "Tanne", null, subtree, null, null, null, true, null, null, null, null);
1011 Assert.assertEquals("Expecting 0 entity", 0, pager.getRecords().size());
1012
1013 //misapplied names
1014 pager = taxonService.findTaxaAndNamesByFullText(
1015 EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames, TaxaAndNamesSearchMode.includeUnpublished),
1016 "kawakamii", (Classification)null, subtree, null, null, null, true, null, null, null, null);
1017 logFreeTextSearchResults(pager, Level.DEBUG, null);
1018 Assert.assertEquals("Expecting 1 entity", 1, pager.getCount().intValue());
1019 //unpublish accepted taxon
1020 pager = taxonService.findTaxaAndNamesByFullText(
1021 EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),
1022 "kawakamii", (Classification)null, subtree, null, null, null, true, null, null, null, null);
1023 Assert.assertEquals("Expecting 0 entities", 0, pager.getCount().intValue());
1024 //published accepted taxon/misapplied name
1025 Taxon abiesBalsamea = (Taxon)taxonService.find(ABIES_BALSAMEA_UUID);
1026 abiesBalsamea.setPublish(true);
1027 commitAndStartNewTransaction();
1028 pager = taxonService.findTaxaAndNamesByFullText(
1029 EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),
1030 "kawakamii", (Classification)null, subtree, null, null, null, true, null, null, null, null);
1031 Assert.assertEquals("Expecting 1 entities", 1, pager.getCount().intValue());
1032 //unpublished misapplied name
1033 Taxon misapplied = (Taxon)taxonService.find(DESC_ABIES_KAWAKAMII_SEC_KOMAROV_UUID);
1034 misapplied.setPublish(false);
1035 commitAndStartNewTransaction();
1036 pager = taxonService.findTaxaAndNamesByFullText(
1037 EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),
1038 "kawakamii", (Classification)null, subtree, null, null, null, true, null, null, null, null);
1039 Assert.assertEquals("Expecting 0 entities", 0, pager.getCount().intValue());
1040
1041 }
1042
1043 @Test
1044 @DataSet
1045 public final void testFindTaxaAndNamesByFullText_wildcard() throws IOException, LuceneParseException, LuceneMultiSearchException {
1046
1047 refreshLuceneIndex();
1048 TaxonNode subtree = null;
1049
1050 Pager<SearchResult<TaxonBase>> pager;
1051 pager = taxonService.findTaxaAndNamesByFullText(TaxaAndNamesSearchMode.taxaAndSynonyms(),
1052 "Abi*", null, subtree, null, null, null, true, null, null, null, null);
1053 // logFreeTextSearchResults(pager, Level.DEBUG, null);
1054 Assert.assertEquals("doTaxa & doSynonyms published only", 6, pager.getCount().intValue());
1055 pager = taxonService.findTaxaAndNamesByFullText(TaxaAndNamesSearchMode.taxaAndSynonyms(),
1056 "*bies", null, subtree, null, null, null, true, null, null, null, null);
1057 Assert.assertEquals("doTaxa & doSynonyms, published only", 6, pager.getCount().intValue());
1058 // logFreeTextSearchResults(pager, Level.ERROR, null);
1059 pager = taxonService.findTaxaAndNamesByFullText(TaxaAndNamesSearchMode.taxaAndSynonyms(),
1060 "?bies", null, subtree, null, null, null, true, null, null, null, null);
1061 Assert.assertEquals("doTaxa & doSynonyms, published only", 6, pager.getCount().intValue());
1062 // logFreeTextSearchResults(pager, Level.ERROR, null);
1063 pager = taxonService.findTaxaAndNamesByFullText(TaxaAndNamesSearchMode.taxaAndSynonyms(),
1064 "*", null, subtree, null, null, null, true, null, null, null, null);
1065 Assert.assertEquals("doTaxa & doSynonyms, published only", 7, pager.getCount().intValue());
1066 }
1067
1068 @Test
1069 @DataSet
1070 // @Ignore // FIXME: fails due org.apache.lucene.queryparser.classic.ParseException: Cannot parse 'relatedFrom.titleCache:()': Encountered " ")" ") "" at line 1, column 24.
1071 public final void testFindTaxaAndNamesByFullText_empty_querString() throws IOException, LuceneParseException, LuceneMultiSearchException {
1072
1073 refreshLuceneIndex();
1074 TaxonNode subtree = null;
1075
1076 Pager<SearchResult<TaxonBase>> pager;
1077 pager = taxonService.findTaxaAndNamesByFullText(EnumSet.of(TaxaAndNamesSearchMode.doTaxa),
1078 "", null, subtree, null, null, null, true, null, null, null, null);
1079 Assert.assertEquals("doTaxa, published only", 7, pager.getCount().intValue());
1080
1081 pager = taxonService.findTaxaAndNamesByFullText(TaxaAndNamesSearchMode.taxaAndSynonyms(),
1082 "", null, subtree, null, null, null, true, null, null, null, null);
1083 Assert.assertEquals("doTaxa & doSynonyms, published only", 7, pager.getCount().intValue());
1084
1085 pager = taxonService.findTaxaAndNamesByFullText(EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doMisappliedNames),
1086 null, null, subtree, null, null, null, true, null, null, null, null);
1087 Assert.assertEquals("doTaxa & doMisappliedNames published only", 7, pager.getCount().intValue());
1088
1089 pager = taxonService.findTaxaAndNamesByFullText(EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doMisappliedNames, TaxaAndNamesSearchMode.doTaxaByCommonNames),
1090 null, null, subtree, null, null, null, true, null, null, null, null);
1091 Assert.assertEquals("doTaxa & doMisappliedNames & doTaxaByCommonNames , published only", 7, pager.getCount().intValue());
1092 // logFreeTextSearchResults(pager, Level.ERROR, null);
1093 }
1094
1095 @Test
1096 @DataSet
1097 //test for https://dev.e-taxonomy.eu/redmine/issues/7486
1098 public final void testFindTaxaAndNamesByFullText_synonymsAndMisapplied_7486() throws IOException, LuceneParseException, LuceneMultiSearchException {
1099
1100 refreshLuceneIndex();
1101 TaxonNode subtree = null;
1102
1103 //misapplied names
1104 Pager<SearchResult<TaxonBase>> pager = taxonService.findTaxaAndNamesByFullText(
1105 EnumSet.of(TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.doMisappliedNames, TaxaAndNamesSearchMode.includeUnpublished),
1106 "Abies", (Classification)null, subtree, null, null, null, true, null, null, null, null);
1107 logFreeTextSearchResults(pager, Level.DEBUG, null);
1108 Assert.assertEquals("Expecting 3 entity", 3, pager.getCount().intValue());
1109 Set<UUID> uuids = getTaxonUuidSet(pager);
1110 Assert.assertTrue("The real synonym should be contained", uuids.contains(ABIES_SUBALPINA_UUID));
1111 Assert.assertTrue("The pro parte synonym should be contained",uuids.contains(ABIES_LASIOCARPA_UUID));
1112 Assert.assertTrue("The misapplied name should be contained",uuids.contains(DESC_ABIES_KAWAKAMII_SEC_KOMAROV_UUID));
1113 }
1114
1115 @Test
1116 @DataSet
1117 public final void testFindTaxaAndNamesByFullText_PhraseQuery() throws IOException, LuceneParseException, LuceneMultiSearchException {
1118
1119 refreshLuceneIndex();
1120 TaxonNode subtree = null;
1121
1122 Pager<SearchResult<TaxonBase>> pager = taxonService.findTaxaAndNamesByFullText(
1123 EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
1124 "\"Abies alba\"", null, subtree, null, null, null, true, null, null, null, null);
1125 // logPagerRecords(pager, Level.DEBUG);
1126 Assert.assertEquals("doTaxa & doSynonyms with simple phrase query", 1, pager.getCount().intValue());
1127
1128 pager = taxonService.findTaxaAndNamesByFullText(
1129 EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
1130 "\"Abies al*\"", null, subtree, null, null, null, true, null, null, null, null);
1131 // logPagerRecords(pager, Level.DEBUG);
1132 Assert.assertEquals("doTaxa & doSynonyms with complex phrase query", 1, pager.getCount().intValue());
1133
1134 pager = taxonService.findTaxaAndNamesByFullText(
1135 EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
1136 "\"Abies*\"", null, subtree, null, null, null, true, null, null, null, null);
1137 // logPagerRecords(pager, Level.DEBUG);
1138 Assert.assertEquals("doTaxa & doSynonyms with simple phrase query", 8, pager.getCount().intValue());
1139
1140 pager = taxonService.findTaxaAndNamesByFullText(
1141 EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
1142 "\"Abies*\"", null, subtree, null, null, null, true, null, null, null, null);
1143 // logPagerRecords(pager, Level.DEBUG);
1144 Assert.assertEquals("doTaxa & doSynonyms with simple phrase query", 8, pager.getCount().intValue());
1145
1146 }
1147
1148 @Test
1149 @DataSet
1150 public final void testFindTaxaAndNamesByFullText_Sort() throws IOException, LuceneParseException, LuceneMultiSearchException {
1151
1152 refreshLuceneIndex();
1153 TaxonNode subtree = null;
1154
1155 List<OrderHint> orderHints = new ArrayList<>();
1156
1157 // String[] docFields2log = new String[]{"id"};
1158
1159 // SortById
1160 orderHints.addAll(OrderHint.ORDER_BY_ID.asList());
1161 Pager<SearchResult<TaxonBase>> pager = taxonService.findTaxaAndNamesByFullText(
1162 EnumSet.of(TaxaAndNamesSearchMode.doTaxa),
1163 "Abies", null, subtree, null, null, null, true, null, null, orderHints, null);
1164 // logSearchResults(pager, Level.DEBUG, docFields2log);
1165 int lastId = -1;
1166 for(SearchResult<TaxonBase> rs : pager.getRecords()){
1167 if(lastId != -1){
1168 Assert.assertTrue("results not sorted by id", lastId < rs.getEntity().getId());
1169 }
1170 lastId = rs.getEntity().getId();
1171 }
1172
1173 orderHints.addAll(OrderHint.ORDER_BY_ID.asList());
1174 pager = taxonService.findTaxaAndNamesByFullText(
1175 EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
1176 "Abies", null, subtree, null, null, null, true, null, null, orderHints, null);
1177 // logSearchResults(pager, Level.DEBUG, docFields2log);
1178
1179 lastId = -1;
1180 for(SearchResult<TaxonBase> rs : pager.getRecords()){
1181 if(lastId != -1){
1182 Assert.assertTrue("results not sorted by id", lastId < rs.getEntity().getId());
1183 }
1184 lastId = rs.getEntity().getId();
1185 }
1186
1187 // Sortby NOMENCLATURAL_SORT_ORDER TODO make assertions !!!
1188 orderHints.clear();
1189 orderHints.addAll(OrderHint.NOMENCLATURAL_SORT_ORDER.asList());
1190 pager = taxonService.findTaxaAndNamesByFullText(
1191 EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
1192 "Abies", null, subtree, null, null, null, true, null, null, orderHints, null);
1193 logFreeTextSearchResults(pager, Level.DEBUG, null);
1194
1195 }
1196
1197 @Test
1198 @DataSet
1199 @Ignore //ignore until #7487 is fixed
1200 public final void testFindTaxaAndNamesByFullText_AreaFilter_7487() throws IOException, LuceneParseException, LuceneMultiSearchException {
1201 refreshLuceneIndex();
1202 TaxonNode subtree = null;
1203 Set<NamedArea> a_germany_canada_russia = new HashSet<>();
1204 a_germany_canada_russia.add(germany);
1205 a_germany_canada_russia.add(canada);
1206 a_germany_canada_russia.add(russia);
1207
1208 Set<PresenceAbsenceTerm> present_native = new HashSet<>();
1209 present_native.add(PresenceAbsenceTerm.PRESENT());
1210 present_native.add(PresenceAbsenceTerm.NATIVE());
1211
1212 Pager<SearchResult<TaxonBase>> pager = taxonService.findTaxaAndNamesByFullText(
1213 EnumSet.of(TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
1214 "Abies", null, subtree, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1215 Assert.assertEquals("Synonyms with matching area filter", 2, pager.getCount().intValue());
1216 Set<UUID> uuids = this.getTaxonUuidSet(pager);
1217 Assert.assertTrue("Synonym of balsamea should be in", uuids.contains(ABIES_SUBALPINA_UUID));
1218 Assert.assertTrue("Pro parte synonym of balsamea should be in", uuids.contains(ABIES_LASIOCARPA_UUID));
1219
1220 //pro parte syn => partial syn
1221 Taxon t_abies_balsamea = (Taxon)taxonService.find(ABIES_BALSAMEA_UUID);
1222 Set<TaxonRelationship> relsTo = t_abies_balsamea.getProParteAndPartialSynonymRelations();
1223 Assert.assertEquals(1, relsTo.size());
1224 TaxonRelationship taxonRelation = relsTo.iterator().next();
1225 taxonRelation.setType(TaxonRelationshipType.PARTIAL_SYNONYM_FOR());
1226 taxonService.saveOrUpdate(t_abies_balsamea);
1227 commitAndStartNewTransaction(null);
1228
1229 //should give same results as above
1230 pager = taxonService.findTaxaAndNamesByFullText(
1231 EnumSet.of(TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
1232 "Abies", null, subtree, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1233 // Assert.assertEquals("Synonyms with matching area filter", 2, pager.getCount().intValue());
1234 // uuids = this.getTaxonUuidSet(pager);
1235 // Assert.assertTrue("Synonym of balsamea should be in", uuids.contains(ABIES_SUBALPINA_UUID));
1236 // Assert.assertTrue("Partial synonym of balsamea should be in", uuids.contains(ABIES_LASIOCARPA_UUID));
1237
1238 ///MISAPPLIED
1239 pager = taxonService.findTaxaAndNamesByFullText(
1240 EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames, TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.includeUnpublished),
1241 "Abies", null, subtree, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1242 Assert.assertEquals("misappliedNames with matching area & status filter", 3, pager.getCount().intValue());
1243 uuids = this.getTaxonUuidSet(pager);
1244 Assert.assertTrue("Misapplied name should be in", uuids.contains(DESC_ABIES_KAWAKAMII_SEC_KOMAROV_UUID));
1245
1246 t_abies_balsamea = (Taxon)taxonService.find(ABIES_BALSAMEA_UUID);
1247 relsTo = t_abies_balsamea.getMisappliedNameRelations();
1248 Assert.assertEquals(1, relsTo.size());
1249 taxonRelation = relsTo.iterator().next();
1250 Assert.assertEquals(taxonRelation.getFromTaxon().getUuid(), DESC_ABIES_KAWAKAMII_SEC_KOMAROV_UUID);
1251 taxonRelation.setType(TaxonRelationshipType.PRO_PARTE_MISAPPLIED_NAME_FOR());
1252 taxonService.saveOrUpdate(t_abies_balsamea);
1253 commitAndStartNewTransaction(null);
1254
1255 //strange it works here before fixing #7487 already
1256 pager = taxonService.findTaxaAndNamesByFullText(
1257 EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames, TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.includeUnpublished),
1258 "Abies", null, subtree, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1259 Assert.assertEquals("misappliedNames with matching area & status filter", 3, pager.getCount().intValue());
1260 uuids = this.getTaxonUuidSet(pager);
1261 Assert.assertTrue("Pro parte misapplied name should be in", uuids.contains(DESC_ABIES_KAWAKAMII_SEC_KOMAROV_UUID));
1262
1263 }
1264
1265
1266 @Test
1267 @DataSet
1268 public final void testFindTaxaAndNamesByFullText_AreaFilter() throws IOException, LuceneParseException, LuceneMultiSearchException {
1269
1270 refreshLuceneIndex();
1271 TaxonNode subtree = null;
1272
1273 Set<NamedArea> a_germany_canada_russia = new HashSet<>();
1274 a_germany_canada_russia.add(germany);
1275 a_germany_canada_russia.add(canada);
1276 a_germany_canada_russia.add(russia);
1277
1278 Set<NamedArea> a_russia = new HashSet<>();
1279 a_russia.add(russia);
1280
1281 Set<PresenceAbsenceTerm> present = new HashSet<>();
1282 present.add(PresenceAbsenceTerm.PRESENT());
1283
1284 Set<PresenceAbsenceTerm> present_native = new HashSet<>();
1285 present_native.add(PresenceAbsenceTerm.PRESENT());
1286 present_native.add(PresenceAbsenceTerm.NATIVE());
1287
1288 Set<PresenceAbsenceTerm> absent = new HashSet<>();
1289 absent.add(PresenceAbsenceTerm.ABSENT());
1290
1291 Pager<SearchResult<TaxonBase>> pager = taxonService.findTaxaAndNamesByFullText(
1292 EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.includeUnpublished),
1293 "Abies", null, subtree, a_germany_canada_russia, null, null, true, null, null, null, null);
1294 logFreeTextSearchResults(pager, Level.DEBUG, null);
1295 Assert.assertEquals("Synonyms with matching area filter", 2, pager.getCount().intValue());
1296 Set<UUID> uuids = this.getTaxonUuidSet(pager);
1297 Assert.assertTrue("Abies alba (accepted with distribution) should be in", uuids.contains(ABIES_ALBA_UUID));
1298 Assert.assertTrue("Abies balsamea (accepted with distribution) should be in", uuids.contains(ABIES_BALSAMEA_UUID));
1299
1300 pager = taxonService.findTaxaAndNamesByFullText(
1301 EnumSet.of(TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
1302 "Abies", null, subtree, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1303 Assert.assertEquals("Synonyms with matching area filter", 2, pager.getCount().intValue());
1304 uuids = this.getTaxonUuidSet(pager);
1305 Assert.assertTrue("Synonym of balsamea should be in", uuids.contains(ABIES_SUBALPINA_UUID));
1306 Assert.assertTrue("Pro parte synonym of balsamea should be in", uuids.contains(ABIES_LASIOCARPA_UUID));
1307
1308 pager = taxonService.findTaxaAndNamesByFullText(
1309 EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
1310 "Abies", null, subtree, a_germany_canada_russia, null, null, true, null, null, null, null);
1311 logFreeTextSearchResults(pager, Level.DEBUG, null);
1312 Assert.assertEquals("taxa and synonyms with matching area filter", 4, pager.getCount().intValue());
1313 uuids = this.getTaxonUuidSet(pager);
1314 Assert.assertTrue("Accepted taxon with area should be in", uuids.contains(ABIES_ALBA_UUID));
1315 Assert.assertTrue("Accepted taxon with area should be in", uuids.contains(ABIES_BALSAMEA_UUID));
1316 Assert.assertTrue("Synonym of balsamea should be in", uuids.contains(ABIES_SUBALPINA_UUID));
1317 Assert.assertTrue("Pro parte synonym of balsamea should be in", uuids.contains(ABIES_LASIOCARPA_UUID));
1318 Assert.assertFalse("Misapplied name should NOT be in", uuids.contains(DESC_ABIES_KAWAKAMII_SEC_KOMAROV_UUID));
1319
1320 pager = taxonService.findTaxaAndNamesByFullText(
1321 EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
1322 "Abies", null, subtree, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1323 Assert.assertEquals("taxa and synonyms with matching area & status filter 4", 4, pager.getCount().intValue());
1324 uuids = this.getTaxonUuidSet(pager);
1325 Assert.assertTrue("Synonym of balsamea should be in", uuids.contains(ABIES_SUBALPINA_UUID));
1326 Assert.assertTrue("Accepted taxon with area should be in", uuids.contains(ABIES_ALBA_UUID));
1327 Assert.assertTrue("Synonym of balsamea should be in", uuids.contains(ABIES_SUBALPINA_UUID));
1328 Assert.assertTrue("Pro parte synonym of balsamea should be in", uuids.contains(ABIES_LASIOCARPA_UUID));
1329
1330 pager = taxonService.findTaxaAndNamesByFullText(
1331 EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
1332 "Abies", null, subtree, a_germany_canada_russia, present, null, true, null, null, null, null);
1333 Assert.assertEquals("taxa and synonyms with matching area & status filter 3", 3, pager.getCount().intValue());
1334 uuids = this.getTaxonUuidSet(pager);
1335 Assert.assertTrue("Abies balsamea (accepted taxon) should be in", uuids.contains(ABIES_BALSAMEA_UUID));
1336 Assert.assertTrue("Synonym of balsamea should be in", uuids.contains(ABIES_SUBALPINA_UUID));
1337 Assert.assertTrue("Pro parte synonym of balsamea should be in", uuids.contains(ABIES_LASIOCARPA_UUID));
1338
1339 pager = taxonService.findTaxaAndNamesByFullText(
1340 EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms, TaxaAndNamesSearchMode.includeUnpublished),
1341 "Abies", null, subtree, a_russia, present, null, true, null, null, null, null);
1342 Assert.assertEquals("taxa and synonyms with non matching area & status filter", 0, pager.getCount().intValue());
1343
1344 pager = taxonService.findTaxaAndNamesByFullText(
1345 EnumSet.of(TaxaAndNamesSearchMode.doTaxaByCommonNames, TaxaAndNamesSearchMode.includeUnpublished),
1346 "Tanne", null, subtree, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1347 Assert.assertEquals("ByCommonNames with area filter", 1, pager.getCount().intValue());
1348 uuids = this.getTaxonUuidSet(pager);
1349 Assert.assertTrue("Abies balsamea should be in", uuids.contains(ABIES_BALSAMEA_UUID));
1350
1351 // abies_kawakamii_sensu_komarov as misapplied name for t_abies_balsamea
1352 pager = taxonService.findTaxaAndNamesByFullText(
1353 EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames, TaxaAndNamesSearchMode.includeUnpublished),
1354 "Abies", null, subtree, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1355 Assert.assertEquals("misappliedNames with matching area & status filter", 1, pager.getCount().intValue());
1356 uuids = this.getTaxonUuidSet(pager);
1357 Assert.assertTrue("Misapplied name should be in", uuids.contains(DESC_ABIES_KAWAKAMII_SEC_KOMAROV_UUID));
1358
1359
1360 // 1. remove existing taxon relation
1361 Taxon t_abies_balsamea = (Taxon)taxonService.find(ABIES_BALSAMEA_UUID);
1362 Set<TaxonRelationship> relsTo = t_abies_balsamea.getMisappliedNameRelations();
1363 Assert.assertEquals(1, relsTo.size());
1364 TaxonRelationship taxonRelation = relsTo.iterator().next();
1365 t_abies_balsamea.removeTaxonRelation(taxonRelation);
1366 taxonService.saveOrUpdate(t_abies_balsamea);
1367 commitAndStartNewTransaction(null);
1368
1369 pager = taxonService.findTaxaAndNamesByFullText(
1370 EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames, TaxaAndNamesSearchMode.includeUnpublished),
1371 "Abies", null, subtree, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1372 Assert.assertEquals("misappliedNames with matching area & status filter, should match nothing now", 0, pager.getCount().intValue());
1373
1374 // 2. now add abies_kawakamii_sensu_komarov as misapplied name for t_abies_alba and search for misapplications in Russia: ABSENT
1375 Taxon t_abies_kawakamii_sensu_komarov = (Taxon)taxonService.find(DESC_ABIES_KAWAKAMII_SEC_KOMAROV_UUID);
1376 Taxon t_abies_alba = (Taxon)taxonService.find(ABIES_ALBA_UUID);
1377 t_abies_alba.addMisappliedName(t_abies_kawakamii_sensu_komarov, null, null);
1378 taxonService.update(t_abies_kawakamii_sensu_komarov);
1379 commitAndStartNewTransaction(null);
1380
1381 pager = taxonService.findTaxaAndNamesByFullText(
1382 EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames, TaxaAndNamesSearchMode.includeUnpublished),
1383 "Abies", null, subtree, a_germany_canada_russia, absent, null, true, null, null, null, null);
1384 Assert.assertEquals("misappliedNames with matching area & status filter, should find one", 1, pager.getCount().intValue());
1385 uuids = this.getTaxonUuidSet(pager);
1386 Assert.assertTrue("Misapplied name should be in", uuids.contains(DESC_ABIES_KAWAKAMII_SEC_KOMAROV_UUID));
1387
1388 }
1389
1390 @Test
1391 @DataSet
1392 //https://dev.e-taxonomy.eu/redmine/issues/5477
1393 public final void testFindTaxaAndNamesByFullText_AreaFilter_issue5477() throws IOException, LuceneParseException, LuceneMultiSearchException {
1394
1395 TaxonNode subtree = null;
1396 Set<NamedArea> a_germany_canada_russia = new HashSet<>();
1397 a_germany_canada_russia.add(germany);
1398 a_germany_canada_russia.add(canada);
1399 a_germany_canada_russia.add(russia);
1400
1401
1402 Set<PresenceAbsenceTerm> absent = new HashSet<>();
1403 absent.add(PresenceAbsenceTerm.ABSENT());
1404
1405 Taxon t_abies_kawakamii_sensu_komarov = (Taxon)taxonService.find(DESC_ABIES_KAWAKAMII_SEC_KOMAROV_UUID);
1406 Taxon t_abies_alba = (Taxon)taxonService.find(ABIES_ALBA_UUID);
1407 t_abies_alba.addMisappliedName(t_abies_kawakamii_sensu_komarov, null, null);
1408
1409 /* Since the upgrade from hibernate search 4 to 5.5
1410 * triggering an update of t_abies_alba is no longer sufficient to also update the
1411 * document of t_abies_kawakamii_sensu_komarov in the lucene index.
1412 * the last test in testFindTaxaAndNamesByFullText_AreaFilter() failed in this case.
1413 * This situation is reproduced here:
1414 */
1415 taxonService.update(t_abies_alba);
1416
1417 commitAndStartNewTransaction(null);
1418
1419 Pager<SearchResult<TaxonBase>> pager = taxonService.findTaxaAndNamesByFullText(
1420 EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),
1421 "Abies", null, subtree, a_germany_canada_russia, absent, null, true, null, null, null, null);
1422 Assert.assertEquals("misappliedNames with matching area & status filter, should find one", 1, pager.getCount().intValue());
1423 }
1424
1425
1426 /**
1427 * Regression test for #3119: fulltext search: Entity always null whatever search
1428 *
1429 * @throws IOException
1430 * @throws LuceneParseException
1431 * @throws LuceneMultiSearchException
1432 */
1433 @Test
1434 @DataSet
1435 public final void testFindByEverythingFullText() throws IOException, LuceneParseException, LuceneMultiSearchException {
1436
1437 refreshLuceneIndex();
1438 TaxonNode subtree = null;
1439 EnumSet<TaxaAndNamesSearchMode> mode = TaxaAndNamesSearchMode.taxaAndSynonymsWithUnpublished();
1440 // via Taxon
1441 Pager<SearchResult<TaxonBase>>pager = taxonService.findByEverythingFullText("Abies", null, subtree, includeUnpublished, null, true, null, null, null, null);
1442 // Pager<SearchResult<TaxonBase>> pager = taxonService.findTaxaAndNamesByFullText(mode,
1443 // "Abies", null, null, null, null, true, null, null, null, null);
1444 logFreeTextSearchResults(pager, Level.DEBUG, null);
1445 Assert.assertTrue("Expecting at least 7 entities for 'Abies'", pager.getCount() > 7);
1446 Assert.assertNotNull("Expecting entity", pager.getRecords().get(0).getEntity());
1447 // Assert.assertEquals("Expecting Taxon entity", Taxon.class, pager.getRecords().get(0).getEntity().getClass());
1448
1449 // via DescriptionElement
1450 pager = taxonService.findByEverythingFullText("present", null, subtree, includeUnpublished, null, true, null, null, null, null);
1451 //this is not covered by findTaxaAndNamesByFullText
1452 // pager = taxonService.findTaxaAndNamesByFullText(mode,
1453 // "present", null, null, null, null, true, null, null, null, null);
1454 Assert.assertEquals("Expecting one entity when searching for area 'present'", 1, pager.getCount().intValue());
1455 Assert.assertNotNull("Expecting entity", pager.getRecords().get(0).getEntity());
1456 Assert.assertEquals("Expecting Taxon entity", Taxon.class, CdmBase.deproxy(pager.getRecords().get(0).getEntity()).getClass());
1457 Assert.assertEquals("Expecting Taxon ", ABIES_BALSAMEA_UUID, pager.getRecords().get(0).getEntity().getUuid());
1458
1459 }
1460
1461
1462 @Test
1463 @DataSet
1464 public final void findByEveryThingFullText() throws IOException, LuceneParseException, LuceneMultiSearchException {
1465
1466 refreshLuceneIndex();
1467 TaxonNode subtree = null;
1468
1469 Classification classification = null;
1470 EnumSet<TaxaAndNamesSearchMode> mode = TaxaAndNamesSearchMode.taxaAndSynonymsWithUnpublished();
1471
1472 Pager<SearchResult<TaxonBase>> pager = taxonService.findByEverythingFullText("genus", null, subtree, includeUnpublished, null, false, null, null, null, null); // --> 1
1473 // Pager<SearchResult<TaxonBase>> pager = taxonService.findTaxaAndNamesByFullText(mode,
1474 // "genus", classification, null, null, null, false, null, null, null, null);
1475 Assert.assertEquals("Expecting 1 entity", 1, pager.getCount().intValue());
1476
1477 //FIXME FAILS: abies balamea is returned twice, see also testFullText_Grouping()
1478 pager = taxonService.findByEverythingFullText("Balsam", null, subtree, includeUnpublished, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
1479 logFreeTextSearchResults(pager, Level.DEBUG, null);
1480 // pager = taxonService.findTaxaAndNamesByFullText(EnumSet.allOf(TaxaAndNamesSearchMode.class),
1481 // "Balsam", classification, null, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
1482 Assert.assertEquals("expecting to find the Abies balsamea via the GERMAN DescriptionElements", 1, pager.getCount().intValue());
1483
1484 //TODO fieldHighlight does not yet work
1485 pager = taxonService.findByEverythingFullText("Abies", null, subtree, includeUnpublished, null, true, null, null, null, null);
1486 // pager = taxonService.findTaxaAndNamesByFullText(mode,
1487 // "Abies", classification, null, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
1488 Assert.assertEquals("Expecting 8 entities", 8, pager.getCount().intValue());
1489 SearchResult<TaxonBase> searchResult = pager.getRecords().get(0);
1490 Assert.assertTrue("the map of highlighted fragments should contain at least one item", searchResult.getFieldHighlightMap().size() > 0);
1491 String[] fragments = searchResult.getFieldHighlightMap().values().iterator().next();
1492 Assert.assertTrue("first fragments should contains serch term", fragments[0].toLowerCase().contains("<b>abies</b>"));
1493 }
1494
1495 // @SuppressWarnings("rawtypes")
1496 // @Test
1497 // @DataSet
1498 // public final void benchmarkFindTaxaAndNamesHql() throws IOException, LuceneParseException {
1499 //
1500 // createRandomTaxonWithCommonName(NUM_OF_NEW_RADOM_ENTITIES);
1501 //
1502 // IFindTaxaAndNamesConfigurator configurator = new FindTaxaAndNamesConfiguratorImpl();
1503 // configurator.setTitleSearchString("Wei"+UTF8.SHARP_S+"%");
1504 // configurator.setMatchMode(MatchMode.BEGINNING);
1505 // configurator.setDoTaxa(false);
1506 // configurator.setDoSynonyms(false);
1507 // configurator.setDoNamesWithoutTaxa(false);
1508 // configurator.setDoTaxaByCommonNames(true);
1509 //
1510 // Pager<IdentifiableEntity> pager;
1511 //
1512 // long startMillis = System.currentTimeMillis();
1513 // for (int indx = 0; indx < BENCHMARK_ROUNDS; indx++) {
1514 // pager = taxonService.findTaxaAndNames(configurator);
1515 // if (logger.isDebugEnabled()) {
1516 // logger.debug("[" + indx + "]" + pager.getRecords().get(0).getTitleCache());
1517 // }
1518 // }
1519 // double duration = ((double) (System.currentTimeMillis() - startMillis)) / BENCHMARK_ROUNDS;
1520 // logger.info("Benchmark result - [find taxon by CommonName via HQL] : " + duration + "ms (" + BENCHMARK_ROUNDS + " benchmark rounds )");
1521 // }
1522
1523 @SuppressWarnings("rawtypes")
1524 @Test
1525 @DataSet
1526 public final void benchmarkFindByCommonNameHql() {
1527
1528 // printDataSet(System.err, new String[] { "TaxonBase" });
1529
1530 createRandomTaxonWithCommonName(NUM_OF_NEW_RADOM_ENTITIES);
1531
1532 IFindTaxaAndNamesConfigurator configurator = FindTaxaAndNamesConfiguratorImpl.NewInstance();
1533 configurator.setTitleSearchString("Wei"+UTF8.SHARP_S+"%");
1534 configurator.setMatchMode(MatchMode.BEGINNING);
1535 configurator.setDoTaxa(false);
1536 configurator.setDoSynonyms(false);
1537 configurator.setDoNamesWithoutTaxa(false);
1538 configurator.setDoTaxaByCommonNames(true);
1539
1540 Pager<IdentifiableEntity> pager;
1541
1542 long startMillis = System.currentTimeMillis();
1543 for (int indx = 0; indx < BENCHMARK_ROUNDS; indx++) {
1544 pager = taxonService.findTaxaAndNames(configurator);
1545 if (logger.isDebugEnabled()) {
1546 logger.debug("[" + indx + "]" + pager.getRecords().get(0).getTitleCache());
1547 }
1548 }
1549 double duration = ((double) (System.currentTimeMillis() - startMillis)) / BENCHMARK_ROUNDS;
1550 logger.info("Benchmark result - [find taxon by CommonName via HQL] : " + duration + "ms (" + BENCHMARK_ROUNDS + " benchmark rounds )");
1551 }
1552
1553 @SuppressWarnings("rawtypes")
1554 @Test
1555 @DataSet
1556 public final void benchmarkFindByCommonNameLucene() throws IOException, LuceneParseException {
1557 TaxonNode subtree = null;
1558 createRandomTaxonWithCommonName(NUM_OF_NEW_RADOM_ENTITIES);
1559
1560 refreshLuceneIndex();
1561
1562 Pager<SearchResult<TaxonBase>> pager;
1563
1564 long startMillis = System.currentTimeMillis();
1565 for (int indx = 0; indx < BENCHMARK_ROUNDS; indx++) {
1566 pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"*", null, subtree, null, null, false, null, null, null, null);
1567 if (logger.isDebugEnabled()) {
1568 logger.debug("[" + indx + "]" + pager.getRecords().get(0).getEntity().getTitleCache());
1569 }
1570 }
1571 double duration = ((double) (System.currentTimeMillis() - startMillis)) / BENCHMARK_ROUNDS;
1572 logger.info("Benchmark result - [find taxon by CommonName via lucene] : " + duration + "ms (" + BENCHMARK_ROUNDS + " benchmark rounds )");
1573 }
1574
1575 /**
1576 * uncomment @Test annotation to create the dataset for this test
1577 */
1578 @Override
1579 // @Test
1580 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="ClearDBDataSet.xml")
1581 public final void createTestDataSet() throws FileNotFoundException {
1582
1583 Classification europeanAbiesClassification = Classification.NewInstance("European Abies");
1584 europeanAbiesClassification.setUuid(CLASSIFICATION_UUID);
1585 classificationService.save(europeanAbiesClassification);
1586
1587 Classification alternativeClassification = Classification.NewInstance("Abies alternative");
1588 alternativeClassification.setUuid(CLASSIFICATION_ALT_UUID);
1589 classificationService.save(alternativeClassification);
1590
1591 Reference sec = ReferenceFactory.newBook();
1592 sec.setTitleCache("Kohlbecker, A., Testcase standart views, 2013", true);
1593 Reference sec_sensu = ReferenceFactory.newBook();
1594 sec_sensu.setTitleCache("Komarov, V. L., Flora SSSR 29", true);
1595 referenceService.save(sec);
1596 referenceService.save(sec_sensu);
1597
1598 IBotanicalName n_abies = TaxonNameFactory.NewBotanicalInstance(Rank.GENUS());
1599 n_abies.setNameCache("Abies", true);
1600 Taxon t_abies = Taxon.NewInstance(n_abies, sec);
1601 taxonService.save(t_abies);
1602
1603 IBotanicalName n_abies_alba = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1604 n_abies_alba.setNameCache("Abies alba", true);
1605 Taxon t_abies_alba = Taxon.NewInstance(n_abies_alba, sec);
1606 t_abies_alba.setUuid(ABIES_ALBA_UUID);
1607 taxonService.save(t_abies_alba);
1608
1609 IBotanicalName n_abies_subalpina = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1610 n_abies_subalpina.setNameCache("Abies subalpina", true);
1611 Synonym s_abies_subalpina = Synonym.NewInstance(n_abies_subalpina, sec);
1612 taxonService.save(s_abies_subalpina);
1613
1614 IBotanicalName n_abies_balsamea = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1615 n_abies_balsamea.setNameCache("Abies balsamea", true);
1616 Taxon t_abies_balsamea = Taxon.NewInstance(n_abies_balsamea, sec);
1617 t_abies_balsamea.setUuid(ABIES_BALSAMEA_UUID);
1618 t_abies_balsamea.addSynonym(s_abies_subalpina, SynonymType.SYNONYM_OF());
1619 taxonService.save(t_abies_balsamea);
1620
1621 IBotanicalName n_abies_grandis = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1622 n_abies_grandis.setNameCache("Abies grandis", true);
1623 Taxon t_abies_grandis = Taxon.NewInstance(n_abies_grandis, sec);
1624 taxonService.save(t_abies_grandis);
1625
1626 IBotanicalName n_abies_kawakamii = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1627 n_abies_kawakamii.setNameCache("Abies kawakamii", true);
1628 Taxon t_abies_kawakamii = Taxon.NewInstance(n_abies_kawakamii, sec);
1629 t_abies_kawakamii.getTitleCache();
1630 taxonService.save(t_abies_kawakamii);
1631
1632 // abies_kawakamii_sensu_komarov as missapplied name for t_abies_balsamea
1633 Taxon t_abies_kawakamii_sensu_komarov = Taxon.NewInstance(n_abies_kawakamii, sec_sensu);
1634 taxonService.save(t_abies_kawakamii_sensu_komarov);
1635 t_abies_kawakamii_sensu_komarov.addTaxonRelation(t_abies_balsamea, TaxonRelationshipType.MISAPPLIED_NAME_FOR(), null, null);
1636 taxonService.saveOrUpdate(t_abies_kawakamii_sensu_komarov);
1637
1638 IBotanicalName n_abies_lasiocarpa = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1639 n_abies_lasiocarpa.setNameCache("Abies lasiocarpa", true);
1640 Taxon t_abies_lasiocarpa = Taxon.NewInstance(n_abies_lasiocarpa, sec);
1641 taxonService.save(t_abies_lasiocarpa);
1642
1643 // add taxa to classifications
1644 europeanAbiesClassification.addChildTaxon(t_abies_balsamea, null, null);
1645 alternativeClassification.addChildTaxon(t_abies_lasiocarpa, null, null);
1646 classificationService.saveOrUpdate(europeanAbiesClassification);
1647 classificationService.saveOrUpdate(alternativeClassification);
1648
1649 //
1650 // Description
1651 //
1652 TaxonDescription d_abies_alba = TaxonDescription.NewInstance(t_abies_alba);
1653 TaxonDescription d_abies_balsamea = TaxonDescription.NewInstance(t_abies_balsamea);
1654
1655 d_abies_alba.setUuid(DESC_ABIES_ALBA_UUID);
1656 d_abies_balsamea.setUuid(DESC_ABIES_BALSAMEA_UUID);
1657
1658
1659 // CommonTaxonName
1660 d_abies_alba.addElement(CommonTaxonName.NewInstance("Wei"+UTF8.SHARP_S+"tanne", Language.GERMAN()));
1661 d_abies_alba.addElement(CommonTaxonName.NewInstance("silver fir", Language.ENGLISH()));
1662 d_abies_alba.addElement(Distribution
1663 .NewInstance(
1664 germany,
1665 PresenceAbsenceTerm.NATIVE()));
1666 d_abies_alba.addElement(Distribution
1667 .NewInstance(
1668 russia,
1669 PresenceAbsenceTerm.ABSENT()));
1670
1671 // TextData
1672 d_abies_balsamea
1673 .addElement(TextData
1674 .NewInstance(
1675 "Die Balsam-Tanne (Abies balsamea) ist eine Pflanzenart aus der Gattung der Tannen (Abies). Sie wächst im nordöstlichen Nordamerika, wo sie sowohl Tief- als auch Bergland besiedelt. Sie gilt als relativ anspruchslos gegenüber dem Standort und ist frosthart. In vielen Teilen des natürlichen Verbreitungsgebietes stellt sie die Klimaxbaumart dar.",
1676 Language.GERMAN(), null));
1677 d_abies_balsamea
1678 .addElement(CommonTaxonName
1679 .NewInstance(
1680 "Balsam-Tanne",
1681 Language.GERMAN(), null));
1682
1683 d_abies_balsamea
1684 .addElement(Distribution
1685 .NewInstance(
1686 canada,
1687 PresenceAbsenceTerm.PRESENT()));
1688
1689 d_abies_balsamea
1690 .addElement(Distribution
1691 .NewInstance(
1692 germany,
1693 PresenceAbsenceTerm.NATIVE()));
1694
1695 d_abies_balsamea
1696 .addElement(TextData
1697 .NewInstance(
1698 TaxonServiceSearchTestUtf8Constants.RUSSIAN_ABIES_ALBA_LONG,
1699 Language.RUSSIAN(), null));
1700 d_abies_balsamea
1701 .addElement(CommonTaxonName
1702 .NewInstance(
1703 TaxonServiceSearchTestUtf8Constants.RUSSIAN_ABIES_ALBA_SHORT,
1704 Language.RUSSIAN(), null));
1705 descriptionService.saveOrUpdate(d_abies_balsamea);
1706
1707 setComplete();
1708 endTransaction();
1709
1710
1711 writeDbUnitDataSetFile(new String[] {
1712 "TAXONBASE", "TAXONNAME",
1713 "TAXONRELATIONSHIP",
1714 "REFERENCE", "DESCRIPTIONELEMENTBASE", "DESCRIPTIONBASE",
1715 "AGENTBASE", "HOMOTYPICALGROUP",
1716 "CLASSIFICATION", "TAXONNODE",
1717 "LANGUAGESTRING", "DESCRIPTIONELEMENTBASE_LANGUAGESTRING",
1718 "HIBERNATE_SEQUENCES" // IMPORTANT!!!
1719 });
1720
1721 }
1722
1723 /**
1724 *
1725 */
1726 private void refreshLuceneIndex() {
1727
1728 // commitAndStartNewTransaction(null);
1729 commit();
1730 endTransaction();
1731 indexer.purge(DefaultProgressMonitor.NewInstance());
1732 indexer.reindex(typesToIndex, DefaultProgressMonitor.NewInstance());
1733 startNewTransaction();
1734 // commitAndStartNewTransaction(null);
1735 }
1736
1737 /**
1738 * @param numberOfNew
1739 *
1740 */
1741 private void createRandomTaxonWithCommonName(int numberOfNew) {
1742
1743 logger.debug(String.format("creating %1$s random taxan with CommonName", numberOfNew));
1744
1745 commitAndStartNewTransaction(null);
1746
1747 Reference sec = ReferenceFactory.newBook();
1748 referenceService.save(sec);
1749
1750 for (int i = numberOfNew; i < numberOfNew; i++) {
1751 RandomStringUtils.randomAlphabetic(10);
1752 String radomName = RandomStringUtils.randomAlphabetic(5) + " " + RandomStringUtils.randomAlphabetic(10);
1753 String radomCommonName = RandomStringUtils.randomAlphabetic(10);
1754
1755 IBotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1756 name.setNameCache(radomName, true);
1757 Taxon taxon = Taxon.NewInstance(name, sec);
1758 taxonService.save(taxon);
1759
1760 TaxonDescription description = TaxonDescription.NewInstance(taxon);
1761 description.addElement(CommonTaxonName.NewInstance(radomCommonName, Language.GERMAN()));
1762 descriptionService.save(description);
1763 }
1764
1765 commitAndStartNewTransaction(null);
1766 }
1767
1768 private <T extends CdmBase> void logFreeTextSearchResults(Pager<SearchResult<T>> pager, Level level, String[] docFields){
1769 if(level == null){
1770 level = Level.DEBUG;
1771 }
1772 if(logger.isEnabledFor(level)){
1773 StringBuilder b = new StringBuilder();
1774 b.append("\n");
1775 int i = 0;
1776 for(SearchResult<?> sr : pager.getRecords()){
1777
1778 b.append(" ").append(i++).append(" - ");
1779 b.append("score:").append(sr.getScore()).append(", ");
1780
1781 if(docFields != null){
1782 b.append("docs : ");
1783 for(Document doc : sr.getDocs()) {
1784 b.append("<");
1785 for(String f : docFields){
1786 b.append(f).append(":").append(Arrays.toString(doc.getValues(f)));
1787 }
1788 b.append(">");
1789 }
1790 }
1791
1792 CdmBase entity = sr.getEntity();
1793 if(entity == null){
1794 b.append("NULL");
1795 } else {
1796 b.append(entity.getClass().getSimpleName()).
1797 append(" [").append(entity.getId()).
1798 append(" | ").append(entity.getUuid()).append("] : ").
1799 append(entity.toString());
1800
1801 }
1802 b.append("\n");
1803 }
1804 logger.log(level, b);
1805 }
1806 }
1807
1808
1809 /**
1810 * @param pager
1811 * @return
1812 */
1813 private Set<UUID> getTaxonUuidSet(@SuppressWarnings("rawtypes") Pager<SearchResult<TaxonBase>> pager) {
1814 Set<UUID> result = new HashSet<>();
1815 for (@SuppressWarnings("rawtypes") SearchResult<TaxonBase> searchResult : pager.getRecords()){
1816 result.add(searchResult.getEntity().getUuid());
1817 }
1818 return result;
1819 }
1820
1821 }