ref #7443, ref #10432 add formatting and partly parsing for name in-authors
authorAndreas Müller <a.mueller@bgbm.org>
Tue, 16 Jan 2024 12:28:36 +0000 (13:28 +0100)
committerAndreas Müller <a.mueller@bgbm.org>
Tue, 16 Jan 2024 12:28:36 +0000 (13:28 +0100)
cdmlib-model/src/main/java/eu/etaxonomy/cdm/strategy/cache/name/TaxonNameDefaultCacheStrategy.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/strategy/parser/NonViralNameParserImplRegExBase.java
cdmlib-model/src/test/java/eu/etaxonomy/cdm/strategy/cache/name/TaxonNameDefaultCacheStrategyTest.java

index c913df75ab1c5650e362bdcf150f78d08ef8b8e0..4dfeeb70a76c586e42b379631af3d4bbe22d1300 100644 (file)
@@ -24,6 +24,7 @@ import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
 import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.model.name.HybridRelationship;
 import eu.etaxonomy.cdm.model.name.INonViralName;
+import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
 import eu.etaxonomy.cdm.model.name.Rank;
 import eu.etaxonomy.cdm.model.name.TaxonName;
 import eu.etaxonomy.cdm.strategy.cache.TagEnum;
@@ -57,6 +58,7 @@ public class TaxonNameDefaultCacheStrategy
     private String basionymStart = "(";
     private String basionymEnd = ")";
     private String exAuthorSeperator = " ex ";
+    private String inAuthorSeperator = " in ";
     private CharSequence basionymAuthorCombinationAuthorSeperator = " ";
 
     private String zooAuthorYearSeperator = ", ";
@@ -185,6 +187,13 @@ public class TaxonNameDefaultCacheStrategy
             TeamOrPersonBase<?> exCombinationAuthor = nonViralName.getExCombinationAuthorship();
             TeamOrPersonBase<?> basionymAuthor = nonViralName.getBasionymAuthorship();
             TeamOrPersonBase<?> exBasionymAuthor = nonViralName.getExBasionymAuthorship();
