Project

General

Profile

Download (75 KB) Statistics
| Branch: | Tag: | Revision:
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.DefinedTermBase;
48
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
49
import eu.etaxonomy.cdm.model.common.Language;
50
import eu.etaxonomy.cdm.model.description.CategoricalData;
51
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
52
import eu.etaxonomy.cdm.model.description.DescriptionBase;
53
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
54
import eu.etaxonomy.cdm.model.description.Distribution;
55
import eu.etaxonomy.cdm.model.description.Feature;
56
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
57
import eu.etaxonomy.cdm.model.description.State;
58
import eu.etaxonomy.cdm.model.description.StateData;
59
import eu.etaxonomy.cdm.model.description.TaxonDescription;
60
import eu.etaxonomy.cdm.model.description.TextData;
61
import eu.etaxonomy.cdm.model.location.Country;
62
import eu.etaxonomy.cdm.model.location.NamedArea;
63
import eu.etaxonomy.cdm.model.name.IBotanicalName;
64
import eu.etaxonomy.cdm.model.name.Rank;
65
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
66
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
67
import eu.etaxonomy.cdm.model.reference.Reference;
68
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
69
import eu.etaxonomy.cdm.model.taxon.Classification;
70
import eu.etaxonomy.cdm.model.taxon.Synonym;
71
import eu.etaxonomy.cdm.model.taxon.SynonymType;
72
import eu.etaxonomy.cdm.model.taxon.Taxon;
73
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
74
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
75
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
76
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
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
 * @created 04.02.2009
85
 */
86
public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
87

    
88
    private static final String ABIES_BALSAMEA_UUID = "f65d47bd-4f49-4ab1-bc4a-bc4551eaa1a8";
89

    
90
    private static final String ABIES_ALBA_UUID = "7dbd5810-a3e5-44b6-b563-25152b8867f4";
91

    
92
    private static final String CLASSIFICATION_UUID = "2a5ceebb-4830-4524-b330-78461bf8cb6b";
93

    
94
    private static final String CLASSIFICATION_ALT_UUID = "d7c741e3-ae9e-4a7d-a566-9e3a7a0b51ce";
95

    
96
    private static final String D_ABIES_BALSAMEA_UUID = "900108d8-e6ce-495e-b32e-7aad3099135e";
97

    
98
    private static final String D_ABIES_ALBA_UUID = "ec8bba03-d993-4c85-8472-18b14942464b";
99

    
100
    private static final String D_ABIES_KAWAKAMII_SEC_KOMAROV_UUID = "e9d8c2fd-6409-46d5-9c2e-14a2bbb1b2b1";
101

    
102
    private static final int NUM_OF_NEW_RADOM_ENTITIES = 1000;
103

    
104
    private static Logger logger = Logger.getLogger(TaxonServiceSearchTest.class);
105

    
106

    
107

    
108
    @SpringBeanByType
109
    private ITaxonService taxonService;
110
    @SpringBeanByType
111
    private ITermService termService;
112
    @SpringBeanByType
113
    private IClassificationService classificationService;
114
    @SpringBeanByType
115
    private IReferenceService referenceService;
116
    @SpringBeanByType
117
    private IDescriptionService descriptionService;
118
    @SpringBeanByType
119
    private INameService nameService;
120
    @SpringBeanByType
121
    private ICdmMassIndexer indexer;
122

    
123
    @SpringBeanByType
124
    private ITaxonNodeService nodeService;
125

    
126
    private static final int BENCHMARK_ROUNDS = 300;
127

    
128
    private Set<Class<? extends CdmBase>> typesToIndex = null;
129

    
130
    private NamedArea germany;
131
    private NamedArea france ;
132
    private NamedArea russia ;
133
    private NamedArea canada ;
134

    
135
    /**
136
     * @throws java.lang.Exception
137
     */
138
    @Before
139
    public void setUp() throws Exception {
140
        typesToIndex = new HashSet<Class<? extends CdmBase>>();
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

    
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

    
167
        Pager<SearchResult<TaxonBase>> pager;
168

    
169
        pager = taxonService.findByFullText(null, "Abies", null, 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, 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, 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
        refreshLuceneIndex();
193

    
194
        Pager<SearchResult<TaxonBase>> pager;
195

    
196
        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"tanne", null, 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, 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, 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, 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

    
224
        Pager<SearchResult<TaxonBase>> pager;
225
        // by Area
226
        pager = taxonService.findByDescriptionElementFullText(null, "Canada", null, 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, 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

    
240
        Pager<SearchResult<TaxonBase>> pager;
241

    
242
        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"*", null, null, null, false, null, null, null, null);
243
        Assert.assertEquals("Expecting one entity when searching for CommonTaxonName", 1, pager.getCount().intValue());
244
    }
245

    
246
    /**
247
     * Regression test for #3113 (hibernate search: wildcard query can cause BooleanQuery$TooManyClauses: maxClauseCount is set to 1024)
248
     *
249
     * @throws IOException
250
     * @throws LuceneParseException
251
     */
252
    @SuppressWarnings("rawtypes")
253
    @Test
254
    @DataSet
255
    public final void testFindByDescriptionElementFullText_TooManyClauses() throws IOException, LuceneParseException {
256

    
257
        // generate 1024 terms to reproduce the bug
258
        TaxonDescription description = (TaxonDescription) descriptionService.find(UUID.fromString(D_ABIES_ALBA_UUID));
259
        Set<String> uniqueRandomStrs = new HashSet<String>(1024);
260
        while(uniqueRandomStrs.size() < 1024){
261
            uniqueRandomStrs.add(RandomStringUtils.random(10, true, false));
262
        }
263
        for(String rndStr: uniqueRandomStrs){
264
            description.addElement(CommonTaxonName.NewInstance("Rot" + rndStr, Language.DEFAULT()));
265
        }
266
        descriptionService.saveOrUpdate(description);
267
        commitAndStartNewTransaction(null);
268

    
269
        refreshLuceneIndex();
270

    
271
        Pager<SearchResult<TaxonBase>> pager;
272

    
273
        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Rot*", null, null, null, false, null, null, null, null);
274
        Assert.assertEquals("Expecting all 1024 entities grouped into one SearchResult item when searching for Rot*", 1, pager.getCount().intValue());
275
    }
276

    
277
    /**
278
     * Regression test for #3116 (fulltext search: always only one page of results)
279
     *
280
     * @throws IOException
281
     * @throws LuceneParseException
282
     */
283
    @SuppressWarnings("rawtypes")
284
    @Test
285
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
286
    @Ignore
287
    public final void testFullText_Paging() throws IOException, LuceneParseException {
288

    
289
        Reference sec = ReferenceFactory.newDatabase();
290
        referenceService.save(sec);
291

    
292
        Set<String> uniqueRandomStrs = new HashSet<String>(1024);
293
        int numOfItems = 100;
294
        while(uniqueRandomStrs.size() < numOfItems){
295
            uniqueRandomStrs.add(RandomStringUtils.random(5, true, false));
296
        }
297

    
298
        for(String rndStr: uniqueRandomStrs){
299

    
300
            Taxon taxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.SERIES()), sec);
301
            taxon.setTitleCache("Tax" + rndStr, true);
302
            taxonService.save(taxon);
303

    
304
            TaxonDescription description = TaxonDescription.NewInstance(taxon);
305
            description.addElement(CommonTaxonName.NewInstance("Rot" + rndStr, Language.DEFAULT()));
306
            descriptionService.saveOrUpdate(description);
307
        }
308

    
309
        commitAndStartNewTransaction(new String[]{"TAXONBASE"});
310
        refreshLuceneIndex();
311

    
312
        int pageSize = 10;
313

    
314
        Pager<SearchResult<TaxonBase>> pager;
315

    
316
        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Rot*", null, null, null, false, pageSize, null, null, null);
317
        Assert.assertEquals("unexpeted number of pages", Integer.valueOf(numOfItems / pageSize), pager.getPagesAvailable());
318
        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Rot*", null, null, null, false, pageSize, 9, null, null);
319
        Assert.assertNotNull("last page must have records", pager.getRecords());
320
        Assert.assertNotNull("last item on last page must exist", pager.getRecords().get(0));
321
        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Rot*", null, null, null, false, pageSize, 10, null, null);
322
        Assert.assertNotNull("last page + 1 must not have any records", pager.getRecords());
323
    }
324

    
325
    /**
326
     * test for max score and sort by score of hit groups
327
     * with all matches per taxon in a single TextData  element
328
     * see {@link #testFullText_ScoreAndOrder_2()} for the complement
329
     * test with matches in multiple TextData per taxon
330
     *
331
     * @throws IOException
332
     * @throws LuceneParseException
333
     */
334
    @SuppressWarnings("rawtypes")
335
    @Test
336
    @DataSet
337
    @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
