Import nomenclatural status
[cdmlib-apps.git] / app-import / src / main / java / eu / etaxonomy / cdm / io / redlist / gefaesspflanzen / RedListGefaesspflanzenImportNames.java
index a474c857f9f74057d078646aad0d6a5a359b8758..5468f6fe42926f4cd277eeecae7bbf1415d293fd 100644 (file)
@@ -20,17 +20,22 @@ import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
 import eu.etaxonomy.cdm.common.CdmUtils;
-import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
 import eu.etaxonomy.cdm.io.common.DbImportBase;
 import eu.etaxonomy.cdm.io.common.IPartitionedIO;
 import eu.etaxonomy.cdm.io.common.ImportHelper;
 import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;
 import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
+import eu.etaxonomy.cdm.model.agent.AgentBase;
 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
 import eu.etaxonomy.cdm.model.common.CdmBase;
 import eu.etaxonomy.cdm.model.name.BotanicalName;
+import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
+import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
 import eu.etaxonomy.cdm.model.name.Rank;
 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
+import eu.etaxonomy.cdm.model.taxon.Synonym;
+import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;
 
 /**
  *
@@ -42,14 +47,13 @@ import eu.etaxonomy.cdm.model.name.TaxonNameBase;
 @Component
 @SuppressWarnings("serial")
 public class RedListGefaesspflanzenImportNames extends DbImportBase<RedListGefaesspflanzenImportState, RedListGefaesspflanzenImportConfigurator> {
+
     private static final Logger logger = Logger.getLogger(RedListGefaesspflanzenImportNames.class);
 
     private static final String tableName = "Rote Liste Gefäßpflanzen";
 
     private static final String pluralString = "names";
 
-    private static final String NAME_NAMESPACE = "name";
-
     public RedListGefaesspflanzenImportNames() {
         super(tableName, pluralString);
     }
@@ -80,9 +84,10 @@ public class RedListGefaesspflanzenImportNames extends DbImportBase<RedListGefae
     public boolean doPartition(ResultSetPartitioner partitioner, RedListGefaesspflanzenImportState state) {
         ResultSet rs = partitioner.getResultSet();
         Set<TaxonNameBase> namesToSave = new HashSet<TaxonNameBase>();
+        Set<TaxonBase> taxaToSave = new HashSet<TaxonBase>();
         try {
             while (rs.next()){
-                makeSingleName(state, rs, namesToSave);
+                makeSingleNameAndTaxon(state, rs, namesToSave, taxaToSave);
 
             }
         } catch (SQLException e) {
@@ -90,55 +95,168 @@ public class RedListGefaesspflanzenImportNames extends DbImportBase<RedListGefae
         }
 
         getNameService().saveOrUpdate(namesToSave);
+        getTaxonService().saveOrUpdate(taxaToSave);
         return true;
     }
 
-    private void makeSingleName(RedListGefaesspflanzenImportState state, ResultSet rs, Set<TaxonNameBase> namesToSave)
+    private void makeSingleNameAndTaxon(RedListGefaesspflanzenImportState state, ResultSet rs, Set<TaxonNameBase> namesToSave, Set<TaxonBase> taxaToSave)
             throws SQLException {
-        long id = rs.getLong("NAMNR");
-        String taxNameString = rs.getString("TAXNAME");
-        String rangString = rs.getString("RANG");
-        String ep1String = rs.getString("EPI1");
-        String ep2String = rs.getString("EPI2");
-        String ep3String = rs.getString("EPI3");
-        String nomZusatzString = rs.getString("NOM_ZUSATZ");
-        String zusatzString = rs.getString("ZUSATZ");
-        String authorKombString = rs.getString("AUTOR_KOMB");
-        String authorBasiString = rs.getString("AUTOR_BASI");
-
+        long id = rs.getLong(RedListUtil.NAMNR);
+        String taxNameString = rs.getString(RedListUtil.TAXNAME);
+        String gueltString = rs.getString(RedListUtil.GUELT);
+        String rangString = rs.getString(RedListUtil.RANG);
+        String ep1String = rs.getString(RedListUtil.EPI1);
+        String ep2String = rs.getString(RedListUtil.EPI2);
+        String ep3String = rs.getString(RedListUtil.EPI3);
+        String nomZusatzString = rs.getString(RedListUtil.NOM_ZUSATZ);
+        String zusatzString = rs.getString(RedListUtil.ZUSATZ);
+        String authorKombString = rs.getString(RedListUtil.AUTOR_KOMB);
+        String authorBasiString = rs.getString(RedListUtil.AUTOR_BASI);
+
+        //---NAME---
         if(CdmUtils.isBlank(taxNameString) && CdmUtils.isBlank(ep1String)){
-            logger.error("NAMNR: "+id+" No name found!");
+            RedListUtil.logMessage(id, "No name found!", logger);
         }
 
-
-        Rank rank = makeRank(state, rangString);
+        Rank rank = makeRank(id, state, rangString);
+        if(rank==null){
+            RedListUtil.logMessage(id, "Rank could not be resolved.", logger);
+        }
         BotanicalName name = BotanicalName.NewInstance(rank);
 
         //ep1 should always be present
+        if(CdmUtils.isBlank(ep1String)){
+            RedListUtil.logMessage(id, RedListUtil.EPI1+" is empty!", logger);
+        }
         name.setGenusOrUninomial(ep1String);
-        if(rank==Rank.SPECIES()){
-            name.setGenusOrUninomial(ep1String);
+        if(!CdmUtils.isBlank(ep2String)){
+            name.setSpecificEpithet(ep2String);
+        }
+        if(!CdmUtils.isBlank(ep3String)){
+            if(rank==Rank.SUBSPECIES() ||
+                    rank==Rank.VARIETY()){
+                name.setInfraSpecificEpithet(ep3String);
+            }
+        }
+        //nomenclatural status
+        NomenclaturalStatusType status = makeNomenclaturalStatus(id, state, nomZusatzString);
+        if(status!=null){
+            name.addStatus(NomenclaturalStatus.NewInstance(status));
         }
 
-        //add author
-        TeamOrPersonBase authorKomb = HibernateProxyHelper.deproxy(getAgentService().load(state.getAuthorMap().get(authorKombString)), TeamOrPersonBase.class);
-        name.setCombinationAuthorship(authorKomb);
-        TeamOrPersonBase authorBasi = HibernateProxyHelper.deproxy(getAgentService().load(state.getAuthorMap().get(authorBasiString)), TeamOrPersonBase.class);
-        name.setBasionymAuthorship(authorBasi);
+
+        //--- AUTHORS ---
+        //combination author
+        if(authorKombString.contains(RedListUtil.EX)){
+            //TODO: what happens with multiple ex authors??
+            String[] kombSplit = authorKombString.split(RedListUtil.EX);
+            if(kombSplit.length!=2){
+                RedListUtil.logMessage(id, "Multiple ex combination authors found", logger);
+            }
+            for (int i = 0; i < kombSplit.length; i++) {
+                if(i==0){
+                    //first author is ex author
+                    TeamOrPersonBase authorKomb = (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, kombSplit[i]);
+                    name.setExCombinationAuthorship(authorKomb);
+                }
+                else{
+                    TeamOrPersonBase authorKomb = (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, kombSplit[i]);
+                    name.setCombinationAuthorship(authorKomb);
+                }
+            }
+        }
+        else if(authorKombString.trim().equals(RedListUtil.AUCT)){
+            RedListUtil.logMessage(id, "AUCT information in "+RedListUtil.AUTOR_KOMB+" column", logger);
+        }
+        else if(!CdmUtils.isBlank(authorKombString)){
+            TeamOrPersonBase authorKomb = (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, authorKombString);
+            name.setCombinationAuthorship(authorKomb);
+        }
+        //basionym author
+        if(authorBasiString.contains(RedListUtil.EX)){
+            String[] basiSplit = authorBasiString.split(RedListUtil.EX);
+            for (int i = 0; i < basiSplit.length; i++) {
+                if(basiSplit.length!=2){
+                    RedListUtil.logMessage(id, "Multiple ex basionymn authors found", logger);
+                }
+                if(i==0){
+                    TeamOrPersonBase authorBasi= (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, basiSplit[i]);
+                    if(CdmUtils.isBlank(authorKombString)){
+                        name.setExCombinationAuthorship(authorBasi);
+                    }
+                    else{
+                        name.setExBasionymAuthorship(authorBasi);
+                    }
+                }
+                else{
+                    TeamOrPersonBase authorBasi= (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, basiSplit[i]);
+                    if(CdmUtils.isBlank(authorKombString)){
+                        name.setCombinationAuthorship(authorBasi);
+                    }
+                    else{
+                        name.setBasionymAuthorship(authorBasi);
+                    }
+                }
+            }
+        }
+        else if(authorBasiString.trim().equals(RedListUtil.AUCT)){
+            name.setAppendedPhrase(authorBasiString);
+        }
+        else if(!CdmUtils.isBlank(authorBasiString)){
+            //this seems to be a convention in the source database: When there is only a single author then only the "AUTOR_BASI" column is used
+            TeamOrPersonBase authorBasi= (TeamOrPersonBase) state.getRelatedObject(RedListUtil.AUTHOR_NAMESPACE, authorBasiString);
+            if(CdmUtils.isBlank(authorKombString)){
+                name.setCombinationAuthorship(authorBasi);
+            }
+            else{
+                name.setBasionymAuthorship(authorBasi);
+            }
+        }
 
         //check authorship consistency
-        String authorString = rs.getString("AUTOR");
-        if(!authorString.equals(name.getAuthorshipCache())){
-            logger.warn("Authorship inconsisten! Name-AuthorhshipCache: +"+name.getAuthorshipCache()+" Column AUTOR: "+authorString);
+        String authorString = rs.getString(RedListUtil.AUTOR);
+        String authorshipCache = name.getAuthorshipCache();
+
+        if(!CdmUtils.isBlank(zusatzString)){
+            authorString = authorString.replace(", "+zusatzString, "");
+        }
+//        if(CdmUtils.isBlank(authorKombString) && !CdmUtils.isBlank(authorBasiString)){
+//            authorString = "("+authorString+")";
+//        }
+        if(authorString.equals(RedListUtil.AUCT)){
+            authorString = "";
+        }
+        if(!authorString.equals(authorshipCache)){
+            RedListUtil.logMessage(id, "Authorship inconsistent! name.authorhshipCache <-> Column "+RedListUtil.AUTOR+": "+authorshipCache+" <-> "+authorString, logger);
         }
 
         //id
-        ImportHelper.setOriginalSource(name, state.getTransactionalSourceReference(), id, NAME_NAMESPACE);
+        ImportHelper.setOriginalSource(name, state.getTransactionalSourceReference(), id, RedListUtil.NAME_NAMESPACE);
+        state.getNameMap().put(id, name.getUuid());
 
         namesToSave.add(name);
+
+        //---TAXON---
+        TaxonBase taxonBase = null;
+        if(gueltString.equals(RedListUtil.GUELT_ACCEPTED_TAXON) || (name.getAppendedPhrase()!=null && name.getAppendedPhrase().equals(RedListUtil.AUCT))){
+            taxonBase = Taxon.NewInstance(name, null);
+        }
+        else if(gueltString.equals(RedListUtil.GUELT_SYNONYM) || gueltString.equals(RedListUtil.GUELT_BASIONYM)){
+            taxonBase = Synonym.NewInstance(name, null);
+        }
+        if(taxonBase==null){
+            RedListUtil.logMessage(id, "Taxon for name "+name+" could not be created.", logger);
+            return;
+        }
+
+        taxaToSave.add(taxonBase);
+
+        //id
+        ImportHelper.setOriginalSource(taxonBase, state.getTransactionalSourceReference(), id, RedListUtil.TAXON_NAMESPACE);
+        state.getTaxonMap().put(id, taxonBase.getUuid());
     }
 
-    private Rank makeRank(RedListGefaesspflanzenImportState state, String rankStr) {
+    private Rank makeRank(long id, RedListGefaesspflanzenImportState state, String rankStr) {
         Rank rank = null;
         try {
             rank = state.getTransformer().getRankByKey(rankStr);
@@ -146,65 +264,66 @@ public class RedListGefaesspflanzenImportNames extends DbImportBase<RedListGefae
             e.printStackTrace();
         }
         if(rank==null){
-            logger.error(rankStr+" could not be associated to a known rank.");
+            RedListUtil.logMessage(id, rankStr+" could not be associated to a known rank.", logger);
         }
         return rank;
     }
 
+    private NomenclaturalStatusType makeNomenclaturalStatus(long id, RedListGefaesspflanzenImportState state, String nomZusatzString) {
+        NomenclaturalStatusType status = null;
+        try {
+            status = state.getTransformer().getNomenclaturalStatusByKey(nomZusatzString);
+        } catch (UndefinedTransformerMethodException e) {
+            e.printStackTrace();
+        }
+        if(status==null){
+            RedListUtil.logMessage(id, nomZusatzString+" could not be associated to a known nomenclatural status.", logger);
+        }
+        return status;
+    }
+
 
 
     @Override
     public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs,
             RedListGefaesspflanzenImportState state) {
         Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<>();
-//        Map<Long, AgentBase<?>> authorKombMap = new HashMap<>();
-//        Map<Long, AgentBase<?>> authorBasiMap = new HashMap<>();
-//
-//        //load authors
-//        for(Entry<Long, UUID> entry:state.getAuthorKombMap().entrySet()){
-//            authorKombMap.put(entry.getKey(), getAgentService().load(entry.getValue()));
-//        }
-//        for(Entry<Long, UUID> entry:state.getAuthorBasiMap().entrySet()){
-//            authorBasiMap.put(entry.getKey(), getAgentService().load(entry.getValue()));
-//        }
-//        try {
-//            while (rs.next()){
-//                long id = rs.getLong("NAMNR");
-//            }
-//        } catch (SQLException e) {
-//            e.printStackTrace();
-//        }
-//
-//        //Authors
-//        Set<UUID> uuidSet = new HashSet<>();
-//        for (String authorStr : authorKombSet){
-//            UUID uuid = state.getAuthorUuid(authorStr);
-//            uuidSet.add(uuid);
-//        }
-//        List<TeamOrPersonBase<?>> authors = (List)getAgentService().find(uuidSet);
-//        Map<UUID, TeamOrPersonBase<?>> authorUuidMap = new HashMap<>();
-//        for (TeamOrPersonBase<?> author : authors){
-//            authorUuidMap.put(author.getUuid(), author);
-//        }
-//
-//        for (String authorStr : authorKombSet){
-//            UUID uuid = state.getAuthorUuid(authorStr);
-//            TeamOrPersonBase<?> author = authorUuidMap.get(uuid);
-//            authorMap.put(authorStr, author);
-//        }
-//        result.put(AUTHOR_NAMESPACE, authorMap);
-//
-//        //reference map
-//        String nameSpace = REFERENCE_NAMESPACE;
-//        Class<?> cdmClass = Reference.class;
-//        Set<String> idSet = referenceIdSet;
-//        Map<String, Reference<?>> referenceMap = (Map<String, Reference<?>>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);
-//        result.put(nameSpace, referenceMap);
-//
-//        //secundum
-//        UUID secUuid = state.getConfig().getSecUuid();
-//        Reference<?> secRef = getReferenceService().find(secUuid);
-//        referenceMap.put(secUuid.toString(), secRef);
+        Map<String, AgentBase<?>> authorMap = new HashMap<String, AgentBase<?>>();
+
+        try {
+            while (rs.next()){
+                String authorKombString = rs.getString(RedListUtil.AUTOR_KOMB);
+
+                if(authorKombString.contains(RedListUtil.EX)){
+                    String[] kombSplit = authorKombString.split(RedListUtil.EX);
+                    for (int i = 0; i < kombSplit.length; i++) {
+                        if(!authorMap.containsKey(kombSplit[i])){
+                            authorMap.put(kombSplit[i], getAgentService().load(state.getAuthorMap().get(kombSplit[i])));
+                        }
+                    }
+                }
+                else if(!CdmUtils.isBlank(authorKombString) && !authorMap.containsKey(authorKombString)){
+                    authorMap.put(authorKombString, getAgentService().load(state.getAuthorMap().get(authorKombString)));
+                }
+
+                String authorBasiString = rs.getString(RedListUtil.AUTOR_BASI);
+                //basionym author
+                if(authorBasiString.contains(RedListUtil.EX)){
+                    String[] basiSplit = authorBasiString.split(RedListUtil.EX);
+                    for (int i = 0; i < basiSplit.length; i++) {
+                        if(!authorMap.containsKey(basiSplit[i])){
+                            authorMap.put(basiSplit[i], getAgentService().load(state.getAuthorMap().get(basiSplit[i])));
+                        }
+                    }
+                }
+                else if(!CdmUtils.isBlank(authorBasiString) && !authorMap.containsKey(authorBasiString)){
+                    authorMap.put(authorBasiString, getAgentService().load(state.getAuthorMap().get(authorBasiString)));
+                }
+            }
+        } catch (SQLException e) {
+            e.printStackTrace();
+        }
+        result.put(RedListUtil.AUTHOR_NAMESPACE, authorMap);
 
         return result;
     }