Merge branch 'master' of wp5.e-taxonomy.eu:/var/git/cdmlib into remoting-4.0
[cdmlib.git] / cdmlib-services / src / test / java / eu / etaxonomy / cdm / api / service / TaxonServiceSearchTest.java
index 9f13aaeff1e5921022ac1a626bfd9dc12d689c9f..b83b0a10823bd92dbdf65660ba45f6b457d12000 100644 (file)
@@ -14,7 +14,9 @@ import static org.junit.Assert.assertNotNull;
 \r
 import java.io.FileNotFoundException;\r
 import java.io.IOException;\r
+import java.util.ArrayList;\r
 import java.util.Arrays;\r
+import java.util.EnumSet;\r
 import java.util.HashSet;\r
 import java.util.List;\r
 import java.util.Map;\r
@@ -22,11 +24,13 @@ import java.util.Set;
 import java.util.UUID;\r
 \r
 import org.apache.commons.lang.RandomStringUtils;\r
+import org.apache.log4j.Level;\r
 import org.apache.log4j.Logger;\r
 import org.apache.lucene.document.Document;\r
 import org.apache.lucene.index.CorruptIndexException;\r
 import org.apache.lucene.queryParser.ParseException;\r
 import org.junit.Assert;\r
+import org.junit.Before;\r
 import org.junit.Ignore;\r
 import org.junit.Test;\r
 import org.unitils.dbunit.annotation.DataSet;\r
@@ -36,9 +40,13 @@ import eu.etaxonomy.cdm.api.service.config.FindTaxaAndNamesConfiguratorImpl;
 import eu.etaxonomy.cdm.api.service.config.IFindTaxaAndNamesConfigurator;\r
 import eu.etaxonomy.cdm.api.service.pager.Pager;\r
 import eu.etaxonomy.cdm.api.service.search.ICdmMassIndexer;\r
+import eu.etaxonomy.cdm.api.service.search.LuceneMultiSearchException;\r
 import eu.etaxonomy.cdm.api.service.search.SearchResult;\r
+import eu.etaxonomy.cdm.common.UTF8;\r
 import eu.etaxonomy.cdm.common.monitor.DefaultProgressMonitor;\r
 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;\r
+import eu.etaxonomy.cdm.model.common.CdmBase;\r
+import eu.etaxonomy.cdm.model.common.DefinedTermBase;\r
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;\r
 import eu.etaxonomy.cdm.model.common.Language;\r
 import eu.etaxonomy.cdm.model.description.CategoricalData;\r
@@ -47,10 +55,13 @@ import eu.etaxonomy.cdm.model.description.DescriptionBase;
 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
 import eu.etaxonomy.cdm.model.description.Distribution;\r
 import eu.etaxonomy.cdm.model.description.Feature;\r
+import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;\r
 import eu.etaxonomy.cdm.model.description.State;\r
 import eu.etaxonomy.cdm.model.description.StateData;\r
 import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
 import eu.etaxonomy.cdm.model.description.TextData;\r
+import eu.etaxonomy.cdm.model.location.Country;\r
+import eu.etaxonomy.cdm.model.location.NamedArea;\r
 import eu.etaxonomy.cdm.model.name.BotanicalName;\r
 import eu.etaxonomy.cdm.model.name.NonViralName;\r
 import eu.etaxonomy.cdm.model.name.Rank;\r
@@ -63,20 +74,24 @@ import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
 import eu.etaxonomy.cdm.model.taxon.Taxon;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonNode;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
+import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;\r
 import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
+import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
 import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;\r
 import eu.etaxonomy.cdm.test.unitils.CleanSweepInsertLoadStrategy;\r
 \r
-\r
 /**\r
  * @author a.babadshanjan, a.kohlbecker\r
  * @created 04.02.2009\r
- * @version 1.0\r
  */\r
 public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {\r
 \r
     private static final String ABIES_BALSAMEA_UUID = "f65d47bd-4f49-4ab1-bc4a-bc4551eaa1a8";\r
 \r
+    private static final String ABIES_ALBA_UUID = "7dbd5810-a3e5-44b6-b563-25152b8867f4";\r
+\r
     private static final String CLASSIFICATION_UUID = "2a5ceebb-4830-4524-b330-78461bf8cb6b";\r
 \r
     private static final String CLASSIFICATION_ALT_UUID = "d7c741e3-ae9e-4a7d-a566-9e3a7a0b51ce";\r
@@ -85,10 +100,13 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
     private static final String D_ABIES_ALBA_UUID = "ec8bba03-d993-4c85-8472-18b14942464b";\r
 \r
+    private static final String D_ABIES_KAWAKAMII_SEC_KOMAROV_UUID = "e9d8c2fd-6409-46d5-9c2e-14a2bbb1b2b1";\r
     private static final int NUM_OF_NEW_RADOM_ENTITIES = 1000;\r
 \r
     private static Logger logger = Logger.getLogger(TaxonServiceSearchTest.class);\r
 \r
+\r
+\r
     @SpringBeanByType\r
     private ITaxonService taxonService;\r
     @SpringBeanByType\r
@@ -106,6 +124,31 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
     private static final int BENCHMARK_ROUNDS = 300;\r
 \r
+    private Set<Class<? extends CdmBase>> typesToIndex = null;\r
+\r
+    private NamedArea germany;\r
+    private NamedArea france ;\r
+    private NamedArea russia ;\r
+    private NamedArea canada ;\r
+\r
+    /**\r
+     * @throws java.lang.Exception\r
+     */\r
+    @Before\r
+    public void setUp() throws Exception {\r
+        typesToIndex = new HashSet<Class<? extends CdmBase>>();\r
+        typesToIndex.add(DescriptionElementBase.class);\r
+        typesToIndex.add(TaxonBase.class);\r
+        typesToIndex.add(TaxonRelationship.class);\r
+\r
+        germany =  Country.GERMANY();\r
+        france = Country.FRANCEFRENCHREPUBLIC();\r
+        russia = Country.RUSSIANFEDERATION();\r
+        canada = Country.CANADA();\r
+\r
+\r
+    }\r
+\r
     @Test\r
     public void testDbUnitUsageTest() throws Exception {\r
         assertNotNull("taxonService should exist", taxonService);\r
@@ -149,8 +192,11 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         }\r
 \r
         logger.debug("number of taxa: " + list.size());\r
-        assertEquals(7, list.size());\r
-\r
+        assertEquals(9, list.size());\r
+        configurator.setTitleSearchString("Balsam-Tanne");\r
+        pager = taxonService.findTaxaAndNames(configurator);\r
+        list = pager.getRecords();\r
+        assertEquals(1, list.size());\r
         // pass 2\r
 //        configurator.setDoTaxaByCommonNames(false);\r
 //        configurator.setDoMisappliedNames(true);\r
@@ -169,7 +215,29 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
     @Test\r
     @DataSet\r
     public final void testSearchTaxaByName() {\r
-        logger.warn("testSearchTaxaByName not yet implemented"); // TODO\r
+        IFindTaxaAndNamesConfigurator<?> configurator = new FindTaxaAndNamesConfiguratorImpl();\r
+         configurator.setTitleSearchString("Abies*");\r
+         configurator.setMatchMode(MatchMode.BEGINNING);\r
+         configurator.setDoTaxa(false);\r
+         configurator.setDoSynonyms(false);\r
+         configurator.setDoNamesWithoutTaxa(true);\r
+         configurator.setDoTaxaByCommonNames(false);\r
+\r
+        List<UuidAndTitleCache<IdentifiableEntity>> list = taxonService.findTaxaAndNamesForEditor(configurator);\r
+\r
+         Assert.assertEquals("Expecting one entity", 1, list.size());\r
+         \r
+         configurator.setTitleSearchString("silver fir");\r
+         configurator.setMatchMode(MatchMode.BEGINNING);\r
+         configurator.setDoTaxa(false);\r
+         configurator.setDoSynonyms(false);\r
+         configurator.setDoNamesWithoutTaxa(true);\r
+         configurator.setDoTaxaByCommonNames(true);\r
+\r
+         list = taxonService.findTaxaAndNamesForEditor(configurator);\r
+\r
+         Assert.assertEquals("Expecting one entity", 1, list.size());\r
+         \r
     }\r
 \r
     @SuppressWarnings("rawtypes")\r
@@ -182,7 +250,7 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         Pager<SearchResult<TaxonBase>> pager;\r
 \r
         pager = taxonService.findByFullText(null, "Abies", null, null, true, null, null, null, null); // --> 7\r
-        Assert.assertEquals("Expecting 7 entities", Integer.valueOf(7), pager.getCount());\r
+        Assert.assertEquals("Expecting 8 entities", Integer.valueOf(8), pager.getCount());\r
 \r
         indexer.purge(null);\r
         commitAndStartNewTransaction(null);\r
@@ -201,7 +269,7 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
         Pager<SearchResult<TaxonBase>> pager;\r
 \r
-        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Weißtanne", null, null, null,\r
+        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"tanne", null, null, null,\r
                 false, null, null, null, null);\r
         Assert.assertEquals("Expecting one entity when searching for CommonTaxonName", Integer.valueOf(1),\r
                 pager.getCount());\r