338
    public final void testFullText_ScoreAndOrder_1() throws IOException, LuceneParseException {
339

    
340
        int numOfTaxa = 3;
341

    
342
        UUID[] taxonUuids = new UUID[numOfTaxa];
343
        StringBuilder text = new StringBuilder();
344

    
345
        for(int i = 0; i < numOfTaxa; i++){
346

    
347
            Taxon taxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(null), null);
348
            taxon.setTitleCache("Taxon_" + i, true);
349
            taxonUuids[i] = taxon.getUuid();
350
            taxonService.save(taxon);
351

    
352
            text.append(" ").append("Rot");
353
            TaxonDescription description = TaxonDescription.NewInstance(taxon);
354
            description.addElement(TextData.NewInstance(text.toString(), Language.DEFAULT(), null));
355
            descriptionService.saveOrUpdate(description);
356
        }
357

    
358
        commitAndStartNewTransaction(null);
359
        refreshLuceneIndex();
360

    
361
        Pager<SearchResult<TaxonBase>> pager;
362

    
363
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Rot", null, null, null, false, null, null, null, null);
364
        for(int i = 0; i < numOfTaxa; i++){
365
            Assert.assertEquals("taxa should be orderd by relevance (= score)", taxonUuids[numOfTaxa - i - 1], pager.getRecords().get(i).getEntity().getUuid());
366
        }
367
        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);
368
    }
369

    
370
    /**
371
     * test for max score and sort by score of hit groups
372
     * with all matches per taxon in a multiple TextData elements
373
     * see {@link #testFullText_ScoreAndOrder_1()} for the complement
374
     * test with matches in a single TextData per taxon
375
     *
376
     * @throws IOException
377
     * @throws LuceneParseException
378
     */
379
    @SuppressWarnings("rawtypes")
380
    @Test
381
    @DataSet
382
    @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
383
    public final void testFullText_ScoreAndOrder_2() throws IOException, LuceneParseException {
384

    
385
        int numOfTaxa = 3;
386

    
387
        UUID[] taxonUuids = new UUID[numOfTaxa];
388

    
389
        for(int i = 0; i < numOfTaxa; i++){
390

    
391
            Taxon taxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(null), null);
392
            taxon.setTitleCache("Taxon_" + i, true);
393
            taxonUuids[i] = taxon.getUuid();
394
            taxonService.save(taxon);
395

    
396
            TaxonDescription description = TaxonDescription.NewInstance(taxon);
397
            for(int k = 0; k < i; k++){
398
                description.addElement(TextData.NewInstance("Rot", Language.DEFAULT(), null));
399
            }
400
            descriptionService.saveOrUpdate(description);
401
        }
402

    
403
        commitAndStartNewTransaction(null);
404
        refreshLuceneIndex();
405

    
406
        Pager<SearchResult<TaxonBase>> pager;
407

    
408
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Rot", null, null, null, false, null, null, null, null);
409
        for(int i = 0; i < numOfTaxa; i++){
410
            Assert.assertEquals("taxa should be orderd by relevance (= score)", taxonUuids[numOfTaxa - i - 1], pager.getRecords().get(i).getEntity().getUuid());
411
        }
412
        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);
413
    }
414

    
415

    
416
    /**
417
     * @throws IOException
418
     * @throws LuceneParseException
419
     * @throws LuceneMultiSearchException
420
     */
421
    @Test
422
    @DataSet
423
    public final void testFullText_Grouping() throws IOException, LuceneParseException, LuceneMultiSearchException {
424

    
425
        TaxonDescription description = (TaxonDescription) descriptionService.find(UUID.fromString(D_ABIES_ALBA_UUID));
426
        Set<String> uniqueRandomStrs = new HashSet<String>(1024);
427
        int numOfItems = 100;
428
        while(uniqueRandomStrs.size() < numOfItems){
429
            uniqueRandomStrs.add(RandomStringUtils.random(5, true, false));
430
        }
431
        for(String rndStr: uniqueRandomStrs){
432
            description.addElement(CommonTaxonName.NewInstance("Rot" + rndStr, Language.DEFAULT()));
433
        }
434
        descriptionService.saveOrUpdate(description);
435

    
436
        commitAndStartNewTransaction(new String[]{"DESCRIPTIONELEMENTBASE"});
437

    
438
        refreshLuceneIndex();
439

    
440
        int pageSize = 10;
441

    
442
        Pager<SearchResult<TaxonBase>> pager;
443
        boolean highlightFragments = true;
444

    
445
        // test with findByDescriptionElementFullText
446
        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Rot*", null, null, null, highlightFragments, pageSize, null, null, null);
447
        logFreeTextSearchResults(pager, Level.DEBUG, null);
448
        Assert.assertEquals("All matches should be grouped into a single SearchResult element", 1, pager.getRecords().size());
449
        Assert.assertEquals("The count property of the pager must be set correctly", 1, pager.getCount().intValue());
450
        Map<String, String[]> highlightMap = pager.getRecords().get(0).getFieldHighlightMap();
451
        // maxDocsPerGroup is defined in LuceneSearch and defaults to 10
452
        int maxDocsPerGroup = 10;
453
        Assert.assertEquals("expecting 10 highlighted fragments of field 'name'", maxDocsPerGroup, highlightMap.get("name").length);
454

    
455
        // test with findByEverythingFullText
456
        pager = taxonService.findByEverythingFullText( "Rot*", null, null, highlightFragments, pageSize, null, null, null);
457
        logFreeTextSearchResults(pager, Level.DEBUG, null);
458
        Assert.assertEquals("All matches should be grouped into a single SearchResult element", 1, pager.getRecords().size());
459
        Assert.assertEquals("The count property of the pager must be set correctly", 1, pager.getCount().intValue());
460
        highlightMap = pager.getRecords().get(0).getFieldHighlightMap();
461
        // maxDocsPerGroup is defined in LuceneSearch and defaults to 10
462
        maxDocsPerGroup = 10;
463
        Assert.assertEquals("expecting 10 highlighted fragments of field 'name'", maxDocsPerGroup, highlightMap.get("name").length);
464

    
465
    }
466

    
467
    @SuppressWarnings("rawtypes")
468
    @Test
469
    @DataSet
470
    @Ignore
471
    public final void testFindByDescriptionElementFullText_TextData() throws IOException, LuceneParseException {
472

    
473
        refreshLuceneIndex();
474

    
475
        Pager<SearchResult<TaxonBase>> pager;
476
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Abies", null, null, null, false, null, null, null, null);
477
        logFreeTextSearchResults(pager, Level.DEBUG, null);
478
        Assert.assertEquals("Expecting one entity when searching for any TextData", 1, pager.getCount().intValue());
479
        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());
480
        Assert.assertTrue("Expecting two docs, one for RUSSIAN and one for GERMAN", pager.getRecords().get(0).getDocs().size() == 2);
481
        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getDocs().iterator().next().get("inDescription.taxon.titleCache"));
482

    
483

    
484
        pager = taxonService.findByDescriptionElementFullText(null, "Abies", null, null, null, false, null, null, null, null);
485
        Assert.assertEquals("Expecting one entity when searching for any type", 1, pager.getCount().intValue());
486

    
487
        pager = taxonService.findByDescriptionElementFullText(null, "Abies", null, Arrays.asList(new Feature[]{Feature.UNKNOWN()}), null, false, null, null, null, null);
488
        Assert.assertEquals("Expecting one entity when searching for any type and for Feature DESCRIPTION", 1, pager.getCount().intValue());
489

    
490
        pager = taxonService.findByDescriptionElementFullText(null, "Abies", null, Arrays.asList(new Feature[]{Feature.CHROMOSOME_NUMBER()}), null, false, null, null, null, null);
491
        Assert.assertEquals("Expecting no entity when searching for any type and for Feature CHROMOSOME_NUMBER", 0, pager.getCount().intValue());
492

    
493
        pager = taxonService.findByDescriptionElementFullText(null, "Abies", null, Arrays.asList(new Feature[]{Feature.CHROMOSOME_NUMBER(), Feature.UNKNOWN()}), null, false, null, null, null, null);
494
        Assert.assertEquals("Expecting no entity when searching for any type and for Feature DESCRIPTION or CHROMOSOME_NUMBER", 1, pager.getCount().intValue());
495

    
496
        pager = taxonService.findByDescriptionElementFullText(Distribution.class, "Abies", null, null, null, false, null, null, null, null);
497
        Assert.assertEquals("Expecting no entity when searching for Distribution", 0, pager.getCount().intValue());
498

    
499
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Бальзам", null, null, Arrays.asList(new Language[]{}), false, null, null, null, null);
500
        Assert.assertEquals("Expecting one entity", 1, pager.getCount().intValue());
501
        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());
502

    
503
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Бальзам", null, null, Arrays.asList(new Language[]{Language.RUSSIAN()}), false, null, null, null, null);
504
        Assert.assertEquals("Expecting one entity", 1, pager.getCount().intValue());
505
        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());
506

    
507
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Бальзам", null, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
508
        Assert.assertEquals("Expecting no entity", 0, pager.getCount().intValue());