+            TeamOrPersonBase<?> inCombinationAuthor = null;
+            TeamOrPersonBase<?> inBasionymAuthor = null;
+            if (nonViralName.getNameType() == NomenclaturalCode.Fungi) {
+                //for now we format only fungi (and zoonames, but not here) with in-authors
+                inCombinationAuthor = nonViralName.getInCombinationAuthorship();
+                inBasionymAuthor = nonViralName.getInBasionymAuthorship();
+            }
             if (isCultivar(nonViralName) ){
                 exCombinationAuthor = null;
                 basionymAuthor = null;
@@ -194,11 +203,11 @@ public class TaxonNameDefaultCacheStrategy
             String basionymPart = "";
             String authorPart = "";
             //basionym
-            if (basionymAuthor != null || exBasionymAuthor != null){
-                basionymPart = basionymStart + getAuthorAndExAuthor(basionymAuthor, exBasionymAuthor) + basionymEnd;
+            if (basionymAuthor != null || exBasionymAuthor != null || inBasionymAuthor != null){
+                basionymPart = basionymStart + getAuthorAndExAndInAuthor(basionymAuthor, exBasionymAuthor, inBasionymAuthor) + basionymEnd;
             }
-            if (combinationAuthor != null || exCombinationAuthor != null){
-                authorPart = getAuthorAndExAuthor(combinationAuthor, exCombinationAuthor);
+            if (combinationAuthor != null || exCombinationAuthor != null || inCombinationAuthor != null){
+                authorPart = getAuthorAndExAndInAuthor(combinationAuthor, exCombinationAuthor, inCombinationAuthor);
             }
             result = CdmUtils.concat(basionymAuthorCombinationAuthorSeperator, basionymPart, authorPart);
 //          if ("".equals(result)){
@@ -221,6 +230,8 @@ public class TaxonNameDefaultCacheStrategy
         TeamOrPersonBase<?> exCombinationAuthor = nonViralName.getExCombinationAuthorship();
         TeamOrPersonBase<?> basionymAuthor = nonViralName.getBasionymAuthorship();
         TeamOrPersonBase<?> exBasionymAuthor = nonViralName.getExBasionymAuthorship();
+        TeamOrPersonBase<?> inCombinationAuthor = nonViralName.getInCombinationAuthorship();
+        TeamOrPersonBase<?> inBasionymAuthor = nonViralName.getInBasionymAuthorship();
         Integer publicationYear = nonViralName.getPublicationYear();
         Integer originalPublicationYear = nonViralName.getOriginalPublicationYear();
 
@@ -228,13 +239,13 @@ public class TaxonNameDefaultCacheStrategy
         String authorPart = "";
         //basionym
         if (basionymAuthor != null || exBasionymAuthor != null || originalPublicationYear != null ){
-            String authorAndEx = getAuthorAndExAuthor(basionymAuthor, exBasionymAuthor);
+            String authorAndEx = getAuthorAndExAndInAuthor(basionymAuthor, exBasionymAuthor, inBasionymAuthor);
             String originalPublicationYearString = originalPublicationYear == null ? null : String.valueOf(originalPublicationYear);
             String authorAndExAndYear = CdmUtils.concat(zooAuthorYearSeperator, authorAndEx, originalPublicationYearString );
             basionymPart = basionymStart + authorAndExAndYear + basionymEnd;
         }
         if (combinationAuthor != null || exCombinationAuthor != null){
-            String authorAndEx = getAuthorAndExAuthor(combinationAuthor, exCombinationAuthor);
+            String authorAndEx = getAuthorAndExAndInAuthor(combinationAuthor, exCombinationAuthor, inCombinationAuthor);
             String publicationYearString = publicationYear == null ? null : String.valueOf(publicationYear);
             authorPart = CdmUtils.concat(zooAuthorYearSeperator, authorAndEx, publicationYearString);
         }
@@ -251,18 +262,23 @@ public class TaxonNameDefaultCacheStrategy
      * combination authors as well as on basionym/orginal combination authors.
      * The correct order is exAuthor ex author though some botanist do not know about and do it the
      * other way round. (see 46.4-46.6 ICBN (Vienna Code, 2006))
+     * @param inAuthor
      */
-    protected String getAuthorAndExAuthor(TeamOrPersonBase<?> author, TeamOrPersonBase<?> exAuthor){
+    protected String getAuthorAndExAndInAuthor(TeamOrPersonBase<?> author, TeamOrPersonBase<?> exAuthor, TeamOrPersonBase<?> inAuthor){
         String authorString = "";
         String exAuthorString = "";
+        String inAuthorString = "";
         if (author != null){
             authorString = getNomAuthorTitle(author);
         }
         if (exAuthor != null){
             exAuthorString = getNomAuthorTitle(exAuthor);
-            exAuthorString += exAuthorSeperator;
         }
-        String result = exAuthorString + authorString;
+        if (inAuthor != null){
+            inAuthorString = getNomAuthorTitle(inAuthor);
+        }
+        String result = CdmUtils.concat(inAuthorSeperator,
+                CdmUtils.concat(exAuthorSeperator, exAuthorString, authorString), inAuthorString);
         return result;
     }
 
index 431fc542d2373b515ce2a536d2cfadc5e988612a..1610fd0a475b6c8de90b8155d98ac2a84f007d27 100644 (file)
@@ -104,7 +104,8 @@ public abstract class NonViralNameParserImplRegExBase  {
     protected static String author = "((" + authorPart + "(" + fWs + "|-)" + ")+" + "(f(il)?\\.|secundus|jun\\.|ter|bis)?|Man in "+qm+"t Veld|Sant"+qm+"Anna)" ;
     protected static String finalTeamSplitter = "(" + fWs + "(&)" + fWs + "|" + oWs + "et" + oWs + ")";
     protected static String notFinalTeamSplitter = "(?:" + fWs + "," + fWs + "|" + finalTeamSplitter + ")";
-    protected static String authorTeam = fWs + "(((?>" + author + notFinalTeamSplitter + ")*" + author + finalTeamSplitter + ")?(?:"  + author + "|al\\.)|hort\\.)" +  fWs;
+    //temp. public for CoraTaxonImport #10432, can be removed once in-authors are included in general parser
+    public static String authorTeam = fWs + "(((?>" + author + notFinalTeamSplitter + ")*" + author + finalTeamSplitter + ")?(?:"  + author + "|al\\.)|hort\\.)" +  fWs;
     protected static String exString = "(ex\\.?)";
     protected static String authorAndExTeam = "(" + authorTeam + oWs + exString + oWs + ")?" + authorTeam;
     protected static String basStart = "\\(";
index e1ad635bf3b89e94d5c4f58245b7b9ba9da6a7ac..c6745e1d701c51b1815d879dd5ac05f4dce258d8 100644 (file)
@@ -29,6 +29,7 @@ import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
 import eu.etaxonomy.cdm.model.name.IBotanicalName;
 import eu.etaxonomy.cdm.model.name.INonViralName;
 import eu.etaxonomy.cdm.model.name.IZoologicalName;
+import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
 import eu.etaxonomy.cdm.model.name.Rank;
@@ -61,8 +62,10 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
 
     private static final String authorString = "L.";
     private static final String exAuthorString = "Exaut.";
+    private static final String inAuthorString = "Inaut. B.";
     private static final String basAuthorString = "Basio, A.";
     private static final String exBasAuthorString = "ExBas. N.";
+    private static final String inBasAuthorString = "Inbas., C.";
 
     private static final String referenceTitle = "My Reference";
 
@@ -73,8 +76,10 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
     private TaxonName subSpeciesName;
     private TeamOrPersonBase<?> author;
     private TeamOrPersonBase<?> exAuthor;
+    private TeamOrPersonBase<?> inAuthor;
     private TeamOrPersonBase<?> basAuthor;
     private TeamOrPersonBase<?> exBasAuthor;
+    private TeamOrPersonBase<?> inBasAuthor;
     private Reference citationRef;
 
     @Before
@@ -93,11 +98,15 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         author = Person.NewInstance();
         author.setNomenclaturalTitleCache(authorString, true);
         exAuthor = Person.NewInstance();
-        exAuthor.setNomenclaturalTitleCache(exAuthorString, true);
+        exAuthor.setNomenclaturalTitleCache(inAuthorString, true);
+        inAuthor = Person.NewInstance();
+        inAuthor.setNomenclaturalTitleCache(inAuthorString, true);
         basAuthor = Person.NewInstance();
         basAuthor.setNomenclaturalTitleCache(basAuthorString, true);
         exBasAuthor = Person.NewInstance();
         exBasAuthor.setNomenclaturalTitleCache(exBasAuthorString, true);
+        inBasAuthor = Person.NewInstance();
+        inBasAuthor.setNomenclaturalTitleCache(inBasAuthorString, true);
 
         citationRef = ReferenceFactory.newGeneric();
         citationRef.setTitle(referenceTitle);
@@ -858,4 +867,32 @@ public class TaxonNameDefaultCacheStrategyTest extends NameCacheStrategyTestBase
         Assert.assertEquals("", "Ophrys kastelli (Mill. & al.) Mill. & al.", formatter.getTitleCache(name));
 
     }
+
+    @Test  //#7443
+    public void testInAuthors() {
+        //base configuration
+        speciesName.setCombinationAuthorship(author);
+        speciesName.setBasionymAuthorship(basAuthor);
+        String expectedWithoutInAuthor = speciesNameString + " (" + basAuthorString + ") " + authorString;
+        Assert.assertEquals(expectedWithoutInAuthor, speciesName.getTitleCache());
+
+        //with in-authors
+        speciesName.setNameType(NomenclaturalCode.Fungi);
+        speciesName.setInBasionymAuthorship(inBasAuthor);
+        speciesName.setInCombinationAuthorship(inAuthor);
+        String expectedWithInAuthor = speciesNameString + " (" + basAuthorString + " in "+inBasAuthorString+") " + authorString + " in "+inAuthorString;
+        speciesName.setTitleCache(null, false);
+        Assert.assertEquals(expectedWithInAuthor, speciesName.getTitleCache());
+
+        //... for zoo-names
+        speciesName.setNameType(NomenclaturalCode.ICZN);
+        speciesName.setTitleCache(null, false);
+        Assert.assertEquals(expectedWithInAuthor, speciesName.getTitleCache());
+
+        //... for botanical names
+        speciesName.setNameType(NomenclaturalCode.ICNAFP);
+        speciesName.setTitleCache(null, false);
+        Assert.assertEquals("For now we do not allow in-authors for botanical names (except for fungi)",
+                expectedWithoutInAuthor, speciesName.getTitleCache());
+    }
 }
\ No newline at end of file