@@ -212,11 +280,11 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
                 false, null, null, null, null);\r
         Assert.assertEquals("Expecting no entity when searching for 'Nulltanne' ", Integer.valueOf(0), pager.getCount());\r
 \r
-        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Weißtanne", null, null,\r
+        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"tanne", null, null,\r
                 Arrays.asList(new Language[] { Language.GERMAN() }), false, null, null, null, null);\r
         Assert.assertEquals("Expecting one entity when searching in German", Integer.valueOf(1), pager.getCount());\r
 \r
-        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Weißtanne", null, null,\r
+        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"tanne", null, null,\r
                 Arrays.asList(new Language[] { Language.RUSSIAN() }), false, null, null, null, null);\r
         Assert.assertEquals("Expecting no entity when searching in Russian", Integer.valueOf(0), pager.getCount());\r
 \r
@@ -231,8 +299,8 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
         Pager<SearchResult<TaxonBase>> pager;\r
         // by Area\r
-        pager = taxonService.findByDescriptionElementFullText(null, "America", null, null, null, false, null, null, null, null);\r
-        Assert.assertEquals("Expecting one entity when searching for arae 'America'", Integer.valueOf(1), pager.getCount());\r
+        pager = taxonService.findByDescriptionElementFullText(null, "Canada", null, null, null, false, null, null, null, null);\r
+        Assert.assertEquals("Expecting one entity when searching for arae 'Canada'", Integer.valueOf(1), pager.getCount());\r
         // by Status\r
         pager = taxonService.findByDescriptionElementFullText(null, "present", null, null, null, false, null, null, null, null);\r
         Assert.assertEquals("Expecting one entity when searching for status 'present'", Integer.valueOf(1), pager.getCount());\r
@@ -247,7 +315,7 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
         Pager<SearchResult<TaxonBase>> pager;\r
 \r
-        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Weiß*", null, null, null, false, null, null, null, null);\r
+        pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"*", null, null, null, false, null, null, null, null);\r
         Assert.assertEquals("Expecting one entity when searching for CommonTaxonName", Integer.valueOf(1), pager.getCount());\r
     }\r
 \r
@@ -428,10 +496,11 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
      * @throws CorruptIndexException\r
      * @throws IOException\r
      * @throws ParseException\r
+     * @throws LuceneMultiSearchException\r
      */\r
     @Test\r
     @DataSet\r
-    public final void testFullText_Grouping() throws CorruptIndexException, IOException, ParseException {\r
+    public final void testFullText_Grouping() throws CorruptIndexException, IOException, ParseException, LuceneMultiSearchException {\r
 \r
         TaxonDescription description = (TaxonDescription) descriptionService.find(UUID.fromString(D_ABIES_ALBA_UUID));\r
         Set<String> uniqueRandomStrs = new HashSet<String>(1024);\r
@@ -451,15 +520,28 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         int pageSize = 10;\r
 \r
         Pager<SearchResult<TaxonBase>> pager;\r
-\r
         boolean highlightFragments = true;\r
+\r
+        // test with findByDescriptionElementFullText\r
         pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Rot*", null, null, null, highlightFragments, pageSize, null, null, null);\r
-        Assert.assertEquals("All matches should be grouped in one page", 1, pager.getPagesAvailable().intValue());\r
+        logSearchResults(pager, Level.DEBUG, null);\r
+        Assert.assertEquals("All matches should be grouped into a single SearchResult element", 1, pager.getRecords().size());\r
+        Assert.assertEquals("The count property of the pager must be set correctly", 1, pager.getCount().intValue());\r
         Map<String, String[]> highlightMap = pager.getRecords().get(0).getFieldHighlightMap();\r
         // maxDocsPerGroup is defined in LuceneSearch and defaults to 10\r
         int maxDocsPerGroup = 10;\r
         Assert.assertEquals("expecting 10 highlighted fragments of field 'name'", maxDocsPerGroup, highlightMap.get("name").length);\r
 \r
+        // test with findByEverythingFullText\r
+        pager = taxonService.findByEverythingFullText( "Rot*", null, null, highlightFragments, pageSize, null, null, null);\r
+        logSearchResults(pager, Level.DEBUG, null);\r
+        Assert.assertEquals("All matches should be grouped into a single SearchResult element", 1, pager.getRecords().size());\r
+        Assert.assertEquals("The count property of the pager must be set correctly", 1, pager.getCount().intValue());\r
+        highlightMap = pager.getRecords().get(0).getFieldHighlightMap();\r
+        // maxDocsPerGroup is defined in LuceneSearch and defaults to 10\r
+        maxDocsPerGroup = 10;\r
+        Assert.assertEquals("expecting 10 highlighted fragments of field 'name'", maxDocsPerGroup, highlightMap.get("name").length);\r
+\r
     }\r
 \r
     @SuppressWarnings("rawtypes")\r
@@ -471,10 +553,11 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
         Pager<SearchResult<TaxonBase>> pager;\r
         pager = taxonService.findByDescriptionElementFullText(TextData.class, "Abies", null, null, null, false, null, null, null, null);\r
+        logSearchResults(pager, Level.DEBUG, null);\r
         Assert.assertEquals("Expecting one entity when searching for any TextData", Integer.valueOf(1), pager.getCount());\r
-        Assert.assertEquals("Abies balsamea sec. ", pager.getRecords().get(0).getEntity().getTitleCache());\r
-        Assert.assertTrue("Expecting only one doc", pager.getRecords().get(0).getDocs().size() == 1);\r
-        Assert.assertEquals("Abies balsamea sec. ", pager.getRecords().get(0).getDocs().iterator().next().get("inDescription.taxon.titleCache"));\r
+        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());\r
+        Assert.assertTrue("Expecting two docs, one for RUSSIAN and one for GERMAN", pager.getRecords().get(0).getDocs().size() == 2);\r
+        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getDocs().iterator().next().get("inDescription.taxon.titleCache"));\r
 \r
 \r
         pager = taxonService.findByDescriptionElementFullText(null, "Abies", null, null, null, false, null, null, null, null);\r