509

    
510
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, null, Arrays.asList(new Language[]{Language.GERMAN(), Language.RUSSIAN()}), false, null, null, null, null);
511
        Assert.assertEquals("Expecting one entity", 1, pager.getCount().intValue());
512
        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());
513
    }
514

    
515
    @SuppressWarnings("rawtypes")
516
    @Test
517
    @DataSet
518
    public final void testFindByDescriptionElementFullText_MultipleWords() throws IOException, LuceneParseException {
519

    
520
        refreshLuceneIndex();
521

    
522
        // Pflanzenart aus der Gattung der Tannen
523
        long start = System.currentTimeMillis();
524

    
525
        Pager<SearchResult<TaxonBase>> pager;
526
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Pflanzenart Tannen", null, null, null, false, null, null, null, null);
527
        Assert.assertEquals("OR search : Expecting one entity", 1, pager.getCount().intValue());
528

    
529
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Pflanzenart Wespen", null, null, null, false, null, null, null, null);
530
        Assert.assertEquals("OR search : Expecting one entity", 1, pager.getCount().intValue());
531

    
532
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "+Pflanzenart +Tannen", null, null, null, false, null, null, null, null);
533
        Assert.assertEquals("AND search : Expecting one entity", 1, pager.getCount().intValue());
534

    
535
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "+Pflanzenart +Wespen", null, null, null, false, null, null, null, null);
536
        Assert.assertEquals("AND search : Expecting no entity", 0, pager.getCount().intValue());
537

    
538
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "\"Pflanzenart aus der Gattung der Tannen\"", null, null, null, false, null, null, null, null);
539
        Assert.assertEquals("Phrase search : Expecting one entity", 1, pager.getCount().intValue());
540

    
541
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "\"Pflanzenart aus der Gattung der Wespen\"", null, null, null, false, null, null, null, null);
542
        Assert.assertEquals("Phrase search : Expecting one entity", 0, pager.getCount().intValue());
543

    
544
        logger.info("testFindByDescriptionElementFullText_MultipleWords() duration: " + (System.currentTimeMillis() - start) + "ms");
545

    
546
    }
547

    
548

    
549
    @SuppressWarnings("rawtypes")
550
    @Test
551
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
552
    public final void testFindByDescriptionElementFullText_modify_DescriptionElement() throws IOException, LuceneParseException {
553

    
554
        refreshLuceneIndex();
555

    
556
        Pager<SearchResult<TaxonBase>> pager;
557
        //
558
        // modify the DescriptionElement
559
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, null, Arrays.asList(new Language[]{Language.GERMAN(), Language.RUSSIAN()}), false, null, null, null, null);
560
        Assert.assertTrue("Search did not return any results", pager.getRecords().size() > 0);
561
        Assert.assertTrue("Expecting only one doc", pager.getRecords().get(0).getDocs().size() == 1);
562
        Document indexDocument = pager.getRecords().get(0).getDocs().iterator().next();
563
        String[] descriptionElementUuidStr = indexDocument.getValues("uuid");
564
        String[] inDescriptionUuidStr = indexDocument.getValues("inDescription.uuid");
565
        // is only one uuid!
566
        DescriptionElementBase textData = descriptionService.getDescriptionElementByUuid(UUID.fromString(descriptionElementUuidStr[0]));
567

    
568
        ((TextData)textData).removeText(Language.GERMAN());
569
        ((TextData)textData).putText(Language.SPANISH_CASTILIAN(), "abeto bals"+UTF8.SMALL_A_ACUTE+"mico");
570

    
571
        descriptionService.saveDescriptionElement(textData);
572
        commitAndStartNewTransaction(null);
573
//        printDataSet(System.out, new String[] {
574
//                "DESCRIPTIONELEMENTBASE", "LANGUAGESTRING", "DESCRIPTIONELEMENTBASE_LANGUAGESTRING" }
575
//        );
576

    
577
        //
578
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, null, Arrays.asList(new Language[]{Language.GERMAN(), Language.RUSSIAN()}), false, null, null, null, null);
579
        Assert.assertEquals("The german 'Balsam-Tanne' TextData should no longer be indexed", 0, pager.getCount().intValue());
580
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "abeto", null, null, Arrays.asList(new Language[]{Language.SPANISH_CASTILIAN()}), false, null, null, null, null);
581
        Assert.assertEquals("expecting to find the SPANISH_CASTILIAN 'abeto bals"+UTF8.SMALL_A_ACUTE+"mico'", 1, pager.getCount().intValue());
582
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "bals"+UTF8.SMALL_A_ACUTE+"mico", null, null, null, false, null, null, null, null);
583
        Assert.assertEquals("expecting to find the SPANISH_CASTILIAN 'abeto bals"+UTF8.SMALL_A_ACUTE+"mico'", 1, pager.getCount().intValue());
584

    
585
        //
586
        // modify the DescriptionElement via the Description object
587
        DescriptionBase<?> description = descriptionService.find(UUID.fromString(inDescriptionUuidStr[0]));
588
        Set<DescriptionElementBase> elements = description.getElements();
589
        for( DescriptionElementBase elm : elements){
590
            if(elm.getUuid().toString().equals(descriptionElementUuidStr[0])){
591
                ((TextData)elm).removeText(Language.SPANISH_CASTILIAN());
592
                ((TextData)elm).putText(Language.POLISH(), "Jod"+UTF8.POLISH_L+"a balsamiczna");
593
            }
594
        }
595
        descriptionService.saveOrUpdate(description);
596
        commitAndStartNewTransaction(null);
597
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "abeto", null, null, Arrays.asList(new Language[]{Language.SPANISH_CASTILIAN()}), false, null, null, null, null);
598
        Assert.assertEquals("The spanish 'abeto bals"+UTF8.SMALL_A_ACUTE+"mico' TextData should no longer be indexed", 0, pager.getCount().intValue());
599
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "balsamiczna", null, null, Arrays.asList(new Language[]{Language.POLISH()}), false, null, null, null, null);
600
        Assert.assertEquals("expecting to find the POLISH 'Jod"+UTF8.POLISH_L+"a balsamiczna'", 1, pager.getCount().intValue());
601
    }
602

    
603
    @SuppressWarnings("rawtypes")
604
    @Test
605
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
606
    public final void testFindByDescriptionElementFullText_modify_Taxon() throws IOException, LuceneParseException {
607

    
608
        refreshLuceneIndex();
609

    
610
        Pager<SearchResult<TaxonBase>> pager;
611
        Taxon t_abies_balsamea = (Taxon)taxonService.find(UUID.fromString(ABIES_BALSAMEA_UUID));
612
        TaxonDescription d_abies_balsamea = (TaxonDescription)descriptionService.find(UUID.fromString(D_ABIES_BALSAMEA_UUID));
613

    
614
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
615
        Assert.assertEquals("expecting to find the GERMAN 'Balsam-Tanne'", 1, pager.getCount().intValue());
616

    
617
        // exchange the Taxon with another one via the Taxon object
618
        // 1.) remove existing description:
619
        t_abies_balsamea.removeDescription(d_abies_balsamea);
620

    
621
        taxonService.saveOrUpdate(t_abies_balsamea);
622
        commitAndStartNewTransaction(null);
623

    
624
        t_abies_balsamea = (Taxon)taxonService.find(t_abies_balsamea.getUuid());
625

    
626
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
627
        Assert.assertEquals("'Balsam-Tanne' should no longer be found", 0, pager.getCount().intValue());
628

    
629
        // 2.) create new description and add to taxon:
630
        TaxonDescription d_abies_balsamea_new = TaxonDescription.NewInstance();
631
        d_abies_balsamea_new
632
                .addElement(TextData
633
                        .NewInstance(
634
                                "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",
635
                                Language.GERMAN(), null));
636
        t_abies_balsamea.addDescription(d_abies_balsamea_new);
637
        // set authorshipCache to null to avoid validation exception,
638
        // this is maybe not needed in future,  see ticket #3344
639
        IBotanicalName abies_balsamea = CdmBase.deproxy(t_abies_balsamea.getName(), TaxonNameBase.class);
640
        abies_balsamea.setAuthorshipCache(null);
641
        printDataSet(System.err, new String[] {"LANGUAGESTRING_AUD"});
642
        taxonService.saveOrUpdate(t_abies_balsamea);
643
        commitAndStartNewTransaction(null);
644

    
645
//        printDataSet(System.out, new String[] {
646
//                "DESCRIPTIONBASE"
647
//        });
648

    
649
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "mittelgro"+UTF8.SHARP_S+"er Baum", null, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
650
        Assert.assertEquals("the taxon should be found via the new Description", 1, pager.getCount().intValue());
651
    }
652

    
653
    @SuppressWarnings("rawtypes")
654
    @Test
655
    @DataSet