@@ -494,18 +577,18 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
         pager = taxonService.findByDescriptionElementFullText(TextData.class, "Бальзам", null, null, Arrays.asList(new Language[]{}), false, null, null, null, null);\r
         Assert.assertEquals("Expecting one entity", Integer.valueOf(1), pager.getCount());\r
-        Assert.assertEquals("Abies balsamea sec. ", pager.getRecords().get(0).getEntity().getTitleCache());\r
+        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());\r
 \r
         pager = taxonService.findByDescriptionElementFullText(TextData.class, "Бальзам", null, null, Arrays.asList(new Language[]{Language.RUSSIAN()}), false, null, null, null, null);\r
         Assert.assertEquals("Expecting one entity", Integer.valueOf(1), pager.getCount());\r
-        Assert.assertEquals("Abies balsamea sec. ", pager.getRecords().get(0).getEntity().getTitleCache());\r
+        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());\r
 \r
         pager = taxonService.findByDescriptionElementFullText(TextData.class, "Бальзам", null, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);\r
         Assert.assertEquals("Expecting no entity", Integer.valueOf(0), pager.getCount());\r
 \r
         pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, null, Arrays.asList(new Language[]{Language.GERMAN(), Language.RUSSIAN()}), false, null, null, null, null);\r
         Assert.assertEquals("Expecting one entity", Integer.valueOf(1), pager.getCount());\r
-        Assert.assertEquals("Abies balsamea sec. ", pager.getRecords().get(0).getEntity().getTitleCache());\r
+        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());\r
     }\r
 \r
     @SuppressWarnings("rawtypes")\r
@@ -559,7 +642,7 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         DescriptionElementBase textData = descriptionService.getDescriptionElementByUuid(UUID.fromString(descriptionElementUuidStr[0]));\r
 \r
         ((TextData)textData).removeText(Language.GERMAN());\r
-        ((TextData)textData).putText(Language.SPANISH_CASTILIAN(), "abeto balsámico");\r
+        ((TextData)textData).putText(Language.SPANISH_CASTILIAN(), "abeto bals"+UTF8.SMALL_A_ACUTE+"mico");\r
 \r
         descriptionService.saveDescriptionElement(textData);\r
         commitAndStartNewTransaction(null);\r
@@ -571,9 +654,9 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, null, Arrays.asList(new Language[]{Language.GERMAN(), Language.RUSSIAN()}), false, null, null, null, null);\r
         Assert.assertEquals("The german 'Balsam-Tanne' TextData should no longer be indexed", Integer.valueOf(0), pager.getCount());\r
         pager = taxonService.findByDescriptionElementFullText(TextData.class, "abeto", null, null, Arrays.asList(new Language[]{Language.SPANISH_CASTILIAN()}), false, null, null, null, null);\r
-        Assert.assertEquals("expecting to find the SPANISH_CASTILIAN 'abeto balsámico'", Integer.valueOf(1), pager.getCount());\r
-        pager = taxonService.findByDescriptionElementFullText(TextData.class, "balsámico", null, null, null, false, null, null, null, null);\r
-        Assert.assertEquals("expecting to find the SPANISH_CASTILIAN 'abeto balsámico'", Integer.valueOf(1), pager.getCount());\r
+        Assert.assertEquals("expecting to find the SPANISH_CASTILIAN 'abeto bals"+UTF8.SMALL_A_ACUTE+"mico'", Integer.valueOf(1), pager.getCount());\r
+        pager = taxonService.findByDescriptionElementFullText(TextData.class, "bals"+UTF8.SMALL_A_ACUTE+"mico", null, null, null, false, null, null, null, null);\r
+        Assert.assertEquals("expecting to find the SPANISH_CASTILIAN 'abeto bals"+UTF8.SMALL_A_ACUTE+"mico'", Integer.valueOf(1), pager.getCount());\r
 \r
         //\r
         // modify the DescriptionElement via the Description object\r
@@ -582,15 +665,15 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         for( DescriptionElementBase elm : elements){\r
             if(elm.getUuid().toString().equals(descriptionElementUuidStr[0])){\r
                 ((TextData)elm).removeText(Language.SPANISH_CASTILIAN());\r
-                ((TextData)elm).putText(Language.POLISH(), "Jodła balsamiczna");\r
+                ((TextData)elm).putText(Language.POLISH(), "Jod"+UTF8.POLISH_L+"a balsamiczna");\r
             }\r
         }\r
         descriptionService.saveOrUpdate(description);\r
         commitAndStartNewTransaction(null);\r
         pager = taxonService.findByDescriptionElementFullText(TextData.class, "abeto", null, null, Arrays.asList(new Language[]{Language.SPANISH_CASTILIAN()}), false, null, null, null, null);\r
-        Assert.assertEquals("The spanish 'abeto balsámico' TextData should no longer be indexed", Integer.valueOf(0), pager.getCount());\r
+        Assert.assertEquals("The spanish 'abeto bals"+UTF8.SMALL_A_ACUTE+"mico' TextData should no longer be indexed", Integer.valueOf(0), pager.getCount());\r
         pager = taxonService.findByDescriptionElementFullText(TextData.class, "balsamiczna", null, null, Arrays.asList(new Language[]{Language.POLISH()}), false, null, null, null, null);\r
-        Assert.assertEquals("expecting to find the POLISH 'Jodła balsamiczna'", Integer.valueOf(1), pager.getCount());\r
+        Assert.assertEquals("expecting to find the POLISH 'Jod"+UTF8.POLISH_L+"a balsamiczna'", Integer.valueOf(1), pager.getCount());\r
     }\r
 \r
     @SuppressWarnings("rawtypes")\r
@@ -614,6 +697,7 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         taxonService.saveOrUpdate(t_abies_balsamea);\r
         commitAndStartNewTransaction(null);\r
 \r
+        t_abies_balsamea = (Taxon)taxonService.find(t_abies_balsamea.getUuid());\r
 \r
         pager = taxonService.findByDescriptionElementFullText(TextData.class, "Balsam-Tanne", null, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);\r
         Assert.assertEquals("'Balsam-Tanne' should no longer be found", Integer.valueOf(0), pager.getCount());\r
@@ -623,7 +707,7 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         d_abies_balsamea_new\r
                 .addElement(TextData\r
                         .NewInstance(\r
-                                "Die Balsamtanne ist mit bis zu 30 m Höhe ein mittelgroßer Baum und kann bis zu 200 Jahre alt werden",\r
+                                "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",\r
                                 Language.GERMAN(), null));\r
         t_abies_balsamea.addDescription(d_abies_balsamea_new);\r
         // set authorshipCache to null to avoid validation exception,\r
@@ -637,7 +721,7 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
                 "DESCRIPTIONBASE"\r
         });\r
 \r