656
    public final void testFindByDescriptionElementFullText_modify_Classification() throws IOException, LuceneParseException {
657

    
658
        refreshLuceneIndex();
659

    
660
        Pager<SearchResult<TaxonBase>> pager;
661

    
662
        // put taxon into other classification, new taxon node
663
        Classification classification = classificationService.find(UUID.fromString(CLASSIFICATION_UUID));
664
        Classification alternateClassification = classificationService.find(UUID.fromString(CLASSIFICATION_ALT_UUID));
665

    
666
        // TODO: why is the test failing when the childNode is already retrieved here, and not after the following four lines?
667
        //TaxonNode childNode = classification.getChildNodes().iterator().next();
668

    
669
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
670
        Assert.assertEquals("expecting to find the GERMAN 'Balsam-Tanne' even if filtering by classification", 1, pager.getCount().intValue());
671
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", alternateClassification, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
672
        Assert.assertEquals("GERMAN 'Balsam-Tanne' should NOT be found in other classification", 0, pager.getCount().intValue());
673

    
674
        // check for the right taxon node
675
        TaxonNode childNode = classification.getChildNodes().iterator().next();
676
        Assert.assertEquals("expecting Abies balsamea sec.", childNode.getTaxon().getUuid().toString(), ABIES_BALSAMEA_UUID);
677
        Assert.assertEquals("expecting default classification", childNode.getClassification().getUuid().toString(), CLASSIFICATION_UUID);
678

    
679
        // moving the taxon around, the rootnode is only a proxy
680
        alternateClassification.setRootNode(HibernateProxyHelper.deproxy(alternateClassification.getRootNode(), TaxonNode.class));
681
        alternateClassification.addChildNode(childNode, null, null);
682

    
683
        classificationService.saveOrUpdate(alternateClassification);
684
        commitAndStartNewTransaction(null);
685

    
686
//        printDataSet(System.out, new String[] {
687
//            "TAXONBASE", "TAXONNODE", "CLASSIFICATION"
688
//        });
689

    
690
        // reload classification
691
        classification = classificationService.find(UUID.fromString(CLASSIFICATION_UUID));
692
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", alternateClassification, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
693
        Assert.assertEquals("GERMAN 'Balsam-Tanne' should now be found in other classification", 1, pager.getCount().intValue());
694

    
695
        classification.getChildNodes().clear();
696
        classificationService.saveOrUpdate(classification);
697
        commitAndStartNewTransaction(null);
698

    
699
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", classification, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
700
        Assert.assertEquals("Now the GERMAN 'Balsam-Tanne' should NOT be found in original classification", 0, pager.getCount().intValue());
701

    
702
    }
703

    
704
    @SuppressWarnings("rawtypes")
705
    @Test
706
    @DataSet
707
    public final void testFindByDescriptionElementFullText_CategoricalData() throws IOException, LuceneParseException {
708

    
709
        // add CategoricalData
710
        DescriptionBase d_abies_balsamea = descriptionService.find(UUID.fromString(D_ABIES_BALSAMEA_UUID));
711
        // Categorical data
712
        CategoricalData cdata = CategoricalData.NewInstance();
713
        cdata.setFeature(Feature.DESCRIPTION());
714
        State state = State.NewInstance("green", "green", "gn");
715

    
716
        StateData statedata = StateData.NewInstance(state);
717
        statedata.putModifyingText(Language.ENGLISH(), "always, even during winter");
718
        cdata.addStateData(statedata);
719
        d_abies_balsamea.addElement(cdata);
720

    
721
        UUID termUUID = termService.save(state).getUuid();
722
        descriptionService.save(d_abies_balsamea);
723

    
724
        commitAndStartNewTransaction(null);
725

    
726
//        printDataSet(System.out, new String[] {
727
//                 "STATEDATA", "STATEDATA_DEFINEDTERMBASE", "STATEDATA_LANGUAGESTRING", "LANGUAGESTRING"});
728

    
729
        refreshLuceneIndex();
730

    
731
        Pager<SearchResult<TaxonBase>> pager;
732
        pager = taxonService.findByDescriptionElementFullText(CategoricalData.class, "green", null, null, null, false, null, null, null, null);
733
        Assert.assertEquals("Expecting one entity", 1, pager.getCount().intValue());
734
        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());
735
        Assert.assertTrue("Expecting only one doc", pager.getRecords().get(0).getDocs().size() == 1);
736
        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getDocs().iterator().next().get("inDescription.taxon.titleCache"));
737

    
738

    
739
        //TODO modify the StateData
740
        TaxonBase taxon = pager.getRecords().get(0).getEntity();
741

    
742
        String newName = "Quercus robur";
743
        taxon.setTitleCache(newName + " sec. ", true);
744

    
745
        taxonService.saveOrUpdate(taxon);
746
        commitAndStartNewTransaction(null);
747

    
748
        taxon = taxonService.find(taxon.getUuid());
749
        Assert.assertEquals(newName + " sec. ", taxon.getTitleCache());
750
        DefinedTermBase term = termService.find(termUUID);
751

    
752
        termService.delete(term);
753

    
754
    }
755

    
756
    @SuppressWarnings("rawtypes")
757
    @Test
758
    @DataSet
759
    public final void testFindByDescriptionElementFullText_Highlighting() throws IOException, LuceneParseException {
760

    
761
        refreshLuceneIndex();
762

    
763
        Pager<SearchResult<TaxonBase>> pager;
764
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Abies", null, null, null, true, null, null, null, null);
765
        Assert.assertEquals("Expecting one entity when searching for any TextData", 1, pager.getCount().intValue());
766
        SearchResult<TaxonBase> searchResult = pager.getRecords().get(0);
767
        Assert.assertTrue("the map of highlighted fragments should contain at least one item", searchResult.getFieldHighlightMap().size() > 0);
768
        String[] fragments = searchResult.getFieldHighlightMap().values().iterator().next();
769
        Assert.assertTrue("first fragments should contains serch term", fragments[0].contains("<B>Abies</B>"));
770

    
771
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Pflanzenart Tannen", null, null, null, true, null, null, null, null);
772
        searchResult = pager.getRecords().get(0);
773
        Assert.assertTrue("Phrase search : Expecting at least one item in highlighted fragments", searchResult.getFieldHighlightMap().size() > 0);
774
        fragments = searchResult.getFieldHighlightMap().values().iterator().next();
775
        Assert.assertTrue("first fragments should contains serch term", fragments[0].contains("<B>Pflanzenart</B>") || fragments[0].contains("<B>Tannen</B>"));
776

    
777
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "+Pflanzenart +Tannen", null, null, null, true, null, null, null, null);
778
        searchResult = pager.getRecords().get(0);
779
        Assert.assertTrue("Phrase search : Expecting at least one item in highlighted fragments", searchResult.getFieldHighlightMap().size() > 0);
780
        fragments = searchResult.getFieldHighlightMap().values().iterator().next();
781
        Assert.assertTrue("first fragments should contains serch term", fragments[0].contains("<B>Pflanzenart</B>") && fragments[0].contains("<B>Tannen</B>"));
782

    
783
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "\"Pflanzenart aus der Gattung der Tannen\"", null, null, null, true, null, null, null, null);
784
        searchResult = pager.getRecords().get(0);
785
        Assert.assertTrue("Phrase search : Expecting at least one item in highlighted fragments", searchResult.getFieldHighlightMap().size() > 0);
786
        fragments = searchResult.getFieldHighlightMap().values().iterator().next();
787
        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>"));
788

    
789
        pager = taxonService.findByDescriptionElementFullText(TextData.class, "Gatt*", null, null, null, true, null, null, null, null);
790
        searchResult = pager.getRecords().get(0);
791
        Assert.assertTrue("Wildcard search : Expecting at least one item in highlighted fragments", searchResult.getFieldHighlightMap().size() > 0);
792
        fragments = searchResult.getFieldHighlightMap().values().iterator().next();
793
        Assert.assertTrue("first fragments should contains serch term", fragments[0].contains("<B>Gatt"));
794
    }
795

    
796

    
797
    @Test
798
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
799
    public final void testFindByFullText() throws IOException, LuceneParseException {
800

    
801
        refreshLuceneIndex();
802

    
803
        Classification europeanAbiesClassification = classificationService.find(UUID.fromString(CLASSIFICATION_UUID));
804

    
805
        Pager<SearchResult<TaxonBase>> pager;
806

    
807
        pager = taxonService.findByFullText(null, "Abies", null, null, true, null, null, null, null); // --> 7
808
        logFreeTextSearchResults(pager, Level.DEBUG, null);
809
        Assert.assertEquals("Expecting 8 entities", 8, pager.getCount().intValue());
810

    
811
        pager = taxonService.findByFullText(Taxon.class, "Abies", null, null, true, null, null, null, null); // --> 6
812
        Assert.assertEquals("Expecting 7 entities", 7, pager.getCount().intValue());
813

    
814
        pager = taxonService.findByFullText(Synonym.class, "Abies", null, null, true, null, null, null, null); // --> 1
815
        Assert.assertEquals("Expecting 1 entity", 1, pager.getCount().intValue());
816

    
817
        pager = taxonService.findByFullText(TaxonBase.class, "sec", null, null, true, null, null, null, null); // --> 7
818
        Assert.assertEquals("Expecting 8 entities", 9, pager.getCount().intValue());
819

    
820
        pager = taxonService.findByFullText(null, "genus", null, null, true, null, null, null, null); // --> 1
821
        Assert.assertEquals("Expecting 1 entity", 1, pager.getCount().intValue());
822

    
823
        pager = taxonService.findByFullText(Taxon.class, "subalpina", null, null, true, null, null, null, null); // --> 0
824
        Assert.assertEquals("Expecting 0 entities", 0, pager.getCount().intValue());
825

    
826
        // synonym in classification ???
827
    }
828

    
829
    @Test
830
    @DataSet
831
    public final void testPrepareByAreaSearch() throws IOException, LuceneParseException {
832

    
833
        List<PresenceAbsenceTerm> statusFilter = new ArrayList<PresenceAbsenceTerm>();
834
        List<NamedArea> areaFilter = new ArrayList<NamedArea>();
835
        areaFilter.add(germany);
836
        areaFilter.add(canada);
837
        areaFilter.add(russia);
838

    
839
        Pager<SearchResult<TaxonBase>> pager = taxonService.findByDistribution(areaFilter, statusFilter, null, 20, 0, null, null);
840
        Assert.assertEquals("Expecting 2 entities", Integer.valueOf(2), Integer.valueOf(pager.getRecords().size()));
841

    
842
    }
843

    
844
    @Test
845
    @DataSet
846
    public final void testFindTaxaAndNamesByFullText() throws IOException, LuceneParseException, LuceneMultiSearchException {
847

    
848
        refreshLuceneIndex();
849

    
850
        Pager<SearchResult<TaxonBase>> pager;
851

    
852
        Classification alternateClassification = classificationService.find(UUID.fromString(CLASSIFICATION_ALT_UUID));
853

    
854

    
855
        pager = taxonService.findTaxaAndNamesByFullText(
856
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
857
                "Abies", null, null, null, null, true, null, null, null, null);
858
//        logPagerRecords(pager, Level.DEBUG);
859
        Assert.assertEquals("doTaxa & doSynonyms", 8, pager.getCount().intValue());
860

    
861
        pager = taxonService.findTaxaAndNamesByFullText(
862
                EnumSet.allOf(TaxaAndNamesSearchMode.class),
863
                "Abies", null, null, null, null, true, null, null, null, null);
864
//        logPagerRecords(pager, Level.DEBUG);
865
        Assert.assertEquals("all search modes", 8, pager.getCount().intValue());
866

    
867
        pager = taxonService.findTaxaAndNamesByFullText(
868
                EnumSet.allOf(TaxaAndNamesSearchMode.class),
869
                "Abies", alternateClassification, null, null, null, true, null, null, null, null);
870
//        logPagerRecords(pager, Level.DEBUG);
871
        Assert.assertEquals("all search modes, filtered by alternateClassification", 1, pager.getCount().intValue());
872

    
873
        pager = taxonService.findTaxaAndNamesByFullText(
874
                EnumSet.of(TaxaAndNamesSearchMode.doSynonyms),
875
                "Abies", null, null, null, null, true, null, null, null, null);
876
        Assert.assertEquals("Expecting 1 entity", 1, pager.getCount().intValue());
877
        SearchResult<TaxonBase> searchResult = pager.getRecords().get(0);
878
        Assert.assertEquals(Synonym.class, searchResult.getEntity().getClass());
879
        // Abies subalpina sec. Kohlbecker, A., Testcase standart views, 2013
880

    
881

    
882
        pager = taxonService.findTaxaAndNamesByFullText(
883
                EnumSet.of(TaxaAndNamesSearchMode.doTaxaByCommonNames),
884
                "Abies", null, null, null, null, true, null, null, null, null);
885
        Assert.assertEquals("Expecting 0 entity", 0, pager.getCount().intValue());
886

    
887

    
888
        pager = taxonService.findTaxaAndNamesByFullText(
889
                EnumSet.of(TaxaAndNamesSearchMode.doTaxaByCommonNames),
890
                "Tanne", null, null, null, null, true, null, null, null, null);
891
        Assert.assertEquals("Expecting 1 entity", 1, pager.getRecords().size());
892
        Assert.assertEquals("Expecting 1 entity", 1, pager.getCount().intValue());
893

    
894
        pager = taxonService.findTaxaAndNamesByFullText(
895
                EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),
896
                "kawakamii", null, null, null, null, true, null, null, null, null);
897
        logFreeTextSearchResults(pager, Level.DEBUG, null);
898
        Assert.assertEquals("Expecting 1 entity", 1, pager.getCount().intValue());
899

    
900
    }
901

    
902
    @Test
903
    @DataSet
904
    public final void testFindTaxaAndNamesByFullText_PhraseQuery() throws IOException, LuceneParseException, LuceneMultiSearchException {
905

    
906
        refreshLuceneIndex();
907

    
908
        Pager<SearchResult<TaxonBase>> pager;
909

    
910

    
911
        pager = taxonService.findTaxaAndNamesByFullText(
912
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
913
                "\"Abies alba\"", null, null, null, null, true, null, null, null, null);
914
//        logPagerRecords(pager, Level.DEBUG);
915
        Assert.assertEquals("doTaxa & doSynonyms with simple phrase query", 1, pager.getCount().intValue());
916

    
917
        pager = taxonService.findTaxaAndNamesByFullText(
918
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
919
                "\"Abies al*\"", null, null, null, null, true, null, null, null, null);
920
//        logPagerRecords(pager, Level.DEBUG);
921
        Assert.assertEquals("doTaxa & doSynonyms with complex phrase query", 1, pager.getCount().intValue());
922

    
923
        pager = taxonService.findTaxaAndNamesByFullText(
924
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
925
                "\"Abies*\"", null, null, null, null, true, null, null, null, null);
926
//        logPagerRecords(pager, Level.DEBUG);
927
        Assert.assertEquals("doTaxa & doSynonyms with simple phrase query", 8, pager.getCount().intValue());
928

    
929
    }
930

    
931
    @Test
932
    @DataSet
933
    public final void testFindTaxaAndNamesByFullText_Sort() throws IOException, LuceneParseException, LuceneMultiSearchException {
934

    
935
        refreshLuceneIndex();
936

    
937
        Pager<SearchResult<TaxonBase>> pager;
938

    
939
        List<OrderHint> orderHints = new ArrayList<OrderHint>();
940

    
941
        String[] docFields2log = new String[]{"id"};
942

    
943
        // SortById
944
        orderHints.addAll(OrderHint.ORDER_BY_ID.asList());
945
        pager = taxonService.findTaxaAndNamesByFullText(
946
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa),
947
                "Abies", null, null, null, null, true, null, null, orderHints, null);
948
//        logSearchResults(pager, Level.DEBUG, docFields2log);
949
        int lastId = -1;
950
        for(SearchResult<TaxonBase> rs : pager.getRecords()){
951
            if(lastId != -1){
952
                Assert.assertTrue("results not sorted by id", lastId < rs.getEntity().getId());
953
            }
954
            lastId = rs.getEntity().getId();
955
        }
956

    
957
        orderHints.addAll(OrderHint.ORDER_BY_ID.asList());
958
        pager = taxonService.findTaxaAndNamesByFullText(
959
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
960
                "Abies", null, null, null, null, true, null, null, orderHints, null);
961
//        logSearchResults(pager, Level.DEBUG, docFields2log);
962

    
963
        lastId = -1;
964
        for(SearchResult<TaxonBase> rs : pager.getRecords()){
965
            if(lastId != -1){
966
                Assert.assertTrue("results not sorted by id", lastId < rs.getEntity().getId());
967
            }
968
            lastId = rs.getEntity().getId();
969
        }
970

    
971
        // Sortby NOMENCLATURAL_SORT_ORDER TODO make assertions !!!
972
        orderHints.clear();
973
        orderHints.addAll(OrderHint.NOMENCLATURAL_SORT_ORDER.asList());
974
        pager = taxonService.findTaxaAndNamesByFullText(
975
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
976
                "Abies", null, null, null, null, true, null, null, orderHints, null);
977
        logFreeTextSearchResults(pager, Level.DEBUG, null);
978

    
979
    }
980

    
981
    @Test
982
    @DataSet