-        pager = taxonService.findByDescriptionElementFullText(TextData.class, "mittelgroßer Baum", null, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);\r
+        pager = taxonService.findByDescriptionElementFullText(TextData.class, "mittelgro"+UTF8.SHARP_S+"er Baum", null, null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);\r
         Assert.assertEquals("the taxon should be found via the new Description", Integer.valueOf(1), pager.getCount());\r
     }\r
 \r
@@ -668,7 +752,7 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         Assert.assertEquals("expecting default classification", childNode.getClassification().getUuid().toString(), CLASSIFICATION_UUID);\r
 \r
         // moving the taxon around\r
-        alternateClassification.addChildNode(childNode, null, null, null);\r
+        alternateClassification.addChildNode(childNode, null, null);\r
         classificationService.saveOrUpdate(alternateClassification);\r
         commitAndStartNewTransaction(null);\r
 \r
@@ -702,10 +786,10 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
         StateData statedata = StateData.NewInstance(state);\r
         statedata.putModifyingText(Language.ENGLISH(), "always, even during winter");\r
-        cdata.addState(statedata);\r
+        cdata.addStateData(statedata);\r
         d_abies_balsamea.addElement(cdata);\r
 \r
-        termService.save(state);\r
+        UUID termUUID = termService.save(state);\r
         descriptionService.save(d_abies_balsamea);\r
 \r
         commitAndStartNewTransaction(null);\r
@@ -718,9 +802,9 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         Pager<SearchResult<TaxonBase>> pager;\r
         pager = taxonService.findByDescriptionElementFullText(CategoricalData.class, "green", null, null, null, false, null, null, null, null);\r
         Assert.assertEquals("Expecting one entity", Integer.valueOf(1), pager.getCount());\r
-        Assert.assertEquals("Abies balsamea sec. ", pager.getRecords().get(0).getEntity().getTitleCache());\r
+        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getEntity().getTitleCache());\r
         Assert.assertTrue("Expecting only one doc", pager.getRecords().get(0).getDocs().size() == 1);\r
-        Assert.assertEquals("Abies balsamea sec. ", pager.getRecords().get(0).getDocs().iterator().next().get("inDescription.taxon.titleCache"));\r
+        Assert.assertEquals("Abies balsamea sec. Kohlbecker, A., Testcase standart views, 2013", pager.getRecords().get(0).getDocs().iterator().next().get("inDescription.taxon.titleCache"));\r
 \r
 \r
         //TODO modify the StateData\r
@@ -732,8 +816,12 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         taxonService.saveOrUpdate(taxon);\r
         commitAndStartNewTransaction(null);\r
 \r
-        taxon = taxonService.load(taxon.getUuid());\r
+        taxon = taxonService.find(taxon.getUuid());\r
         Assert.assertEquals(newName + " sec. ", taxon.getTitleCache());\r
+        DefinedTermBase term = termService.find(termUUID);\r
+\r
+        termService.delete(term);\r
+\r
     }\r
 \r
     @SuppressWarnings("rawtypes")\r
@@ -783,19 +871,22 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
         refreshLuceneIndex();\r
 \r
+        Classification europeanAbiesClassification = classificationService.find(UUID.fromString(CLASSIFICATION_UUID));\r
+\r
         Pager<SearchResult<TaxonBase>> pager;\r
 \r
         pager = taxonService.findByFullText(null, "Abies", null, null, true, null, null, null, null); // --> 7\r
-        Assert.assertEquals("Expecting 7 entities", Integer.valueOf(7), pager.getCount());\r
+        logSearchResults(pager, Level.DEBUG, null);\r
+        Assert.assertEquals("Expecting 8 entities", Integer.valueOf(8), pager.getCount());\r
 \r
         pager = taxonService.findByFullText(Taxon.class, "Abies", null, null, true, null, null, null, null); // --> 6\r
-        Assert.assertEquals("Expecting 6 entities", Integer.valueOf(6), pager.getCount());\r
+        Assert.assertEquals("Expecting 7 entities", Integer.valueOf(7), pager.getCount());\r
 \r
         pager = taxonService.findByFullText(Synonym.class, "Abies", null, null, true, null, null, null, null); // --> 1\r
         Assert.assertEquals("Expecting 1 entity", Integer.valueOf(1), pager.getCount());\r
 \r
         pager = taxonService.findByFullText(TaxonBase.class, "sec", null, null, true, null, null, null, null); // --> 7\r
-        Assert.assertEquals("Expecting 7 entities", Integer.valueOf(7), pager.getCount());\r
+        Assert.assertEquals("Expecting 8 entities", Integer.valueOf(8), pager.getCount());\r
 \r
         pager = taxonService.findByFullText(null, "genus", null, null, true, null, null, null, null); // --> 1\r
         Assert.assertEquals("Expecting 1 entity", Integer.valueOf(1), pager.getCount());\r
@@ -806,16 +897,239 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         // synonym in classification ???\r
     }\r
 \r