983
    public final void testFindTaxaAndNamesByFullText_AreaFilter() throws IOException, LuceneParseException, LuceneMultiSearchException {
984

    
985
        refreshLuceneIndex();
986

    
987
        Pager<SearchResult<TaxonBase>> pager;
988

    
989
        Set<NamedArea> a_germany_canada_russia = new HashSet<NamedArea>();
990
        a_germany_canada_russia.add(germany);
991
        a_germany_canada_russia.add(canada);
992
        a_germany_canada_russia.add(russia);
993

    
994
        Set<NamedArea> a_russia = new HashSet<NamedArea>();
995
        a_russia.add(russia);
996

    
997
        Set<PresenceAbsenceTerm> present = new HashSet<PresenceAbsenceTerm>();
998
        present.add(PresenceAbsenceTerm.PRESENT());
999

    
1000
        Set<PresenceAbsenceTerm> present_native = new HashSet<PresenceAbsenceTerm>();
1001
        present_native.add(PresenceAbsenceTerm.PRESENT());
1002
        present_native.add(PresenceAbsenceTerm.NATIVE());
1003

    
1004
        Set<PresenceAbsenceTerm> absent = new HashSet<PresenceAbsenceTerm>();
1005
        absent.add(PresenceAbsenceTerm.ABSENT());
1006

    
1007
        pager = taxonService.findTaxaAndNamesByFullText(
1008
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa),
1009
                "Abies", null, a_germany_canada_russia, null, null, true, null, null, null, null);
1010
        logFreeTextSearchResults(pager, Level.DEBUG, null);
1011

    
1012
        // abies_kawakamii_sensu_komarov as missapplied name for t_abies_balsamea
1013
        pager = taxonService.findTaxaAndNamesByFullText(
1014
                EnumSet.of(TaxaAndNamesSearchMode.doSynonyms),
1015
                "Abies", null, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1016
        Assert.assertEquals("synonyms with matching area filter", 1, pager.getCount().intValue());
1017

    
1018
        pager = taxonService.findTaxaAndNamesByFullText(
1019
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
1020
                "Abies", null, a_germany_canada_russia, null, null, true, null, null, null, null);
1021
        logFreeTextSearchResults(pager, Level.DEBUG, null);
1022
        Assert.assertEquals("taxa and synonyms with matching area filter", 3, pager.getCount().intValue());
1023

    
1024
        pager = taxonService.findTaxaAndNamesByFullText(
1025
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
1026
                "Abies", null, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1027
        Assert.assertEquals("taxa and synonyms with matching area & status filter 1", 3, pager.getCount().intValue());
1028

    
1029
        pager = taxonService.findTaxaAndNamesByFullText(
1030
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
1031
                "Abies", null, a_germany_canada_russia, present, null, true, null, null, null, null);
1032
        Assert.assertEquals("taxa and synonyms with matching area & status filter 2", 2, pager.getCount().intValue());
1033

    
1034
        pager = taxonService.findTaxaAndNamesByFullText(
1035
                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),
1036
                "Abies", null, a_russia, present, null, true, null, null, null, null);
1037
        Assert.assertEquals("taxa and synonyms with non matching area & status filter", 0, pager.getCount().intValue());
1038

    
1039
        pager = taxonService.findTaxaAndNamesByFullText(
1040
                EnumSet.of(TaxaAndNamesSearchMode.doTaxaByCommonNames),
1041
                "Tanne", null, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1042
        Assert.assertEquals("ByCommonNames with area filter", 1, pager.getCount().intValue());
1043

    
1044
        // abies_kawakamii_sensu_komarov as misapplied name for t_abies_balsamea
1045
        pager = taxonService.findTaxaAndNamesByFullText(
1046
                EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),
1047
                "Abies", null, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1048
        Assert.assertEquals("misappliedNames with matching area & status filter", 1, pager.getCount().intValue());
1049

    
1050

    
1051
        // 1. remove existing taxon relation
1052
        Taxon t_abies_balsamea = (Taxon)taxonService.find(UUID.fromString(ABIES_BALSAMEA_UUID));
1053
        Set<TaxonRelationship> relsTo = t_abies_balsamea.getRelationsToThisTaxon();
1054
        Assert.assertEquals(1, relsTo.size());
1055
        TaxonRelationship taxonRelation = relsTo.iterator().next();
1056
        t_abies_balsamea.removeTaxonRelation(taxonRelation);
1057
        taxonService.saveOrUpdate(t_abies_balsamea);
1058
        commitAndStartNewTransaction(null);
1059

    
1060
        pager = taxonService.findTaxaAndNamesByFullText(
1061
                EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),
1062
                "Abies", null, a_germany_canada_russia, present_native, null, true, null, null, null, null);
1063
        Assert.assertEquals("misappliedNames with matching area & status filter, should match nothing now", 0, pager.getCount().intValue());
1064

    
1065
        // 2. now add abies_kawakamii_sensu_komarov as misapplied name for t_abies_alba and search for misapplications in russia: ABSENT
1066
        Taxon t_abies_kawakamii_sensu_komarov = (Taxon)taxonService.find(UUID.fromString(D_ABIES_KAWAKAMII_SEC_KOMAROV_UUID));
1067
        Taxon t_abies_alba = (Taxon)taxonService.find(UUID.fromString(ABIES_ALBA_UUID));
1068
        t_abies_alba.addMisappliedName(t_abies_kawakamii_sensu_komarov, null, null);
1069

    
1070
        taxonService.update(t_abies_kawakamii_sensu_komarov);
1071

    
1072
        commitAndStartNewTransaction(null);
1073

    
1074
        pager = taxonService.findTaxaAndNamesByFullText(
1075
                EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),
1076
                "Abies", null, a_germany_canada_russia, absent, null, true, null, null, null, null);
1077
        Assert.assertEquals("misappliedNames with matching area & status filter, should find one", 1, pager.getCount().intValue());
1078

    
1079
    }
1080

    
1081
    @Test
1082
    @DataSet
1083
    @Ignore // remove once http://dev.e-taxonomy.eu/trac/ticket/5477 is solved
1084
    public final void testFindTaxaAndNamesByFullText_AreaFilter_issue5477() throws IOException, LuceneParseException, LuceneMultiSearchException {
1085

    
1086
        Set<NamedArea> a_germany_canada_russia = new HashSet<NamedArea>();
1087
        a_germany_canada_russia.add(germany);
1088
        a_germany_canada_russia.add(canada);
1089
        a_germany_canada_russia.add(russia);
1090

    
1091

    
1092
        Set<PresenceAbsenceTerm> absent = new HashSet<PresenceAbsenceTerm>();
1093
        absent.add(PresenceAbsenceTerm.ABSENT());
1094

    
1095
        Taxon t_abies_kawakamii_sensu_komarov = (Taxon)taxonService.find(UUID.fromString(D_ABIES_KAWAKAMII_SEC_KOMAROV_UUID));
1096
        Taxon t_abies_alba = (Taxon)taxonService.find(UUID.fromString(ABIES_ALBA_UUID));
1097
        t_abies_alba.addMisappliedName(t_abies_kawakamii_sensu_komarov, null, null);
1098

    
1099
        /* Since the upgrade from hibernate search 4 to 5.5
1100
         * triggering an update of t_abies_alba is no longer sufficient to also update the
1101
         * document of t_abies_kawakamii_sensu_komarov in the lucene index.
1102
         * the last test in testFindTaxaAndNamesByFullText_AreaFilter() failed in this case.
1103
         * This situation is reproduced here:
1104
         */
1105
        taxonService.update(t_abies_alba);
1106

    
1107
          commitAndStartNewTransaction(null);
1108

    
1109
          Pager pager = taxonService.findTaxaAndNamesByFullText(
1110
                  EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),
1111
                  "Abies", null, a_germany_canada_russia, absent, null, true, null, null, null, null);
1112
          Assert.assertEquals("misappliedNames with matching area & status filter, should find one", 1, pager.getCount().intValue());
1113
    }
1114

    
1115

    
1116
    /**
1117
     * Regression test for #3119: fulltext search: Entity always null whatever search
1118
     *
1119
     * @throws IOException
1120
     * @throws LuceneParseException
1121
     * @throws LuceneMultiSearchException
1122
     */
1123
    @Test
1124
    @DataSet
1125
    public final void testFindByEverythingFullText() throws IOException, LuceneParseException, LuceneMultiSearchException {
1126

    
1127
        refreshLuceneIndex();
1128

    
1129
        Pager<SearchResult<TaxonBase>> pager;
1130

    
1131
        // via Taxon
1132
        pager = taxonService.findByEverythingFullText("Abies", null, null, true, null, null, null, null);
1133
        logFreeTextSearchResults(pager, Level.DEBUG, null);
1134
        Assert.assertTrue("Expecting at least 7 entities for 'Abies'", pager.getCount() > 7);
1135
        Assert.assertNotNull("Expecting entity", pager.getRecords().get(0).getEntity());
1136
        Assert.assertEquals("Expecting Taxon entity", Taxon.class, pager.getRecords().get(0).getEntity().getClass());
1137

    
1138
        // via DescriptionElement
1139
        pager = taxonService.findByEverythingFullText("present", null, null, true, null, null, null, null);
1140
        Assert.assertEquals("Expecting one entity when searching for area 'present'", 1, pager.getCount().intValue());
1141
        Assert.assertNotNull("Expecting entity", pager.getRecords().get(0).getEntity());
1142
        Assert.assertEquals("Expecting Taxon entity", Taxon.class, CdmBase.deproxy(pager.getRecords().get(0).getEntity()).getClass());
1143
        Assert.assertEquals("Expecting Taxon ", ABIES_BALSAMEA_UUID, pager.getRecords().get(0).getEntity().getUuid().toString());
1144

    
1145
    }