+    @Test\r
+    @DataSet\r
+    public final void testPrepareByAreaSearch() throws IOException, ParseException {\r
+\r
+        List<PresenceAbsenceTerm> statusFilter = new ArrayList<PresenceAbsenceTerm>();\r
+        List<NamedArea> areaFilter = new ArrayList<NamedArea>();\r
+        areaFilter.add(germany);\r
+        areaFilter.add(canada);\r
+        areaFilter.add(russia);\r
+\r
+        Pager<SearchResult<TaxonBase>> pager = taxonService.findByDistribution(areaFilter, statusFilter, null, 20, 0, null, null);\r
+        Assert.assertEquals("Expecting 2 entities", Integer.valueOf(2), Integer.valueOf(pager.getRecords().size()));\r
+\r
+    }\r
+\r
+    @Test\r
+    @DataSet\r
+    public final void testFindTaxaAndNamesByFullText() throws CorruptIndexException, IOException, ParseException, LuceneMultiSearchException {\r
+\r
+        refreshLuceneIndex();\r
+\r
+        Pager<SearchResult<TaxonBase>> pager;\r
+\r
+        Classification alternateClassification = classificationService.find(UUID.fromString(CLASSIFICATION_ALT_UUID));\r
+\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),\r
+                "Abies", null, null, null, null, true, null, null, null, null);\r
+//        logPagerRecords(pager, Level.DEBUG);\r
+        Assert.assertEquals("doTaxa & doSynonyms", Integer.valueOf(8), pager.getCount());\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.allOf(TaxaAndNamesSearchMode.class),\r
+                "Abies", null, null, null, null, true, null, null, null, null);\r
+//        logPagerRecords(pager, Level.DEBUG);\r
+        Assert.assertEquals("all search modes", Integer.valueOf(8), pager.getCount());\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.allOf(TaxaAndNamesSearchMode.class),\r
+                "Abies", alternateClassification, null, null, null, true, null, null, null, null);\r
+//        logPagerRecords(pager, Level.DEBUG);\r
+        Assert.assertEquals("all search modes, filtered by alternateClassification", Integer.valueOf(1), pager.getCount());\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doSynonyms),\r
+                "Abies", null, null, null, null, true, null, null, null, null);\r
+        Assert.assertEquals("Expecting 1 entity", Integer.valueOf(1), pager.getCount());\r
+        SearchResult<TaxonBase> searchResult = pager.getRecords().get(0);\r
+        Assert.assertEquals(Synonym.class, searchResult.getEntity().getClass());\r
+        // Abies subalpina sec. Kohlbecker, A., Testcase standart views, 2013\r
+\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxaByCommonNames),\r
+                "Abies", null, null, null, null, true, null, null, null, null);\r
+        Assert.assertEquals("Expecting 0 entity", Integer.valueOf(0), pager.getCount());\r
+\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxaByCommonNames),\r
+                "Tanne", null, null, null, null, true, null, null, null, null);\r
+        Assert.assertEquals("Expecting 1 entity", Integer.valueOf(1), Integer.valueOf(pager.getRecords().size()));\r
+        Assert.assertEquals("Expecting 1 entity", Integer.valueOf(1), pager.getCount());\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),\r
+                "kawakamii", null, null, null, null, true, null, null, null, null);\r
+        logSearchResults(pager, Level.DEBUG, null);\r
+        Assert.assertEquals("Expecting 1 entity", Integer.valueOf(1), pager.getCount());\r
+\r
+    }\r
+\r
+    @Test\r
+    @DataSet\r
+    public final void testFindTaxaAndNamesByFullText_Sort() throws CorruptIndexException, IOException, ParseException, LuceneMultiSearchException {\r
+\r
+        refreshLuceneIndex();\r
+\r
+        Pager<SearchResult<TaxonBase>> pager;\r
+\r
+        List<OrderHint> orderHints = new ArrayList<OrderHint>();\r
+\r
+        String[] docFields2log = new String[]{"id"};\r
+\r
+        // SortById\r
+        orderHints.addAll(OrderHint.ORDER_BY_ID);\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxa),\r
+                "Abies", null, null, null, null, true, null, null, orderHints, null);\r
+//        logSearchResults(pager, Level.DEBUG, docFields2log);\r
+        int lastId = -1;\r
+        for(SearchResult<TaxonBase> rs : pager.getRecords()){\r
+            if(lastId != -1){\r
+                Assert.assertTrue("results not sorted by id", lastId < rs.getEntity().getId());\r
+            }\r
+            lastId = rs.getEntity().getId();\r
+        }\r
+\r
+        orderHints.addAll(OrderHint.ORDER_BY_ID);\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),\r
+                "Abies", null, null, null, null, true, null, null, orderHints, null);\r
+//        logSearchResults(pager, Level.DEBUG, docFields2log);\r
+\r
+        lastId = -1;\r
+        for(SearchResult<TaxonBase> rs : pager.getRecords()){\r
+            if(lastId != -1){\r
+                Assert.assertTrue("results not sorted by id", lastId < rs.getEntity().getId());\r
+            }\r
+            lastId = rs.getEntity().getId();\r
+        }\r
+\r
+        // Sortby NOMENCLATURAL_SORT_ORDER TODO make assertions !!!\r
+        orderHints.clear();\r
+        orderHints.addAll(OrderHint.NOMENCLATURAL_SORT_ORDER);\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),\r
+                "Abies", null, null, null, null, true, null, null, orderHints, null);\r
+        logSearchResults(pager, Level.DEBUG, null);\r
+\r
+    }\r
+\r
+    @Test\r
+    @DataSet\r
+    public final void testFindTaxaAndNamesByFullText_AreaFilter() throws CorruptIndexException, IOException, ParseException, LuceneMultiSearchException {\r
+\r
+        refreshLuceneIndex();\r
+\r
+        Pager<SearchResult<TaxonBase>> pager;\r
+\r
+        Set<NamedArea> a_germany_canada_russia = new HashSet<NamedArea>();\r
+        a_germany_canada_russia.add(germany);\r
+        a_germany_canada_russia.add(canada);\r
+        a_germany_canada_russia.add(russia);\r
+\r
+        Set<NamedArea> a_russia = new HashSet<NamedArea>();\r
+        a_russia.add(russia);\r
+\r
+        Set<PresenceAbsenceTerm> present = new HashSet<PresenceAbsenceTerm>();\r
+        present.add(PresenceAbsenceTerm.PRESENT());\r
+\r
+        Set<PresenceAbsenceTerm> present_native = new HashSet<PresenceAbsenceTerm>();\r
+        present_native.add(PresenceAbsenceTerm.PRESENT());\r
+        present_native.add(PresenceAbsenceTerm.NATIVE());\r
+\r
+        Set<PresenceAbsenceTerm> absent = new HashSet<PresenceAbsenceTerm>();\r
+        absent.add(PresenceAbsenceTerm.ABSENT());\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxa),\r
+                "Abies", null, a_germany_canada_russia, null, null, true, null, null, null, null);\r
+        logSearchResults(pager, Level.DEBUG, null);\r
+        Assert.assertEquals("taxa with matching area filter", Integer.valueOf(2), pager.getCount());\r
+\r
+        // abies_kawakamii_sensu_komarov as missapplied name for t_abies_balsamea\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doSynonyms),\r
+                "Abies", null, a_germany_canada_russia, present_native, null, true, null, null, null, null);\r
+        Assert.assertEquals("synonyms with matching area filter", Integer.valueOf(1), pager.getCount());\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),\r
+                "Abies", null, a_germany_canada_russia, null, null, true, null, null, null, null);\r
+        logSearchResults(pager, Level.DEBUG, null);\r
+        Assert.assertEquals("taxa and synonyms with matching area filter", Integer.valueOf(3), pager.getCount());\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),\r
+                "Abies", null, a_germany_canada_russia, present_native, null, true, null, null, null, null);\r
+        Assert.assertEquals("taxa and synonyms with matching area & status filter 1", Integer.valueOf(3), pager.getCount());\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),\r
+                "Abies", null, a_germany_canada_russia, present, null, true, null, null, null, null);\r
+        Assert.assertEquals("taxa and synonyms with matching area & status filter 2", Integer.valueOf(2), pager.getCount());\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxa, TaxaAndNamesSearchMode.doSynonyms),\r
+                "Abies", null, a_russia, present, null, true, null, null, null, null);\r
+        Assert.assertEquals("taxa and synonyms with non matching area & status filter", Integer.valueOf(0), pager.getCount());\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doTaxaByCommonNames),\r
+                "Tanne", null, a_germany_canada_russia, present_native, null, true, null, null, null, null);\r
+        Assert.assertEquals("ByCommonNames with area filter", Integer.valueOf(1), pager.getCount());\r
+\r
+        // abies_kawakamii_sensu_komarov as misapplied name for t_abies_balsamea\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),\r
+                "Abies", null, a_germany_canada_russia, present_native, null, true, null, null, null, null);\r
+        Assert.assertEquals("misappliedNames with matching area & status filter", Integer.valueOf(1), pager.getCount());\r
+\r
+\r
+        // 1. remove existing taxon relation\r
+        Taxon t_abies_balsamea = (Taxon)taxonService.find(UUID.fromString(ABIES_BALSAMEA_UUID));\r
+        Set<TaxonRelationship> relsTo = t_abies_balsamea.getRelationsToThisTaxon();\r
+        Assert.assertEquals(Integer.valueOf(1), Integer.valueOf(relsTo.size()));\r
+        TaxonRelationship taxonRelation = relsTo.iterator().next();\r
+        t_abies_balsamea.removeTaxonRelation(taxonRelation);\r
+        taxonService.saveOrUpdate(t_abies_balsamea);\r
+        commitAndStartNewTransaction(null);\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),\r
+                "Abies", null, a_germany_canada_russia, present_native, null, true, null, null, null, null);\r
+        Assert.assertEquals("misappliedNames with matching area & status filter, should match nothing now", Integer.valueOf(0), pager.getCount());\r
+\r
+        // 2. now add abies_kawakamii_sensu_komarov as misapplied name for t_abies_alba and search for misapplications in russia: ABSENT\r
+        Taxon t_abies_kawakamii_sensu_komarov = (Taxon)taxonService.find(UUID.fromString(D_ABIES_KAWAKAMII_SEC_KOMAROV_UUID));\r
+        Taxon t_abies_alba = (Taxon)taxonService.find(UUID.fromString(ABIES_ALBA_UUID));\r
+        t_abies_alba.addMisappliedName(t_abies_kawakamii_sensu_komarov, null, null);\r
+        taxonService.update(t_abies_alba);\r
+        commitAndStartNewTransaction(null);\r
+\r
+        pager = taxonService.findTaxaAndNamesByFullText(\r
+                EnumSet.of(TaxaAndNamesSearchMode.doMisappliedNames),\r
+                "Abies", null, a_germany_canada_russia, absent, null, true, null, null, null, null);\r
+        Assert.assertEquals("misappliedNames with matching area & status filter, should find one", Integer.valueOf(1), pager.getCount());\r
+\r
+    }\r
+\r
     /**\r
      * Regression test for #3119: fulltext search: Entity always null whatever search\r
      *\r
      * @throws CorruptIndexException\r
      * @throws IOException\r
      * @throws ParseException\r
+     * @throws LuceneMultiSearchException\r
      */\r
     @Test\r
     @DataSet\r
-    public final void testFindByEverythingFullText() throws CorruptIndexException, IOException, ParseException {\r
+    public final void testFindByEverythingFullText() throws CorruptIndexException, IOException, ParseException, LuceneMultiSearchException {\r
 \r
         refreshLuceneIndex();\r
 \r
@@ -823,14 +1137,14 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
         // via Taxon\r
         pager = taxonService.findByEverythingFullText("Abies", null, null, true, null, null, null, null);\r
+        logSearchResults(pager, Level.DEBUG, null);\r
         Assert.assertTrue("Expecting at least 7 entities for 'Abies'", pager.getCount() > 7);\r
         Assert.assertNotNull("Expecting entity", pager.getRecords().get(0).getEntity());\r
         Assert.assertEquals("Expecting Taxon entity", Taxon.class, pager.getRecords().get(0).getEntity().getClass());\r
 \r
-        // via DescriptionElement\r
         // via DescriptionElement\r
         pager = taxonService.findByEverythingFullText("present", null, null, true, null, null, null, null);\r
-        Assert.assertEquals("Expecting one entity when searching for arae 'present'", Integer.valueOf(1), pager.getCount());\r
+        Assert.assertEquals("Expecting one entity when searching for area 'present'", Integer.valueOf(1), pager.getCount());\r
         Assert.assertNotNull("Expecting entity", pager.getRecords().get(0).getEntity());\r
         Assert.assertEquals("Expecting Taxon entity", Taxon.class, pager.getRecords().get(0).getEntity().getClass());\r
         Assert.assertEquals("Expecting Taxon ", ABIES_BALSAMEA_UUID, pager.getRecords().get(0).getEntity().getUuid().toString());\r
@@ -840,7 +1154,7 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
     @Test\r
     @DataSet\r
-    public final void findByEveryThingFullText() throws CorruptIndexException, IOException, ParseException {\r
+    public final void findByEveryThingFullText() throws CorruptIndexException, IOException, ParseException, LuceneMultiSearchException {\r
 \r
         refreshLuceneIndex();\r
 \r
@@ -849,8 +1163,10 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         pager = taxonService.findByEverythingFullText("genus", null, null,  false, null, null, null, null); // --> 1\r
         Assert.assertEquals("Expecting 1 entity", Integer.valueOf(1), pager.getCount());\r
 \r
+        //FIXME FAILS: abies balamea is returned twice, see also testFullText_Grouping()\r
         pager = taxonService.findByEverythingFullText("Balsam-Tanne", null, Arrays.asList(new Language[]{Language.GERMAN()}), false, null, null, null, null);\r
-        Assert.assertEquals("expecting to find the GERMAN 'Balsam-Tanne'", Integer.valueOf(1), pager.getCount());\r
+        logSearchResults(pager, Level.DEBUG, null);\r
+        Assert.assertEquals("expecting to find the Abies balsamea via the GERMAN DescriptionElements", Integer.valueOf(1), pager.getCount());\r
 \r
         pager = taxonService.findByEverythingFullText("Abies", null, null, true, null, null, null, null);\r
         Assert.assertEquals("Expecting 8 entities", Integer.valueOf(8), pager.getCount());\r
@@ -860,31 +1176,45 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         Assert.assertTrue("first fragments should contains serch term", fragments[0].toLowerCase().contains("<b>abies</b>"));\r
     }\r
 \r
-    /**\r
-     *\r
-     */\r
-    private void refreshLuceneIndex() {\r
-\r
-//        commitAndStartNewTransaction(null);\r
-        commit();\r
-        endTransaction();\r
-        indexer.purge(null);\r
-        indexer.reindex(DefaultProgressMonitor.NewInstance());\r
-        startNewTransaction();\r
-//        commitAndStartNewTransaction(null);\r
-    }\r
+//    @SuppressWarnings("rawtypes")\r
+//    @Test\r
+//    @DataSet\r
+//    public final void benchmarkFindTaxaAndNamesHql() throws CorruptIndexException, IOException, ParseException {\r
+//\r
+//        createRandomTaxonWithCommonName(NUM_OF_NEW_RADOM_ENTITIES);\r
+//\r
+//        IFindTaxaAndNamesConfigurator configurator = new FindTaxaAndNamesConfiguratorImpl();\r
+//        configurator.setTitleSearchString("Wei"+UTF8.SHARP_S+"%");\r
+//        configurator.setMatchMode(MatchMode.BEGINNING);\r
+//        configurator.setDoTaxa(false);\r
+//        configurator.setDoSynonyms(false);\r
+//        configurator.setDoNamesWithoutTaxa(false);\r
+//        configurator.setDoTaxaByCommonNames(true);\r
+//\r
+//        Pager<IdentifiableEntity> pager;\r
+//\r
+//        long startMillis = System.currentTimeMillis();\r
+//        for (int indx = 0; indx < BENCHMARK_ROUNDS; indx++) {\r
+//            pager = taxonService.findTaxaAndNames(configurator);\r
+//            if (logger.isDebugEnabled()) {\r
+//                logger.debug("[" + indx + "]" + pager.getRecords().get(0).getTitleCache());\r
+//            }\r
+//        }\r
+//        double duration = ((double) (System.currentTimeMillis() - startMillis)) / BENCHMARK_ROUNDS;\r
+//        logger.info("Benchmark result - [find taxon by CommonName via HQL] : " + duration + "ms (" + BENCHMARK_ROUNDS + " benchmark rounds )");\r
+//    }\r
 \r
     @SuppressWarnings("rawtypes")\r
     @Test\r
     @DataSet\r
-    public final void testFindByCommonNameHqlBenchmark() throws CorruptIndexException, IOException, ParseException {\r
+    public final void benchmarkFindByCommonNameHql() throws CorruptIndexException, IOException, ParseException {\r
 \r
 //        printDataSet(System.err, new String[] { "TaxonBase" });\r
 \r
         createRandomTaxonWithCommonName(NUM_OF_NEW_RADOM_ENTITIES);\r
 \r
         IFindTaxaAndNamesConfigurator configurator = new FindTaxaAndNamesConfiguratorImpl();\r
-        configurator.setTitleSearchString("Weiß%");\r
+        configurator.setTitleSearchString("Wei"+UTF8.SHARP_S+"%");\r
         configurator.setMatchMode(MatchMode.BEGINNING);\r
         configurator.setDoTaxa(false);\r
         configurator.setDoSynonyms(false);\r
@@ -907,9 +1237,7 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
     @SuppressWarnings("rawtypes")\r
     @Test\r
     @DataSet\r
-    public final void testFindByCommonNameLuceneBenchmark() throws CorruptIndexException, IOException, ParseException {\r
-\r
-//        printDataSet(System.err, new String[] { "TaxonBase" });\r
+    public final void benchmarkFindByCommonNameLucene() throws CorruptIndexException, IOException, ParseException {\r
 \r
         createRandomTaxonWithCommonName(NUM_OF_NEW_RADOM_ENTITIES);\r
 \r
@@ -919,7 +1247,7 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
         long startMillis = System.currentTimeMillis();\r
         for (int indx = 0; indx < BENCHMARK_ROUNDS; indx++) {\r
-            pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Weiß*", null, null, null, false, null, null, null, null);\r
+            pager = taxonService.findByDescriptionElementFullText(CommonTaxonName.class, "Wei"+UTF8.SHARP_S+"*", null, null, null, false, null, null, null, null);\r
             if (logger.isDebugEnabled()) {\r
                 logger.debug("[" + indx + "]" + pager.getRecords().get(0).getEntity().getTitleCache());\r
             }\r
@@ -928,19 +1256,28 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         logger.info("Benchmark result - [find taxon by CommonName via lucene] : " + duration + "ms (" + BENCHMARK_ROUNDS + " benchmark rounds )");\r
     }\r
 \r
-//    @Test\r
+    /**\r
+     * uncomment @Test annotation to create the dataset for this test\r
+     */\r
+    @Override\r
+    //    @Test\r
     @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="BlankDataSet.xml")\r
-    public final void createDataSet() throws FileNotFoundException {\r
+    public final void createTestDataSet() throws FileNotFoundException {\r
+\r
+        Classification europeanAbiesClassification = Classification.NewInstance("European Abies");\r
+        europeanAbiesClassification.setUuid(UUID.fromString(CLASSIFICATION_UUID));\r
+        classificationService.save(europeanAbiesClassification);\r
 \r
-        Classification classification = Classification.NewInstance("European Abies");\r
-        classification.setUuid(UUID.fromString(CLASSIFICATION_UUID));\r
         Classification alternativeClassification = Classification.NewInstance("Abies alternative");\r
-        classification.setUuid(UUID.fromString(CLASSIFICATION_ALT_UUID));\r
-        classificationService.save(classification);\r
+        alternativeClassification.setUuid(UUID.fromString(CLASSIFICATION_ALT_UUID));\r
         classificationService.save(alternativeClassification);\r
 \r
         Reference<?> sec = ReferenceFactory.newBook();\r
+        sec.setTitleCache("Kohlbecker, A., Testcase standart views, 2013", true);\r
+        Reference<?> sec_sensu = ReferenceFactory.newBook();\r
+        sec_sensu.setTitleCache("Komarov, V. L., Flora SSSR 29", true);\r
         referenceService.save(sec);\r
+        referenceService.save(sec_sensu);\r
 \r
         BotanicalName n_abies = BotanicalName.NewInstance(Rank.GENUS());\r
         n_abies.setNameCache("Abies", true);\r
@@ -950,12 +1287,19 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         BotanicalName n_abies_alba = BotanicalName.NewInstance(Rank.SPECIES());\r
         n_abies_alba.setNameCache("Abies alba", true);\r
         Taxon t_abies_alba = Taxon.NewInstance(n_abies_alba, sec);\r
+        t_abies_alba.setUuid(UUID.fromString(ABIES_ALBA_UUID));\r
         taxonService.save(t_abies_alba);\r
 \r
+        BotanicalName n_abies_subalpina = BotanicalName.NewInstance(Rank.SPECIES());\r
+        n_abies_subalpina.setNameCache("Abies subalpina", true);\r
+        Synonym s_abies_subalpina = Synonym.NewInstance(n_abies_subalpina, sec);\r
+        taxonService.save(s_abies_subalpina);\r
+\r
         BotanicalName n_abies_balsamea = BotanicalName.NewInstance(Rank.SPECIES());\r
         n_abies_balsamea.setNameCache("Abies balsamea", true);\r
         Taxon t_abies_balsamea = Taxon.NewInstance(n_abies_balsamea, sec);\r
         t_abies_balsamea.setUuid(UUID.fromString(ABIES_BALSAMEA_UUID));\r
+        t_abies_balsamea.addSynonym(s_abies_subalpina, SynonymRelationshipType.SYNONYM_OF());\r
         taxonService.save(t_abies_balsamea);\r
 \r
         BotanicalName n_abies_grandis = BotanicalName.NewInstance(Rank.SPECIES());\r
@@ -969,57 +1313,111 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         t_abies_kawakamii.getTitleCache();\r
         taxonService.save(t_abies_kawakamii);\r
 \r
-        BotanicalName n_abies_subalpina = BotanicalName.NewInstance(Rank.SPECIES());\r
-        n_abies_subalpina.setNameCache("Abies subalpina", true);\r
-        Synonym s_abies_subalpina = Synonym.NewInstance(n_abies_subalpina, sec);\r
-        taxonService.save(s_abies_subalpina);\r
+        // abies_kawakamii_sensu_komarov as missapplied name for t_abies_balsamea\r
+        Taxon t_abies_kawakamii_sensu_komarov = Taxon.NewInstance(n_abies_kawakamii, sec_sensu);\r
+        taxonService.save(t_abies_kawakamii_sensu_komarov);\r
+        t_abies_kawakamii_sensu_komarov.addTaxonRelation(t_abies_balsamea, TaxonRelationshipType.MISAPPLIED_NAME_FOR(), null, null);\r
+        taxonService.saveOrUpdate(t_abies_kawakamii_sensu_komarov);\r
 \r
         BotanicalName n_abies_lasiocarpa = BotanicalName.NewInstance(Rank.SPECIES());\r
         n_abies_lasiocarpa.setNameCache("Abies lasiocarpa", true);\r
         Taxon t_abies_lasiocarpa = Taxon.NewInstance(n_abies_lasiocarpa, sec);\r
-        t_abies_lasiocarpa.addSynonym(s_abies_subalpina, SynonymRelationshipType.SYNONYM_OF());\r
         taxonService.save(t_abies_lasiocarpa);\r
 \r
         // add taxa to classifications\r
-        classification.addChildTaxon(t_abies_balsamea, null, null, null);\r
-        alternativeClassification.addChildTaxon(t_abies_lasiocarpa, null, null, null);\r
-        classificationService.saveOrUpdate(classification);\r
+        europeanAbiesClassification.addChildTaxon(t_abies_balsamea, null, null);\r
+        alternativeClassification.addChildTaxon(t_abies_lasiocarpa, null, null);\r
+        classificationService.saveOrUpdate(europeanAbiesClassification);\r
         classificationService.saveOrUpdate(alternativeClassification);\r
 \r
         //\r
         // Description\r
         //\r
         TaxonDescription d_abies_alba = TaxonDescription.NewInstance(t_abies_alba);\r
+        TaxonDescription d_abies_balsamea = TaxonDescription.NewInstance(t_abies_balsamea);\r
+\r
+        d_abies_alba.setUuid(UUID.fromString(D_ABIES_ALBA_UUID));\r
+        d_abies_balsamea.setUuid(UUID.fromString(D_ABIES_BALSAMEA_UUID));\r
+\r
 \r
-        d_abies_alba.setUuid(UUID.fromString(D_ABIES_BALSAMEA_UUID));\r
         // CommonTaxonName\r
-        d_abies_alba.addElement(CommonTaxonName.NewInstance("Weißtanne", Language.GERMAN()));\r
+        d_abies_alba.addElement(CommonTaxonName.NewInstance("Wei"+UTF8.SHARP_S+"tanne", Language.GERMAN()));\r
         d_abies_alba.addElement(CommonTaxonName.NewInstance("silver fir", Language.ENGLISH()));\r
+        d_abies_alba.addElement(Distribution\r
+                .NewInstance(\r
+                        germany,\r
+                        PresenceAbsenceTerm.NATIVE()));\r
+        d_abies_alba.addElement(Distribution\r
+                .NewInstance(\r
+                        russia,\r
+                        PresenceAbsenceTerm.ABSENT()));\r
+\r
         // TextData\r
-        TaxonDescription d_abies_balsamea = TaxonDescription.NewInstance(t_abies_balsamea);\r
         d_abies_balsamea\r
             .addElement(TextData\r
                     .NewInstance(\r
-                            "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.",\r
+                            "Die Balsam-Tanne (Abies balsamea) ist eine Pflanzenart aus der Gattung der Tannen (Abies). Sie wÃ\83¤chst im nordÃ\83¶stlichen Nordamerika, wo sie sowohl Tief- als auch Bergland besiedelt. Sie gilt als relativ anspruchslos gegenÃ\83¼ber dem Standort und ist frosthart. In vielen Teilen des natÃ\83¼rlichen Verbreitungsgebietes stellt sie die Klimaxbaumart dar.",\r
                             Language.GERMAN(), null));\r
+        d_abies_balsamea\r
+        .addElement(CommonTaxonName\r
+                .NewInstance(\r
+                        "Balsam-Tanne",\r
+                        Language.GERMAN(), null));\r
+\r
+        d_abies_balsamea\r
+        .addElement(Distribution\r
+                .NewInstance(\r
+                        canada,\r
+                        PresenceAbsenceTerm.PRESENT()));\r
+\r
+        d_abies_balsamea\r
+        .addElement(Distribution\r
+                .NewInstance(\r
+                        germany,\r
+                        PresenceAbsenceTerm.NATIVE()));\r
+\r
         d_abies_balsamea\r
                 .addElement(TextData\r
                         .NewInstance(\r
-                                "Бальзам ньыв (лат. Abies balsamea) – быдмассэзлӧн пожум котырись ньыв увтырын торья вид. Ньывпуыс быдмӧ 14–20 метра вылына да овлӧ 10–60 см кыза диаметрын. Ньывпу пантасьӧ Ойвыв Америкаын.",\r
+                                       TaxonServiceSearchTestUtf8Constants.RUSSIAN_ABIES_ALBA_LONG,\r
                                 Language.RUSSIAN(), null));\r
+        d_abies_balsamea\r
+        .addElement(CommonTaxonName\r
+                .NewInstance(\r
+                               TaxonServiceSearchTestUtf8Constants.RUSSIAN_ABIES_ALBA_SHORT,\r
+                        Language.RUSSIAN(), null));\r
+        descriptionService.saveOrUpdate(d_abies_balsamea);\r
+\r
         setComplete();\r
         endTransaction();\r
 \r
 \r
         writeDbUnitDataSetFile(new String[] {\r
-            "TAXONBASE", "TAXONNAMEBASE", "SYNONYMRELATIONSHIP",\r
+            "TAXONBASE", "TAXONNAMEBASE",\r
+            "SYNONYMRELATIONSHIP", "TAXONRELATIONSHIP",\r
             "REFERENCE", "DESCRIPTIONELEMENTBASE", "DESCRIPTIONBASE",\r
             "AGENTBASE", "HOMOTYPICALGROUP",\r
-            "CLASSIFICATION", "CLASSIFICATION_TAXONNODE","TAXONNODE",\r
-            "LANGUAGESTRING", "DESCRIPTIONELEMENTBASE_LANGUAGESTRING" });\r
+            "CLASSIFICATION", "TAXONNODE",\r
+            "LANGUAGESTRING", "DESCRIPTIONELEMENTBASE_LANGUAGESTRING",\r
+            "HIBERNATE_SEQUENCES" // IMPORTANT!!!\r
+            });\r
 \r
     }\r
 \r
+    /**\r
+     *\r
+     */\r
+    private void refreshLuceneIndex() {\r
+\r
+//        commitAndStartNewTransaction(null);\r
+        commit();\r
+        endTransaction();\r
+        indexer.purge(DefaultProgressMonitor.NewInstance());\r
+        indexer.reindex(typesToIndex, DefaultProgressMonitor.NewInstance());\r
+        startNewTransaction();\r
+//        commitAndStartNewTransaction(null);\r
+    }\r
+\r
     /**\r
      * @param numberOfNew\r
      *\r
@@ -1028,6 +1426,8 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
 \r
         logger.debug(String.format("creating %1$s random taxan with CommonName", numberOfNew));\r
 \r
+        commitAndStartNewTransaction(null);\r
+\r
         Reference sec = ReferenceFactory.newBook();\r
         referenceService.save(sec);\r
 \r
@@ -1047,7 +1447,46 @@ public class TaxonServiceSearchTest extends CdmTransactionalIntegrationTest {
         }\r
 \r
         commitAndStartNewTransaction(null);\r
+    }\r
+\r
+    private <T extends CdmBase> void logSearchResults(Pager<SearchResult<T>> pager, Level level, String[] docFields){\r
+        if(level == null){\r
+            level = Level.DEBUG;\r
+        }\r
+        if(logger.isEnabledFor(level)){\r
+            StringBuilder b = new StringBuilder();\r
+            b.append("\n");\r
+            int i = 0;\r
+            for(SearchResult sr : pager.getRecords()){\r
+\r
+                b.append(" ").append(i++).append(" - ");\r
+                b.append("score:").append(sr.getScore()).append(", ");\r
+\r
+                if(docFields != null){\r
+                    b.append("docs : ");\r
+                    for(Document doc : sr.getDocs()) {\r
+                        b.append("<");\r
+                        for(String f : docFields){\r
+                            b.append(f).append(":").append(Arrays.toString(doc.getValues(f)));\r
+                        }\r
+                        b.append(">");\r
+                    }\r
+                }\r
 \r
+                CdmBase entity = sr.getEntity();\r
+                if(entity == null){\r
+                    b.append("NULL");\r
+                } else {\r
+                    b.append(entity.getClass().getSimpleName()).\r
+                        append(" [").append(entity.getId()).\r
+                        append(" | ").append(entity.getUuid()).append("] : ").\r
+                        append(entity.toString());\r
+\r
+                }\r
+                b.append("\n");\r
+            }\r
+            logger.log(level, b);\r
+        }\r
     }\r
 \r
 }\r