1146

    
1147

    
1148
    @Test
1149
    @DataSet
1150
    public final void findByEveryThingFullText() throws IOException, LuceneParseException, LuceneMultiSearchException {
1151

    
1152
        refreshLuceneIndex();
1153

    
1154
        Pager<SearchResult<TaxonBase>> pager;
1155

    
1156
        pager = taxonService.findByEverythingFullText("genus", null, null,  false, null, null, null, null); // --> 1
1157
        Assert.assertEquals("Expecting 1 entity", 1, pager.getCount().intValue());
1158

    
1159
        //FIXME FAILS: abies balamea is returned twice, see also testFullText_Grouping()
1160
        pager = taxonService.findByEverythingFullText("Balsam", null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);
1161
        logFreeTextSearchResults(pager, Level.DEBUG, null);
1162
        Assert.assertEquals("expecting to find the Abies balsamea via the GERMAN DescriptionElements", 1, pager.getCount().intValue());
1163

    
1164
        pager = taxonService.findByEverythingFullText("Abies", null, null, true, null, null, null, null);
1165
        Assert.assertEquals("Expecting 8 entities", 8, pager.getCount().intValue());
1166
        SearchResult<TaxonBase> searchResult = pager.getRecords().get(0);
1167
        Assert.assertTrue("the map of highlighted fragments should contain at least one item", searchResult.getFieldHighlightMap().size() > 0);
1168
        String[] fragments = searchResult.getFieldHighlightMap().values().iterator().next();
1169
        Assert.assertTrue("first fragments should contains serch term", fragments[0].toLowerCase().contains("<b>abies</b>"));
1170
    }
1171

    
1172
//    @SuppressWarnings("rawtypes")
1173
//    @Test
1174
//    @DataSet
1175
//    public final void benchmarkFindTaxaAndNamesHql() throws IOException, LuceneParseException {
1176
//
1177
//        createRandomTaxonWithCommonName(NUM_OF_NEW_RADOM_ENTITIES);
1178
//
1179
//        IFindTaxaAndNamesConfigurator configurator = new FindTaxaAndNamesConfiguratorImpl();
1180
//        configurator.setTitleSearchString("Wei"+UTF8.SHARP_S+"%");
1181
//        configurator.setMatchMode(MatchMode.BEGINNING);
1182
//        configurator.setDoTaxa(false);
1183
//        configurator.setDoSynonyms(false);
1184
//        configurator.setDoNamesWithoutTaxa(false);
1185
//        configurator.setDoTaxaByCommonNames(true);
1186
//
1187
//        Pager<IdentifiableEntity> pager;
1188
//
1189
//        long startMillis = System.currentTimeMillis();
1190
//        for (int indx = 0; indx < BENCHMARK_ROUNDS; indx++) {
1191
//            pager = taxonService.findTaxaAndNames(configurator);
1192
//            if (logger.isDebugEnabled()) {
1193
//                logger.debug("[" + indx + "]" + pager.getRecords().get(0).getTitleCache());
1194
//            }
1195
//        }
1196
//        double duration = ((double) (System.currentTimeMillis() - startMillis)) / BENCHMARK_ROUNDS;
1197
//        logger.info("Benchmark result - [find taxon by CommonName via HQL] : " + duration + "ms (" + BENCHMARK_ROUNDS + " benchmark rounds )");
1198
//    }
1199

    
1200
    @SuppressWarnings("rawtypes")
1201
    @Test
1202
    @DataSet
1203
    public final void benchmarkFindByCommonNameHql() throws IOException, LuceneParseException {
1204

    
1205
//        printDataSet(System.err, new String[] { "TaxonBase" });
1206

    
1207
        createRandomTaxonWithCommonName(NUM_OF_NEW_RADOM_ENTITIES);
1208

    
1209
        IFindTaxaAndNamesConfigurator configurator = new FindTaxaAndNamesConfiguratorImpl<>();
1210
        configurator.setTitleSearchString("Wei"+UTF8.SHARP_S+"%");
1211
        configurator.setMatchMode(MatchMode.BEGINNING);
1212
        configurator.setDoTaxa(false);
1213
        configurator.setDoSynonyms(false);
1214
        configurator.setDoNamesWithoutTaxa(false);
1215
        configurator.setDoTaxaByCommonNames(true);
1216

    
1217
        Pager<IdentifiableEntity> pager;
1218

    
1219
        long startMillis = System.currentTimeMillis();
1220
        for (int indx = 0; indx < BENCHMARK_ROUNDS; indx++) {
1221
            pager = taxonService.findTaxaAndNames(configurator);
1222
            if (logger.isDebugEnabled()) {
1223
                logger.debug("[" + indx + "]" + pager.getRecords().get(0).getTitleCache());
1224
            }
1225
        }
1226
        double duration = ((double) (System.currentTimeMillis() - startMillis)) / BENCHMARK_ROUNDS;
1227
        logger.info("Benchmark result - [find taxon by CommonName via HQL] : " + duration + "ms (" + BENCHMARK_ROUNDS + " benchmark rounds )");
1228
    }
1229

    
1230
    @SuppressWarnings("rawtypes")
1231
    @Test
1232
    @DataSet
1233
    public final void benchmarkFindByCommonNameLucene() throws IOException, LuceneParseException {
1234

    
1235
        createRandomTaxonWithCommonName(NUM_OF_NEW_RADOM_ENTITIES);
1236

    
1237
        refreshLuceneIndex();
1238

    
1239
        Pager<SearchResult<TaxonBase>> pager;
1240

    
1241
        long startMillis = System.currentTimeMillis();
1242
        for (int indx = 0; indx < BENCHMARK_ROUNDS; indx++) {
1243
            pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"*", null, null, null, false, null, null, null, null);
1244
            if (logger.isDebugEnabled()) {
1245
                logger.debug("[" + indx + "]" + pager.getRecords().get(0).getEntity().getTitleCache());
1246
            }
1247
        }
1248
        double duration = ((double) (System.currentTimeMillis() - startMillis)) / BENCHMARK_ROUNDS;
1249
        logger.info("Benchmark result - [find taxon by CommonName via lucene] : " + duration + "ms (" + BENCHMARK_ROUNDS + " benchmark rounds )");
1250
    }
1251

    
1252
    /**
1253
     * uncomment @Test annotation to create the dataset for this test
1254
     */
1255
    @Override
1256
    //    @Test
1257
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="BlankDataSet.xml")
1258
    public final void createTestDataSet() throws FileNotFoundException {
1259

    
1260
        Classification europeanAbiesClassification = Classification.NewInstance("European Abies");
1261
        europeanAbiesClassification.setUuid(UUID.fromString(CLASSIFICATION_UUID));
1262
        classificationService.save(europeanAbiesClassification);
1263

    
1264
        Classification alternativeClassification = Classification.NewInstance("Abies alternative");
1265
        alternativeClassification.setUuid(UUID.fromString(CLASSIFICATION_ALT_UUID));
1266
        classificationService.save(alternativeClassification);
1267

    
1268
        Reference sec = ReferenceFactory.newBook();
1269
        sec.setTitleCache("Kohlbecker, A., Testcase standart views, 2013", true);
1270
        Reference sec_sensu = ReferenceFactory.newBook();
1271
        sec_sensu.setTitleCache("Komarov, V. L., Flora SSSR 29", true);
1272
        referenceService.save(sec);
1273
        referenceService.save(sec_sensu);
1274

    
1275
        IBotanicalName n_abies = TaxonNameFactory.NewBotanicalInstance(Rank.GENUS());
1276
        n_abies.setNameCache("Abies", true);
1277
        Taxon t_abies = Taxon.NewInstance(n_abies, sec);
1278
        taxonService.save(t_abies);
1279

    
1280
        IBotanicalName n_abies_alba = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1281
        n_abies_alba.setNameCache("Abies alba", true);
1282
        Taxon t_abies_alba = Taxon.NewInstance(n_abies_alba, sec);
1283
        t_abies_alba.setUuid(UUID.fromString(ABIES_ALBA_UUID));
1284
        taxonService.save(t_abies_alba);
1285

    
1286
        IBotanicalName n_abies_subalpina = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1287
        n_abies_subalpina.setNameCache("Abies subalpina", true);
1288
        Synonym s_abies_subalpina = Synonym.NewInstance(n_abies_subalpina, sec);
1289
        taxonService.save(s_abies_subalpina);
1290

    
1291
        IBotanicalName n_abies_balsamea = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1292
        n_abies_balsamea.setNameCache("Abies balsamea", true);
1293
        Taxon t_abies_balsamea = Taxon.NewInstance(n_abies_balsamea, sec);
1294
        t_abies_balsamea.setUuid(UUID.fromString(ABIES_BALSAMEA_UUID));
1295
        t_abies_balsamea.addSynonym(s_abies_subalpina, SynonymType.SYNONYM_OF());
1296
        taxonService.save(t_abies_balsamea);
1297

    
1298
        IBotanicalName n_abies_grandis = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1299
        n_abies_grandis.setNameCache("Abies grandis", true);
1300
        Taxon t_abies_grandis = Taxon.NewInstance(n_abies_grandis, sec);
1301
        taxonService.save(t_abies_grandis);
1302

    
1303
        IBotanicalName n_abies_kawakamii = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1304
        n_abies_kawakamii.setNameCache("Abies kawakamii", true);
1305
        Taxon t_abies_kawakamii = Taxon.NewInstance(n_abies_kawakamii, sec);
1306
        t_abies_kawakamii.getTitleCache();
1307
        taxonService.save(t_abies_kawakamii);
1308

    
1309
        // abies_kawakamii_sensu_komarov as missapplied name for t_abies_balsamea
1310
        Taxon t_abies_kawakamii_sensu_komarov = Taxon.NewInstance(n_abies_kawakamii, sec_sensu);
1311
        taxonService.save(t_abies_kawakamii_sensu_komarov);
1312
        t_abies_kawakamii_sensu_komarov.addTaxonRelation(t_abies_balsamea, TaxonRelationshipType.MISAPPLIED_NAME_FOR(), null, null);
1313
        taxonService.saveOrUpdate(t_abies_kawakamii_sensu_komarov);
1314

    
1315
        IBotanicalName n_abies_lasiocarpa = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1316
        n_abies_lasiocarpa.setNameCache("Abies lasiocarpa", true);
1317
        Taxon t_abies_lasiocarpa = Taxon.NewInstance(n_abies_lasiocarpa, sec);
1318
        taxonService.save(t_abies_lasiocarpa);
1319

    
1320
        // add taxa to classifications
1321
        europeanAbiesClassification.addChildTaxon(t_abies_balsamea, null, null);
1322
        alternativeClassification.addChildTaxon(t_abies_lasiocarpa, null, null);
1323
        classificationService.saveOrUpdate(europeanAbiesClassification);
1324
        classificationService.saveOrUpdate(alternativeClassification);
1325

    
1326
        //
1327
        // Description
1328
        //
1329
        TaxonDescription d_abies_alba = TaxonDescription.NewInstance(t_abies_alba);
1330
        TaxonDescription d_abies_balsamea = TaxonDescription.NewInstance(t_abies_balsamea);
1331

    
1332
        d_abies_alba.setUuid(UUID.fromString(D_ABIES_ALBA_UUID));
1333
        d_abies_balsamea.setUuid(UUID.fromString(D_ABIES_BALSAMEA_UUID));
1334

    
1335

    
1336
        // CommonTaxonName
1337
        d_abies_alba.addElement(CommonTaxonName.NewInstance("Wei"+UTF8.SHARP_S+"tanne", Language.GERMAN()));
1338
        d_abies_alba.addElement(CommonTaxonName.NewInstance("silver fir", Language.ENGLISH()));
1339
        d_abies_alba.addElement(Distribution
1340
                .NewInstance(
1341
                        germany,
1342
                        PresenceAbsenceTerm.NATIVE()));
1343
        d_abies_alba.addElement(Distribution
1344
                .NewInstance(
1345
                        russia,
1346
                        PresenceAbsenceTerm.ABSENT()));
1347

    
1348
        // TextData
1349
        d_abies_balsamea
1350
            .addElement(TextData
1351
                    .NewInstance(
1352
                            "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.",
1353
                            Language.GERMAN(), null));
1354
        d_abies_balsamea
1355
        .addElement(CommonTaxonName
1356
                .NewInstance(
1357
                        "Balsam-Tanne",
1358
                        Language.GERMAN(), null));
1359

    
1360
        d_abies_balsamea
1361
        .addElement(Distribution
1362
                .NewInstance(
1363
                        canada,
1364
                        PresenceAbsenceTerm.PRESENT()));
1365

    
1366
        d_abies_balsamea
1367
        .addElement(Distribution
1368
                .NewInstance(
1369
                        germany,
1370
                        PresenceAbsenceTerm.NATIVE()));
1371

    
1372
        d_abies_balsamea
1373
                .addElement(TextData
1374
                        .NewInstance(
1375
                                TaxonServiceSearchTestUtf8Constants.RUSSIAN_ABIES_ALBA_LONG,
1376
                                Language.RUSSIAN(), null));
1377
        d_abies_balsamea
1378
        .addElement(CommonTaxonName
1379
                .NewInstance(
1380
                        TaxonServiceSearchTestUtf8Constants.RUSSIAN_ABIES_ALBA_SHORT,
1381
                        Language.RUSSIAN(), null));
1382
        descriptionService.saveOrUpdate(d_abies_balsamea);
1383

    
1384
        setComplete();
1385
        endTransaction();
1386

    
1387

    
1388
        writeDbUnitDataSetFile(new String[] {
1389
            "TAXONBASE", "TAXONNAMEBASE",
1390
            "TAXONRELATIONSHIP",
1391
            "REFERENCE", "DESCRIPTIONELEMENTBASE", "DESCRIPTIONBASE",
1392
            "AGENTBASE", "HOMOTYPICALGROUP",
1393
            "CLASSIFICATION", "TAXONNODE",
1394
            "LANGUAGESTRING", "DESCRIPTIONELEMENTBASE_LANGUAGESTRING",
1395
            "HIBERNATE_SEQUENCES" // IMPORTANT!!!
1396
            });
1397

    
1398
    }
1399

    
1400
    /**
1401
     *
1402
     */
1403
    private void refreshLuceneIndex() {
1404

    
1405
//        commitAndStartNewTransaction(null);
1406
        commit();
1407
        endTransaction();
1408
        indexer.purge(DefaultProgressMonitor.NewInstance());
1409
        indexer.reindex(typesToIndex, DefaultProgressMonitor.NewInstance());
1410
        startNewTransaction();
1411
//        commitAndStartNewTransaction(null);
1412
    }
1413

    
1414
    /**
1415
     * @param numberOfNew
1416
     *
1417
     */
1418
    private void createRandomTaxonWithCommonName(int numberOfNew) {
1419

    
1420
        logger.debug(String.format("creating %1$s random taxan with CommonName", numberOfNew));
1421

    
1422
        commitAndStartNewTransaction(null);
1423

    
1424
        Reference sec = ReferenceFactory.newBook();
1425
        referenceService.save(sec);
1426

    
1427
        for (int i = numberOfNew; i < numberOfNew; i++) {
1428
            RandomStringUtils.randomAlphabetic(10);
1429
            String radomName = RandomStringUtils.randomAlphabetic(5) + " " + RandomStringUtils.randomAlphabetic(10);
1430
            String radomCommonName = RandomStringUtils.randomAlphabetic(10);
1431

    
1432
            IBotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1433
            name.setNameCache(radomName, true);
1434
            Taxon taxon = Taxon.NewInstance(name, sec);
1435
            taxonService.save(taxon);
1436

    
1437
            TaxonDescription description = TaxonDescription.NewInstance(taxon);
1438
            description.addElement(CommonTaxonName.NewInstance(radomCommonName, Language.GERMAN()));
1439
            descriptionService.save(description);
1440
        }
1441

    
1442
        commitAndStartNewTransaction(null);
1443
    }
1444

    
1445
    private <T extends CdmBase> void logFreeTextSearchResults(Pager<SearchResult<T>> pager, Level level, String[] docFields){
1446
        if(level == null){
1447
            level = Level.DEBUG;
1448
        }
1449
        if(logger.isEnabledFor(level)){
1450
            StringBuilder b = new StringBuilder();
1451
            b.append("\n");
1452
            int i = 0;
1453
            for(SearchResult sr : pager.getRecords()){
1454

    
1455
                b.append(" ").append(i++).append(" - ");
1456
                b.append("score:").append(sr.getScore()).append(", ");
1457

    
1458
                if(docFields != null){
1459
                    b.append("docs : ");
1460
                    for(Document doc : sr.getDocs()) {
1461
                        b.append("<");
1462
                        for(String f : docFields){
1463
                            b.append(f).append(":").append(Arrays.toString(doc.getValues(f)));
1464
                        }
1465
                        b.append(">");
1466
                    }
1467
                }
1468

    
1469
                CdmBase entity = sr.getEntity();
1470
                if(entity == null){
1471
                    b.append("NULL");
1472
                } else {
1473
                    b.append(entity.getClass().getSimpleName()).
1474
                        append(" [").append(entity.getId()).
1475
                        append(" | ").append(entity.getUuid()).append("] : ").
1476
                        append(entity.toString());
1477

    
1478
                }
1479
                b.append("\n");
1480
            }
1481
            logger.log(level, b);
1482
        }
1483
    }
1484

    
1485
}
(28-28/34)