(no commit message)
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / faunaEuropaea / FaunaEuropaeaTaxonNameImport.java
index 7dfad14707ea17940cef70ee4162ab47796a7b62..1355d67867f0258c7cbf87e0afc6ebe3ac326a22 100644 (file)
@@ -11,7 +11,6 @@ package eu.etaxonomy.cdm.io.faunaEuropaea;
 \r
 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.A_AUCT;\r
 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.P_PARENTHESIS;\r
-import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.Q_NO_RESTRICTION;\r
 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_GENUS;\r
 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_SPECIES;\r
 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_SUBGENUS;\r
@@ -21,8 +20,10 @@ import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.T_STATU
 \r
 import java.sql.ResultSet;\r
 import java.sql.SQLException;\r
+import java.util.ArrayList;\r
 import java.util.Collection;\r
 import java.util.HashMap;\r
+import java.util.HashSet;\r
 import java.util.List;\r
 import java.util.Map;\r
 import java.util.Set;\r
@@ -32,23 +33,19 @@ import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;\r
 import org.springframework.transaction.TransactionStatus;\r
 \r
-import eu.etaxonomy.cdm.api.service.IService;\r
 import eu.etaxonomy.cdm.common.CdmUtils;\r
 import eu.etaxonomy.cdm.io.common.ICdmIO;\r
 import eu.etaxonomy.cdm.io.common.ImportHelper;\r
 import eu.etaxonomy.cdm.io.common.MapWrapper;\r
 import eu.etaxonomy.cdm.io.common.Source;\r
-import eu.etaxonomy.cdm.io.profiler.ProfilerController;\r
 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;\r
 import eu.etaxonomy.cdm.model.common.CdmBase;\r
-import eu.etaxonomy.cdm.model.common.OriginalSource;\r
+import eu.etaxonomy.cdm.model.common.IdentifiableSource;\r
 import eu.etaxonomy.cdm.model.name.Rank;\r
 import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
 import eu.etaxonomy.cdm.model.name.ZoologicalName;\r
 import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
 import eu.etaxonomy.cdm.model.taxon.Synonym;\r
-import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;\r
-import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;\r
 import eu.etaxonomy.cdm.model.taxon.Taxon;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
 import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;\r
@@ -67,8 +64,6 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
 \r
        /* Max number of taxa to retrieve (for test purposes) */\r
        private int maxTaxa = 0;\r
-       /* Interval for progress info message when retrieving taxa */\r
-//     private int modCount = 10000;\r
        \r
 \r
        /* (non-Javadoc)\r
@@ -109,47 +104,33 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
         */\r
        protected boolean doInvoke(FaunaEuropaeaImportState state) {                            \r
                \r
-               ProfilerController.memorySnapshot();\r
-\r
-               TransactionStatus txStatus = null;\r
                boolean success = true;\r
-               \r
                if(logger.isInfoEnabled()) { logger.info("Start making taxa..."); }\r
-\r
-               if (state.getConfig().isUseTransactions()) {\r
-                       txStatus = startTransaction();\r
-               }\r
                \r
-               success = retrieveTaxa(state);\r
-//             success = processTaxaSecondPass(state);\r
-//             success = saveTaxa(state, state.getHighestTaxonIndex(), state.getConfig().getLimitSave());\r
                \r
-               if (state.getConfig().isUseTransactions()) {\r
-                       commitTransaction(txStatus);\r
-               }\r
+               \r
+               success = processTaxa(state);\r
                \r
                logger.info("End making taxa...");\r
-               ProfilerController.memorySnapshot();\r
                return success;\r
        }\r
 \r
        \r
-       /** Retrieve taxa from FauEu DB, fill TaxonStore */\r
-       private boolean retrieveTaxa(FaunaEuropaeaImportState state) {\r
+       /** Retrieve taxa from FauEu DB, process in blocks */\r
+       private boolean processTaxa(FaunaEuropaeaImportState state) {\r
 \r
                int limit = state.getConfig().getLimitSave();\r
 \r
+               TransactionStatus txStatus = null;\r
+\r
                Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();\r
-//             MapWrapper<TaxonBase> nameStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXONNAME_STORE);\r
-               MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);\r
                MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);\r
-//             Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap = state.getFauEuTaxonMap();\r
-               Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap = new HashMap<Integer, FaunaEuropaeaTaxon>(limit);\r
-               state.setFauEuTaxonMap(fauEuTaxonMap);\r
+               \r
+               Map<Integer, TaxonBase<?>> taxonMap = null;\r
+               Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap = null;\r
+               /* Store for heterotypic synonyms to be save separately */\r
+               Set<Synonym> synonymSet = null;\r
 \r
-               if (logger.isInfoEnabled()) {\r
-                       logger.info("Initial size of taxon store is: " + taxonStore.size());\r
-               }\r
                FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();\r
                ReferenceBase<?> sourceRef = fauEuConfig.getSourceReference();\r
 \r
@@ -157,38 +138,94 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
                int i = 0;\r
                boolean success = true;\r
 \r
-               try {\r
+               String selectCount = \r
+                       " SELECT count(*) ";\r
+\r
+               String selectColumns = \r
+                       " SELECT Parent.TAX_NAME AS P2Name, Parent.TAX_RNK_ID AS P2RankId, " +\r
+                       " GrandParent.TAX_ID AS GP3Id, GrandParent.TAX_NAME AS GP3Name, GrandParent.TAX_RNK_ID AS GP3RankId, " +\r
+                       " GreatGrandParent.TAX_ID AS GGP4Id, GreatGrandParent.TAX_NAME AS GGP4Name, GreatGrandParent.TAX_RNK_ID AS GGP4RankId, " +\r
+                       " GreatGreatGrandParent.TAX_ID AS GGGP5Id, GreatGreatGrandParent.TAX_NAME AS GGGP5Name, GreatGreatGrandParent.TAX_RNK_ID AS GGGP5RankId, " +\r
+                       " OriginalGenusTaxon.TAX_NAME AS OGenusName, " +\r
+                       " GreatGreatGreatGrandParent.TAX_ID AS GGGGP6Id, GreatGreatGreatGrandParent.TAX_NAME AS GGGGP6Name, GreatGreatGreatGrandParent.TAX_RNK_ID AS GGGGP6RankId," +\r
+                       " Taxon.*, rank.*, author.* ";\r
+               \r
+               String fromClause = \r
+                       " FROM Taxon LEFT OUTER JOIN " +\r
+                       " Taxon AS Parent ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID LEFT OUTER JOIN " +\r
+                       " Taxon AS GrandParent ON Parent.TAX_TAX_IDPARENT = GrandParent.TAX_ID LEFT OUTER JOIN " +\r
+                       " Taxon AS GreatGrandParent ON GrandParent.TAX_TAX_IDPARENT = GreatGrandParent.TAX_ID LEFT OUTER JOIN " +\r
+                       " Taxon AS GreatGreatGrandParent ON GreatGrandParent.TAX_TAX_IDPARENT = GreatGreatGrandParent.TAX_ID LEFT OUTER JOIN " +\r
+                       " Taxon AS GreatGreatGreatGrandParent ON GreatGreatGrandParent.TAX_TAX_IDPARENT = GreatGreatGreatGrandParent.TAX_ID LEFT OUTER JOIN " +\r
+                       " Taxon AS OriginalGenusTaxon ON Taxon.TAX_TAX_IDGENUS = OriginalGenusTaxon.TAX_ID LEFT OUTER JOIN " +\r
+                       " author ON Taxon.TAX_AUT_ID = author.aut_id LEFT OUTER JOIN " +\r
+                       " rank ON Taxon.TAX_RNK_ID = rank.rnk_id ";\r
+\r
+               String countQuery = \r
+                       selectCount + fromClause;\r
+\r
+               String selectQuery = \r
+                       selectColumns + fromClause;\r
+               \r
 \r
-                       String strQuery = \r
-                               " SELECT Taxon.*, rank.*, author.* " + \r
-                               " FROM dbo.Taxon " +\r
-                               " LEFT OUTER JOIN dbo.author ON dbo.Taxon.TAX_AUT_ID = dbo.author.aut_id " +\r
-                               " LEFT OUTER JOIN dbo.rank ON dbo.Taxon.TAX_RNK_ID = dbo.rank.rnk_id " +\r
-                               " WHERE (1=1)";\r
+        try {\r
 \r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("Query: " + strQuery);\r
-                       }\r
-                       ResultSet rs = source.getResultSet(strQuery);\r
+                       ResultSet rs = source.getResultSet(countQuery);\r
+                       rs.next();\r
+                       int count = rs.getInt(1);\r
+                       \r
+                       rs = source.getResultSet(selectQuery);\r
 \r
+               if (logger.isInfoEnabled()) {\r
+                               logger.info("Number of rows: " + count);\r
+                               logger.info("Count Query: " + countQuery);\r
+                               logger.info("Select Query: " + selectQuery);\r
+                       }\r
+               \r
                        while (rs.next()) {\r
 \r
-//                             if ((i++ % limit) == 0 && i != 1 ) { \r
-//                             if(logger.isInfoEnabled()) {\r
-//                             logger.info("Taxa retrieved: " + (i-1)); \r
-//                             }\r
-//                             }\r
+                               if ((i++ % limit) == 0) {\r
+                                       \r
+                                       txStatus = startTransaction();\r
+                                       taxonMap = new HashMap<Integer, TaxonBase<?>>(limit);\r
+                                       fauEuTaxonMap = new HashMap<Integer, FaunaEuropaeaTaxon>(limit);\r
+                                       synonymSet = new HashSet<Synonym>();\r
+                                       \r
+                                       if(logger.isInfoEnabled()) {\r
+                                               logger.info("i = " + i + " - Transaction started"); \r
+                                       }\r
+                               }\r
 \r
-                               int taxonId = rs.getInt("TAX_ID");\r
                                String localName = rs.getString("TAX_NAME");\r
+                               String parentName = rs.getString("P2Name");\r
+                               int grandParentId = rs.getInt("GP3Id");\r
+                               String grandParentName = rs.getString("GP3Name");\r
+                               int greatGrandParentId = rs.getInt("GGP4Id");\r
+                               String greatGrandParentName = rs.getString("GGP4Name");\r
+                               int greatGreatGrandParentId = rs.getInt("GGGP5Id");\r
+                               String greatGreatGrandParentName = rs.getString("GGGP5Name");\r
+                               String greatGreatGreatGrandParentName = rs.getString("GGGGP6Name");\r
+                               String originalGenusName = rs.getString("OGenusName");\r
+                               String autName = rs.getString("aut_name");\r
+                               int taxonId = rs.getInt("TAX_ID");\r
                                int rankId = rs.getInt("TAX_RNK_ID");\r
                                int parentId = rs.getInt("TAX_TAX_IDPARENT");\r
-                               int familyId = rs.getInt("TAX_TAX_IDFAMILY");\r
+                               int parentRankId = rs.getInt("P2RankId");\r
+                               int grandParentRankId = rs.getInt("GP3RankId");\r
+                               int greatGrandParentRankId = rs.getInt("GGP4RankId");\r
+                               int greatGreatGrandParentRankId = rs.getInt("GGGP5RankId");\r
+                               int greatGreatGreatGrandParentRankId = rs.getInt("GGGGP6RankId");\r
                                int originalGenusId = rs.getInt("TAX_TAX_IDGENUS");\r
                                int autId = rs.getInt("TAX_AUT_ID");\r
                                int status = rs.getInt("TAX_VALID");\r
-                               int year = rs.getInt("TAX_YEAR");\r
-                               String autName = rs.getString("aut_name");\r
+                               \r
+                               // Avoid publication year 0 for NULL values in database.\r
+                               Integer year = rs.getInt("TAX_YEAR");\r
+                               if (year != null && year.intValue() == 0) {\r
+                                       year = null;\r
+                               }\r
+                               \r
+                               //int familyId = rs.getInt("TAX_TAX_IDFAMILY");\r
 \r
                                Rank rank = null;\r
                                int parenthesis = rs.getInt("TAX_PARENTHESIS");\r
@@ -199,21 +236,35 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
                                        taxonBaseUuid = UUID.randomUUID();\r
                                }\r
 \r
-//                             String originalGenusName = "";\r
-//                             String genusName = "";\r
-//                             String specificEpithet = "";\r
-\r
-\r
                                FaunaEuropaeaTaxon fauEuTaxon = new FaunaEuropaeaTaxon();\r
                                fauEuTaxon.setUuid(taxonBaseUuid);\r
-                               fauEuTaxon.setLocalName(rs.getString("TAX_NAME"));\r
-                               fauEuTaxon.setParentId(rs.getInt("TAX_TAX_IDPARENT"));\r
-//                             fauEuTaxon.setOriginalGenusId(rs.getInt("TAX_TAX_IDGENUS"));\r
-                               fauEuTaxon.setId(rs.getInt("TAX_ID"));\r
-                               fauEuTaxon.setRankId(rs.getInt("TAX_RNK_ID"));\r
-                               fauEuTaxon.setYear(rs.getInt("TAX_YEAR"));\r
-//                             fauEuTaxon.setAuthorId(autId);\r
-                               fauEuTaxon.setAuthorName(rs.getString("aut_name"));\r
+                               fauEuTaxon.setId(taxonId);\r
+                               fauEuTaxon.setRankId(rankId);\r
+                               fauEuTaxon.setLocalName(localName);\r
+                               \r
+                               fauEuTaxon.setParentId(parentId);\r
+                               fauEuTaxon.setParentRankId(parentRankId);\r
+                               fauEuTaxon.setParentName(parentName);\r
+                               \r
+                               fauEuTaxon.setGrandParentId(grandParentId);\r
+                               fauEuTaxon.setGrandParentRankId(grandParentRankId);\r
+                               fauEuTaxon.setGrandParentName(grandParentName);\r
+                               \r
+                               fauEuTaxon.setGreatGrandParentId(greatGrandParentId);\r
+                               fauEuTaxon.setGreatGrandParentRankId(greatGrandParentRankId);\r
+                               fauEuTaxon.setGreatGrandParentName(greatGrandParentName);\r
+                               \r
+                               fauEuTaxon.setGreatGreatGrandParentId(greatGreatGrandParentId);\r
+                               fauEuTaxon.setGreatGreatGrandParentRankId(greatGreatGrandParentRankId);\r
+                               fauEuTaxon.setGreatGreatGrandParentName(greatGreatGrandParentName);\r
+                               \r
+                               fauEuTaxon.setGreatGreatGreatGrandParentRankId(greatGreatGreatGrandParentRankId);\r
+                               fauEuTaxon.setGreatGreatGreatGrandParentName(greatGreatGreatGrandParentName);\r
+                               \r
+                               fauEuTaxon.setOriginalGenusId(originalGenusId);\r
+                               fauEuTaxon.setYear(year);\r
+                               fauEuTaxon.setOriginalGenusName(originalGenusName);\r
+                               fauEuTaxon.setAuthorName(autName);\r
                                if (parenthesis == P_PARENTHESIS) {\r
                                        fauEuTaxon.setParenthesis(true);\r
                                } else {\r
@@ -225,6 +276,7 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
                                        fauEuTaxon.setValid(false);\r
                                }\r
 \r
+//                             fauEuTaxon.setAuthorId(autId);\r
 \r
                                try {\r
                                        rank = FaunaEuropaeaTransformer.rankId2Rank(rs, false);\r
@@ -241,12 +293,10 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
 \r
                                ZoologicalName zooName = ZoologicalName.NewInstance(rank);\r
                                TeamOrPersonBase<?> author = authorStore.get(autId);\r
+                               \r
                                zooName.setCombinationAuthorTeam(author);\r
                                zooName.setPublicationYear(year);\r
-\r
-                               // set local name cache\r
-//                             zooName.setNameCache(localName);\r
-\r
+                               \r
                                TaxonBase<?> taxonBase;\r
 \r
                                Synonym synonym;\r
@@ -254,11 +304,13 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
                                try {\r
                                        if ((status == T_STATUS_ACCEPTED) || (autId == A_AUCT)) { // taxon\r
                                                if (autId == A_AUCT) { // misapplied name\r
+                                                       zooName.setCombinationAuthorTeam(null);\r
+                                                       zooName.setPublicationYear(null);\r
                                                        taxon = Taxon.NewInstance(zooName, auctReference);\r
                                                        if (logger.isDebugEnabled()) {\r
                                                                logger.debug("Misapplied name created (" + taxonId + ")");\r
                                                        }\r
-                                               } else { // regular taxon\r
+                                               } else { // accepted taxon\r
                                                        taxon = Taxon.NewInstance(zooName, sourceReference);\r
                                                        if (logger.isDebugEnabled()) {\r
                                                                logger.debug("Taxon created (" + taxonId + ")");\r
@@ -267,6 +319,7 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
                                                taxonBase = taxon;\r
                                        } else if ((status == T_STATUS_NOT_ACCEPTED) && (autId != A_AUCT)) { // synonym\r
                                                synonym = Synonym.NewInstance(zooName, sourceReference);\r
+                                               //logger.info("Synonym created: " + synonym.getTitleCache() + " taxonName: " + zooName.getTitleCache());\r
                                                if (logger.isDebugEnabled()) {\r
                                                        logger.debug("Synonym created (" + taxonId + ")");\r
                                                }\r
@@ -282,15 +335,16 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
                                        ImportHelper.setOriginalSource(zooName, fauEuConfig.getSourceReference(), taxonId, "TaxonName");\r
 \r
 \r
-                                       if (!taxonStore.containsId(taxonId)) {\r
+                                       if (!taxonMap.containsKey(taxonId)) {\r
                                                if (taxonBase == null) {\r
                                                        if (logger.isDebugEnabled()) { \r
                                                                logger.debug("Taxon base is null. Taxon (" + taxonId + ") ignored.");\r
                                                        }\r
                                                        continue;\r
                                                }\r
-                                               taxonStore.put(taxonId, taxonBase);\r
+                                               taxonMap.put(taxonId, taxonBase);\r
                                                fauEuTaxonMap.put(taxonId, fauEuTaxon);\r
+                                               \r
 //                                             if (logger.isDebugEnabled()) { \r
 //                                             logger.debug("Stored taxon base (" + taxonId + ") " + localName); \r
 //                                             }\r
@@ -304,24 +358,20 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
                                        e.printStackTrace();\r
                                }\r
 \r
-                               if ((i++ % limit) == 0 && i != 1 ) { \r
-                                       if(logger.isInfoEnabled()) {\r
-                                               logger.info("Taxa retrieved: " + (i-1)); \r
-                                       }\r
-                                       success = processTaxaSecondPass(state);\r
-                                       success = saveTaxa(state);\r
-\r
-                                       if (logger.isInfoEnabled()) {\r
-                                               logger.info("End size of taxon Store is: " + taxonStore.size());\r
-                                       }\r
-\r
-//                                     taxonStore.makeNewMap((IService)getTaxonService());\r
-                                       taxonStore.makeEmpty();\r
-                                       fauEuTaxonMap = new HashMap<Integer, FaunaEuropaeaTaxon>(limit);\r
-                                       state.setFauEuTaxonMap(fauEuTaxonMap);\r
+                               if (((i % limit) == 0 && i != 1 ) || i == count) { \r
 \r
-                                       if (logger.isInfoEnabled()) {\r
-                                               logger.info("Final size of taxon Store is: " + taxonStore.size());\r
+                                       success = processTaxaSecondPass(state, taxonMap, fauEuTaxonMap, synonymSet);\r
+                                       if(logger.isDebugEnabled()) { logger.debug("Saving taxa ..."); }\r
+                                       getTaxonService().save((Collection)taxonMap.values());\r
+                                       getTaxonService().save((Collection)synonymSet);\r
+                                       \r
+                                       taxonMap = null;\r
+                                       synonymSet = null;\r
+                                       fauEuTaxonMap = null;\r
+                                       commitTransaction(txStatus);\r
+                                       \r
+                                       if(logger.isInfoEnabled()) {\r
+                                               logger.info("i = " + i + " - Transaction committed"); \r
                                        }\r
                                }\r
 \r
@@ -338,75 +388,120 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
        /**\r
         * Processes taxa from complete taxon store\r
         */\r
-       private boolean processTaxaSecondPass(FaunaEuropaeaImportState state) {\r
+       private boolean processTaxaSecondPass(FaunaEuropaeaImportState state, Map<Integer, TaxonBase<?>> taxonMap,\r
+                       Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, Set<Synonym> synonymSet) {\r
 \r
-               if(logger.isInfoEnabled()) { logger.info("Processing taxa second pass..."); }\r
+               if(logger.isDebugEnabled()) { logger.debug("Processing taxa second pass..."); }\r
 \r
-               Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();\r
-               MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);\r
                FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();\r
-               ReferenceBase<?> sourceRef = fauEuConfig.getSourceReference();\r
-               Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap = state.getFauEuTaxonMap();\r
-\r
+               \r
                boolean success = true;\r
 \r
-               for (int id : taxonStore.keySet())\r
+               for (int id : taxonMap.keySet())\r
                {\r
-                       TaxonBase<?> taxonBase = taxonStore.get(id);\r
                        if (logger.isDebugEnabled()) { logger.debug("Taxon # " + id); }\r
                        \r
+                       TaxonBase<?> taxonBase = taxonMap.get(id);\r
                        TaxonNameBase<?,?> taxonName = taxonBase.getName();\r
-                       \r
                        FaunaEuropaeaTaxon fauEuTaxon = fauEuTaxonMap.get(id);\r
+                       boolean useOriginalGenus = false;\r
+                       if (taxonBase instanceof Synonym){\r
+                               useOriginalGenus = true;\r
+                       }\r
                        \r
                        String nameString = \r
-                               buildTaxonName(fauEuTaxon, taxonBase, taxonName, false, fauEuTaxonMap, fauEuConfig);\r
+                               buildTaxonName(fauEuTaxon, taxonBase, taxonName, useOriginalGenus, fauEuConfig);\r
+                       \r
+                       if (taxonBase instanceof Synonym){\r
+                               logger.info("Name of Synonym: " + nameString);\r
+                       }\r
                        \r
-                       if (fauEuConfig.isDoBasionyms() && (fauEuTaxon.isValid()) &&\r
-                                       (fauEuTaxon.getOriginalGenusId() != 0) &&\r
-                                       (fauEuTaxon.getParentId() != fauEuTaxon.getOriginalGenusId())) {\r
-                               success = createBasionym(fauEuTaxon, taxonBase, taxonName, fauEuTaxonMap, fauEuConfig);\r
+                       if (fauEuConfig.isDoBasionyms() \r
+                                       && fauEuTaxon.getRankId() > R_SUBGENUS\r
+                                       && (fauEuTaxon.getOriginalGenusId() != 0)) {\r
+                               \r
+                               Integer originalGenusId = fauEuTaxon.getOriginalGenusId();\r
+                               Integer actualGenusId = getActualGenusId(fauEuTaxon);\r
+                               \r
+                               if (logger.isDebugEnabled()) {\r
+                                       logger.debug("actual genus id = " + actualGenusId + ", original genus id = " + originalGenusId);\r
+                               }\r
+                               \r
+                               if (actualGenusId != originalGenusId && taxonBase.isInstanceOf(Taxon.class)) {\r
+                                       success = createBasionym(fauEuTaxon, taxonBase, taxonName, fauEuConfig, synonymSet);\r
+                               } else if (fauEuTaxon.isParenthesis()) {\r
+                                       //the authorteam should be set in parenthesis because there should be a basionym, but we do not know it?\r
+                                       ZoologicalName zooName = taxonName.deproxy(taxonName, ZoologicalName.class);\r
+                                       zooName.setBasionymAuthorTeam(zooName.getCombinationAuthorTeam());\r
+                                       zooName.setCombinationAuthorTeam(null);\r
+                                       zooName.setOriginalPublicationYear(zooName.getPublicationYear());\r
+                                       zooName.setPublicationYear(null);\r
+                               }\r
+                               \r
                        }\r
                }\r
                return success; \r
        }\r
 \r
        \r
-       private boolean createBasionym(FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase, TaxonNameBase<?,?>taxonName, \r
-                       Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, FaunaEuropaeaImportConfigurator fauEuConfig) {\r
-\r
-//             if (fauEuTaxon.isParenthesis() && (fauEuTaxon.getOriginalGenusId() != 0)\r
-//             && (fauEuTaxon.getParentId() != fauEuTaxon.getOriginalGenusId())) {\r
+       private boolean createBasionym(FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase, \r
+                       TaxonNameBase<?,?>taxonName, FaunaEuropaeaImportConfigurator fauEuConfig,\r
+                       Set<Synonym> synonymSet) {\r
 \r
                boolean success = true;\r
 \r
                try {\r
                        ZoologicalName zooName = taxonName.deproxy(taxonName, ZoologicalName.class);\r
-                       Taxon taxon = taxonBase.deproxy(taxonBase, Taxon.class);\r
                        \r
                        // create basionym\r
                        ZoologicalName basionym = ZoologicalName.NewInstance(taxonName.getRank());\r
                        basionym.setCombinationAuthorTeam(zooName.getCombinationAuthorTeam());\r
+                       \r
+                       zooName.setOriginalPublicationYear(zooName.getPublicationYear());\r
                        basionym.setPublicationYear(zooName.getPublicationYear());\r
+\r
+                       // add originalGenusId as source\r
+                       String originalGenusIdString = "" + fauEuTaxon.getId();\r
+                       IdentifiableSource basionymSource = IdentifiableSource.NewInstance(originalGenusIdString, "originalGenusId");\r
+                       basionym.addSource(basionymSource);\r
+                       \r
+                       // add original database reference\r
+                       ImportHelper.setOriginalSource(basionym, fauEuConfig.getSourceReference(), fauEuTaxon.getId(), "TaxonName");\r
+                       \r
                        zooName.addBasionym(basionym, fauEuConfig.getSourceReference(), null, null);\r
                        zooName.setBasionymAuthorTeam(zooName.getCombinationAuthorTeam());\r
+                       zooName.setCombinationAuthorTeam(null);\r
+                       zooName.setPublicationYear(null);\r
+                       zooName.setTitleCache(null); // This should (re)generate the titleCache automagically\r
                        if (logger.isDebugEnabled()) {\r
                                logger.debug("Basionym created (" + fauEuTaxon.getId() + ")");\r
                        }\r
 \r
-                       // create homotypic synonym\r
-                       Synonym homotypicSynonym = Synonym.NewInstance(basionym, fauEuConfig.getSourceReference());\r
-//                     SynonymRelationship synRel = \r
-//                     taxon.addSynonym(homotypicSynonym, SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF(), \r
-//                     sourceReference, null);\r
-//                     homotypicSynonym.addRelationship(synRel);\r
-                       taxon.addHomotypicSynonym(homotypicSynonym, fauEuConfig.getSourceReference(), null);\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("Homotypic synonym created (" + fauEuTaxon.getId() + ")");\r
+                       // create synonym\r
+                       Synonym synonym = Synonym.NewInstance(basionym, fauEuConfig.getSourceReference());\r
+                       \r
+                       if (fauEuTaxon.isValid()) { // Taxon\r
+\r
+                               // homotypic synonym\r
+                               Taxon taxon = taxonBase.deproxy(taxonBase, Taxon.class);\r
+                               taxon.addHomotypicSynonym(synonym, fauEuConfig.getSourceReference(), null);\r
+                               if (logger.isDebugEnabled()) {\r
+                                       logger.debug("Homotypic synonym created (" + fauEuTaxon.getId() + ")");\r
+                               }\r
+\r
+                       } else { // Synonym\r
+                               \r
+                               // heterotypic synonym\r
+                               // synonym relationship to the accepted taxon is created later\r
+                               synonymSet.add(synonym);\r
+                               \r
+                               if (logger.isDebugEnabled()) {\r
+                                       logger.debug("Heterotypic synonym stored (" + fauEuTaxon.getId() + ")");\r
+                               }\r
                        }\r
                        \r
-                       buildTaxonName(fauEuTaxon, homotypicSynonym, basionym, true, fauEuTaxonMap, fauEuConfig);\r
                        \r
+                       buildTaxonName(fauEuTaxon, synonym, basionym, true, fauEuConfig);\r
                } catch (Exception e) {\r
                        logger.warn("Exception occurred when creating basionym for " + fauEuTaxon.getId());\r
                        e.printStackTrace();\r
@@ -421,8 +516,8 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
        private String buildNameTitleCache(String nameString, boolean useOriginalGenus, FaunaEuropaeaTaxon fauEuTaxon) {\r
                \r
                StringBuilder titleCacheStringBuilder = new StringBuilder(nameString);\r
-               int year = fauEuTaxon.getYear();\r
-               if (year != 0) { // TODO: Ignore authors like xp, xf, etc?\r
+               Integer year = fauEuTaxon.getYear();\r
+               if (year != null) { // TODO: Ignore authors like xp, xf, etc?\r
                        titleCacheStringBuilder.append(" ");\r
                        if ((fauEuTaxon.isParenthesis() == true) && !useOriginalGenus) {\r
                                titleCacheStringBuilder.append("(");\r
@@ -463,7 +558,7 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
 \r
                StringBuilder stringBuilder = new StringBuilder();\r
                \r
-               if(useOriginalGenus == true) {\r
+               if(useOriginalGenus) {\r
                        stringBuilder.append(originalGenusName);\r
                        genusOrUninomial.delete(0, genusOrUninomial.length());\r
                        genusOrUninomial.append(originalGenusName);\r
@@ -476,15 +571,24 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
        }\r
 \r
        \r
-       private String genusSubGenusPart(StringBuilder originalGenusName, boolean useOriginalGenus,\r
+       private String genusSubGenusPart(StringBuilder originalGenusName, boolean useOriginalGenus, \r
                        StringBuilder genusOrUninomial,\r
-                       StringBuilder infraGenericEpithet) {\r
+                       StringBuilder infraGenericEpithet,\r
+                       FaunaEuropaeaTaxon fauEuTaxon) {\r
 \r
                StringBuilder stringBuilder = new StringBuilder();\r
                \r
                stringBuilder.append(genusPart(originalGenusName, useOriginalGenus, genusOrUninomial));\r
 \r
-               if (useOriginalGenus == true) {\r
+               // The infraGenericEpithet is set to empty only if the original genus should be used and\r
+               // the actualGenusId is not the originalGenusId.\r
+               // This differentiation is relevant for synonyms and for basionyms.\r
+               // InfraGenericEpithets of accepted taxa are not touched at all.\r
+               Integer originalGenusId = fauEuTaxon.getOriginalGenusId();\r
+               Integer actualGenusId = getActualGenusId(fauEuTaxon);\r
+               if (useOriginalGenus && originalGenusId != actualGenusId && \r
+                               originalGenusId.intValue() > 0 &&\r
+                               actualGenusId.intValue() > 0) {\r
                        infraGenericEpithet.delete(0, infraGenericEpithet.length());\r
                        stringBuilder.append(" ");\r
                        return stringBuilder.toString();\r
@@ -497,119 +601,149 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
                \r
                return stringBuilder.toString();\r
        }\r
+\r
+       /** Get actual genus id **/\r
+       private Integer getActualGenusId(FaunaEuropaeaTaxon fauEuTaxon) {\r
+               Integer actualGenusId = null;\r
+               HashMap<Integer, Integer> ranks = new HashMap<Integer, Integer>();\r
+               ranks.put(fauEuTaxon.getParentRankId(), fauEuTaxon.getParentId());\r
+               ranks.put(fauEuTaxon.getGrandParentRankId(), fauEuTaxon.getGrandParentId());\r
+               ranks.put(fauEuTaxon.getGreatGrandParentRankId(), fauEuTaxon.getGreatGrandParentId());\r
+               ranks.put(fauEuTaxon.getGreatGreatGrandParentRankId(), fauEuTaxon.getGreatGreatGrandParentId());\r
+               ranks.put(fauEuTaxon.getGreatGreatGreatGrandParentRankId(), fauEuTaxon.getGreatGreatGreatGrandParentId());\r
+               \r
+               actualGenusId = ranks.get(R_GENUS);\r
+\r
+               return actualGenusId;\r
+       }\r
        \r
        \r
        /** Build species and subspecies names */\r
-       private String buildLowerTaxonName(StringBuilder originalGenus, boolean useOriginalGenus,\r
+       private String buildLowerTaxonName(StringBuilder originalGenus, boolean useOriginalGenus, \r
                        StringBuilder genusOrUninomial, StringBuilder infraGenericEpithet, \r
                        StringBuilder specificEpithet, StringBuilder infraSpecificEpithet,\r
-                       FaunaEuropaeaTaxon fauEuTaxon, Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap) {\r
+                       FaunaEuropaeaTaxon fauEuTaxon) {\r
                \r
+               // species or subspecies name\r
+               String localName = fauEuTaxon.getLocalName();\r
+               int taxonId = fauEuTaxon.getId();\r
+               int parentId = fauEuTaxon.getParentId();\r
                StringBuilder nameCacheStringBuilder = new StringBuilder();\r
 \r
-               int rank = fauEuTaxon.getRankId();\r
-               int parentId = fauEuTaxon.getParentId();\r
-               FaunaEuropaeaTaxon parent = fauEuTaxonMap.get(parentId);\r
-               if (parent == null) {\r
-                       nameCacheStringBuilder.append(fauEuTaxon.getLocalName());\r
+//             FaunaEuropaeaTaxon parent = fauEuTaxonMap.get(parentId);\r
+               if (parentId == 0) {\r
+                       nameCacheStringBuilder.append(localName);\r
                        if (logger.isInfoEnabled()) {\r
-                               logger.info("Parent of (" + fauEuTaxon.getId() + ") is null");\r
+                               logger.info("Parent of (" + taxonId + ") is null");\r
                        }\r
                        return nameCacheStringBuilder.toString();\r
                }\r
-               int grandParentId = parent.getParentId();\r
-               FaunaEuropaeaTaxon grandParent = fauEuTaxonMap.get(grandParentId);\r
-               int greatGrandParentId = grandParent.getParentId();\r
-               FaunaEuropaeaTaxon greatGrandParent = fauEuTaxonMap.get(greatGrandParentId);\r
+               \r
+               String parentName = fauEuTaxon.getParentName();\r
+               String grandParentName = fauEuTaxon.getGrandParentName();\r
+               String greatGrandParentName = fauEuTaxon.getGreatGrandParentName();\r
+               int rank = fauEuTaxon.getRankId();\r
+               int parentRankId = fauEuTaxon.getParentRankId();\r
+               int grandParentRankId = fauEuTaxon.getGrandParentRankId();\r
+               int greatGrandParentRankId = fauEuTaxon.getGreatGrandParentRankId();\r
+//             int grandParentId = fauEuTaxon.getGrandParentId();\r
+//             int greatGrandParentId = grandParent.getParentId();\r
 \r
                \r
                if (fauEuTaxon.isValid()) { // Taxon\r
                        \r
                        if (rank == R_SPECIES) {\r
 \r
-                               if(parent.getRankId() == R_SUBGENUS) {\r
-\r
+                               if(parentRankId == R_SUBGENUS) {\r
+                                       //differ between isParanthesis= true and false\r
                                        String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, \r
-                                                       genusOrUninomial.append(grandParent.getLocalName()), \r
-                                                       infraGenericEpithet.append(parent.getLocalName()));\r
-                                       nameCacheStringBuilder.append(genusSubGenusPart);\r
+                                                       genusOrUninomial.append(grandParentName), \r
+                                                       infraGenericEpithet.append(parentName),\r
+                                                       fauEuTaxon);\r
+                                               nameCacheStringBuilder.append(genusSubGenusPart);\r
+                                       \r
 \r
-                               } else if(parent.getRankId() == R_GENUS) {\r
+                               } else if(parentRankId == R_GENUS) {\r
 \r
                                        String genusPart = genusPart(originalGenus, useOriginalGenus, \r
-                                                       genusOrUninomial.append(parent.getLocalName()));\r
+                                                       genusOrUninomial.append(parentName));\r
                                        nameCacheStringBuilder.append(genusPart);\r
                                }\r
-                               nameCacheStringBuilder.append(fauEuTaxon.getLocalName());\r
-                               specificEpithet.append(fauEuTaxon.getLocalName());\r
+                               nameCacheStringBuilder.append(localName);\r
+                               specificEpithet.append(localName);\r
 \r
                        } else if (rank == R_SUBSPECIES) {\r
 \r
-                               if(grandParent.getRankId() == R_SUBGENUS) {\r
+                               if(grandParentRankId == R_SUBGENUS) {\r
 \r
                                        String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, \r
-                                                       genusOrUninomial.append(greatGrandParent.getLocalName()), \r
-                                                       infraGenericEpithet.append(grandParent.getLocalName()));\r
+                                                       genusOrUninomial.append(greatGrandParentName), \r
+                                                       infraGenericEpithet.append(grandParentName),\r
+                                                       fauEuTaxon);\r
                                        nameCacheStringBuilder.append(genusSubGenusPart);\r
 \r
-                               } else if (grandParent.getRankId() == R_GENUS) {\r
+                               } else if (grandParentRankId == R_GENUS) {\r
 \r
                                        String genusPart = genusPart(originalGenus, useOriginalGenus, \r
-                                                       genusOrUninomial.append(grandParent.getLocalName()));\r
+                                                       genusOrUninomial.append(grandParentName));\r
                                        nameCacheStringBuilder.append(genusPart);\r
 \r
                                }\r
-                               nameCacheStringBuilder.append(parent.getLocalName());\r
+                               nameCacheStringBuilder.append(parentName);\r
                                nameCacheStringBuilder.append(" ");\r
-                               nameCacheStringBuilder.append(fauEuTaxon.getLocalName());\r
-                               specificEpithet.append(parent.getLocalName());\r
-                               infraSpecificEpithet.append(fauEuTaxon.getLocalName());\r
+                               nameCacheStringBuilder.append(localName);\r
+                               specificEpithet.append(parentName);\r
+                               infraSpecificEpithet.append(localName);\r
                        }\r
                } else { // Synonym\r
                        \r
                        if (rank == R_SPECIES) {\r
 \r
-                               if(grandParent.getRankId() == R_SUBGENUS) {\r
+                               if(grandParentRankId == R_SUBGENUS) {\r
                                        \r
                                        String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, \r
-                                                       genusOrUninomial.append(greatGrandParent.getLocalName()), \r
-                                                       infraGenericEpithet.append(grandParent.getLocalName()));\r
+                                                       genusOrUninomial.append(greatGrandParentName), \r
+                                                       infraGenericEpithet.append(grandParentName),\r
+                                                       fauEuTaxon);\r
                                        nameCacheStringBuilder.append(genusSubGenusPart);\r
 \r
-                               } else if (grandParent.getRankId() == R_GENUS) {\r
+                               } else if (grandParentRankId == R_GENUS) {\r
                                        \r
                                        String genusPart = genusPart(originalGenus, useOriginalGenus, \r
-                                                       genusOrUninomial.append(grandParent.getLocalName()));\r
+                                                       genusOrUninomial.append(grandParentName));\r
                                        nameCacheStringBuilder.append(genusPart);\r
 \r
                                }\r
+                               nameCacheStringBuilder.append(localName);\r
+                               specificEpithet.append(localName);\r
 \r
                        } else if (rank == R_SUBSPECIES) {\r
                                \r
-                               int greatGreatGrandParentId = grandParent.getParentId();\r
-                               FaunaEuropaeaTaxon greatGreatGrandParent = fauEuTaxonMap.get(greatGreatGrandParentId);\r
+                               String greatGreatGrandParentName = fauEuTaxon.getGreatGreatGrandParentName();\r
                                \r
-                               if(greatGrandParent.getRankId() == R_SUBGENUS) {\r
+                               if(greatGrandParentRankId == R_SUBGENUS) {\r
                                        \r
                                        String genusSubGenusPart = genusSubGenusPart(originalGenus, useOriginalGenus, \r
-                                                       genusOrUninomial.append(greatGreatGrandParent.getLocalName()), \r
-                                                       infraGenericEpithet.append(greatGrandParent.getLocalName()));\r
+                                                       genusOrUninomial.append(greatGreatGrandParentName), \r
+                                                       infraGenericEpithet.append(greatGrandParentName),\r
+                                                       fauEuTaxon);\r
                                        nameCacheStringBuilder.append(genusSubGenusPart);\r
                                        \r
-                               } else if (greatGrandParent.getRankId() == R_GENUS) {\r
+                               } else if (greatGrandParentRankId == R_GENUS) {\r
                                        \r
                                        String genusPart = genusPart(originalGenus, useOriginalGenus, \r
-                                                       genusOrUninomial.append(greatGreatGrandParent.getLocalName()));\r
+                                                       genusOrUninomial.append(greatGreatGrandParentName));\r
                                        nameCacheStringBuilder.append(genusPart);\r
                                }\r
                                \r
-                               nameCacheStringBuilder.append(grandParent.getLocalName());\r
+                               nameCacheStringBuilder.append(grandParentName);\r
                                nameCacheStringBuilder.append(" ");\r
-                               specificEpithet.append(grandParent.getLocalName());\r
+                               specificEpithet.append(grandParentName);\r
+                               nameCacheStringBuilder.append(localName);\r
+                               infraSpecificEpithet.append(localName);\r
                        }\r
                        \r
-                       nameCacheStringBuilder.append(fauEuTaxon.getLocalName());\r
-                       infraSpecificEpithet.append(fauEuTaxon.getLocalName());\r
+                       \r
                        \r
                }\r
                \r
@@ -619,58 +753,99 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
        \r
        /** Build taxon's name parts and caches */\r
        private String buildTaxonName(FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase, TaxonNameBase<?,?>taxonName,\r
-                       boolean useOriginalGenus, Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, FaunaEuropaeaImportConfigurator fauEuConfig) {\r
+                       boolean useOriginalGenus, FaunaEuropaeaImportConfigurator fauEuConfig) {\r
 \r
                /* Local taxon name string */\r
                String localString = "";\r
                /* Concatenated taxon name string */\r
                String completeString = "";\r
 \r
-               StringBuilder originalGenus = new StringBuilder(fauEuTaxon.getOriginalGenusName()); \r
+               StringBuilder originalGenus = new StringBuilder("");\r
+               \r
                StringBuilder genusOrUninomial = new StringBuilder();\r
                StringBuilder infraGenericEpithet = new StringBuilder(); \r
                StringBuilder specificEpithet = new StringBuilder();\r
                StringBuilder infraSpecificEpithet = new StringBuilder();\r
 \r
                localString = fauEuTaxon.getLocalName();\r
-\r
                int rank = fauEuTaxon.getRankId();\r
+               \r
+               // determine genus: this also works for cases of synonyms since the accepted taxon is its parent\r
+               String originalGenusString = null;\r
+               if (useOriginalGenus && ! "".equals(fauEuTaxon.getOriginalGenusName())) {\r
+                       originalGenusString  = fauEuTaxon.getOriginalGenusName();\r
+               } else {\r
+                       originalGenusString = determineOriginalGenus(fauEuTaxon);\r
+               }\r
+\r
+               if (originalGenusString != null) {\r
+                       originalGenus = new StringBuilder(originalGenusString);\r
+               }\r
 \r
                if(logger.isDebugEnabled()) { \r
                        logger.debug("Local taxon name (rank = " + rank + "): " + localString); \r
                }\r
 \r
                if (rank < R_SPECIES) {\r
+                       // subgenus or above\r
 \r
                        completeString = localString;\r
                        if (rank == R_SUBGENUS) {\r
+                               // subgenus part\r
                                infraGenericEpithet.append(localString);\r
+                               \r
+                               // genus part\r
+                               genusOrUninomial.append(originalGenus);\r
+                               \r
+                               completeString = originalGenus + " ("+ localString + ")";\r
                        } else {\r
+                               // genus or above\r
                                genusOrUninomial.append(localString);\r
                        }\r
                        \r
                } else {\r
+                       // species or below\r
 \r
                        taxonBase = taxonBase.deproxy(taxonBase, TaxonBase.class);\r
 \r
-//                     completeString = \r
-//                             buildLowerTaxonName(originalGenus, useOriginalGenus,\r
-//                                             genusOrUninomial, infraGenericEpithet, specificEpithet, infraSpecificEpithet,\r
-//                                             fauEuTaxon, fauEuTaxonMap);\r
-//                     \r
-//                     completeString = (String) CdmUtils.removeDuplicateWhitespace(completeString.trim());\r
+                       completeString = \r
+                               buildLowerTaxonName(originalGenus, useOriginalGenus, \r
+                                               genusOrUninomial, infraGenericEpithet, specificEpithet, infraSpecificEpithet,\r
+                                               fauEuTaxon);\r
+                       \r
+                       completeString = (String) CdmUtils.removeDuplicateWhitespace(completeString.trim());\r
 \r
                }\r
-               setCompleteTaxonName(completeString, useOriginalGenus,\r
+               return setCompleteTaxonName(completeString, useOriginalGenus,\r
                                genusOrUninomial.toString(), infraGenericEpithet.toString(), \r
                                specificEpithet.toString(), infraSpecificEpithet.toString(),\r
                                fauEuTaxon, taxonBase, fauEuConfig);\r
-               return completeString;\r
+                \r
        }\r
        \r
        \r
+       /**\r
+        * Determines the original genus name by searching the taxon with rank Genus.\r
+        * @param fauEuTaxon\r
+        * @return\r
+        */\r
+       private String determineOriginalGenus(FaunaEuropaeaTaxon fauEuTaxon) {\r
+               String originalGenus = null;\r
+\r
+               HashMap<Integer, String> ranks = new HashMap<Integer, String>();\r
+               ranks.put(fauEuTaxon.getParentRankId(), fauEuTaxon.getParentName());\r
+               ranks.put(fauEuTaxon.getGrandParentRankId(), fauEuTaxon.getGrandParentName());\r
+               ranks.put(fauEuTaxon.getGreatGrandParentRankId(), fauEuTaxon.getGreatGrandParentName());\r
+               ranks.put(fauEuTaxon.getGreatGreatGrandParentRankId(), fauEuTaxon.getGreatGreatGrandParentName());\r
+               ranks.put(fauEuTaxon.getGreatGreatGreatGrandParentRankId(), fauEuTaxon.getGreatGreatGreatGrandParentName());\r
+               \r
+               originalGenus = ranks.get(R_GENUS);\r
+\r
+               return originalGenus;\r
+       }\r
+\r
        /** Sets name parts and caches */\r
-       private boolean setCompleteTaxonName(String concatString, boolean useOriginalGenus,\r
+       private String setCompleteTaxonName(String concatString, boolean useOriginalGenus,\r
                        String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, \r
                        FaunaEuropaeaTaxon fauEuTaxon, TaxonBase<?> taxonBase, FaunaEuropaeaImportConfigurator fauEuConfig) {\r
 \r
@@ -680,71 +855,66 @@ public class FaunaEuropaeaTaxonNameImport extends FaunaEuropaeaImportBase  {
                ZoologicalName zooName = (ZoologicalName)taxonName;\r
                \r
                if (!genusOrUninomial.equals("")) {\r
-                       zooName.setGenusOrUninomial(genusOrUninomial);\r
+                       zooName.setGenusOrUninomial(emptyToNull(genusOrUninomial));\r
                        if (logger.isDebugEnabled()) { \r
                                logger.debug("genusOrUninomial: " + genusOrUninomial); \r
                        }\r
                }\r
-               if (!infraGenericEpithet.equals("")) {\r
-                       zooName.setInfraGenericEpithet(infraGenericEpithet);\r
+               \r
+               //if ((!infraGenericEpithet.equals("") && fauEuTaxon.isParenthesis()) || (!infraGenericEpithet.equals("") && fauEuTaxon.)) {\r
+               if (fauEuTaxon.getParentRankId() == R_SUBGENUS || fauEuTaxon.getRankId() == R_SUBGENUS ||\r
+                               fauEuTaxon.getGrandParentRankId() == R_SUBGENUS || fauEuTaxon.getGreatGrandParentRankId() == R_SUBGENUS) {\r
+                       zooName.setInfraGenericEpithet(emptyToNull(infraGenericEpithet));\r
                        if (logger.isDebugEnabled()) { \r
                                logger.debug("infraGenericEpithet: " + infraGenericEpithet); \r
                        }\r
                }\r
-               if (!specificEpithet.equals("")) {\r
-                       zooName.setSpecificEpithet(specificEpithet);\r
+               if ((fauEuTaxon.getRankId() == R_SPECIES || fauEuTaxon.getRankId() == R_SUBSPECIES)) {\r
+                       zooName.setSpecificEpithet(emptyToNull(specificEpithet));\r
                        if (logger.isDebugEnabled()) { \r
                                logger.debug("specificEpithet: " + specificEpithet); \r
                        }\r
                }\r
-               if (!infraSpecificEpithet.equals("")) {\r
-                       zooName.setInfraSpecificEpithet(infraSpecificEpithet);\r
+               if (fauEuTaxon.getRankId() == R_SUBSPECIES) {\r
+                       zooName.setInfraSpecificEpithet(emptyToNull(infraSpecificEpithet));\r
                        if (logger.isDebugEnabled()) { \r
                                logger.debug("infraSpecificEpithet: " + infraSpecificEpithet); \r
                        }\r
                }\r
-\r
-               zooName.setNameCache(concatString);\r
-               String titleCache = buildNameTitleCache(concatString, useOriginalGenus, fauEuTaxon);\r
-               zooName.setTitleCache(titleCache);\r
+               //TODO: use generate NameCache\r
+               //zooName.setNameCache(concatString);\r
+               String result = zooName.getNameCache();\r
+//             zooName.generateTitle();\r
+               //String titleCache = buildNameTitleCache(concatString, useOriginalGenus, fauEuTaxon);\r
+               //zooName.setTitleCache(titleCache);\r
                //titleCache = buildNameFullTitleCache(concatString, fauEuConfig);\r
-               zooName.setFullTitleCache(titleCache); // TODO: Add reference, NC status\r
+//             zooName.generateFullTitle();\r
+               //zooName.setFullTitleCache(titleCache); // TODO: Add reference, NC status\r
                \r
 //             ImportHelper.setOriginalSource(taxonName, fauEuConfig.getSourceReference(), \r
 //                             fauEuTaxon.getId(), "TaxonName");\r
-\r
-               titleCache = buildTaxonTitleCache(concatString, fauEuConfig.getSourceReference());\r
-               taxonBase.setTitleCache(titleCache);\r
-                       \r
+//             taxonBase.setSec(fauEuConfig.getSourceReference());\r
+//             taxonBase.generateTitle();\r
+               //titleCache = buildTaxonTitleCache(concatString, fauEuConfig.getSourceReference());\r
+               //taxonBase.setTitleCache(titleCache);\r
+               \r
                if (logger.isDebugEnabled()) { \r
-                       logger.debug("Name stored: " + concatString); \r
+                       logger.debug("Name stored: " + result); \r
                }\r
-               return success;\r
+               return result;\r
        }\r
 \r
-       \r
-       protected boolean saveTaxa(FaunaEuropaeaImportState state) {\r
-\r
-               boolean success = true;\r
-\r
-               Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();\r
-               MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);\r
-               TransactionStatus txStatus = null;\r
-\r
-               if(logger.isInfoEnabled()) { logger.info("Saving taxa ..."); }\r
-\r
-               if (state.getConfig().isUseTransactions()) {\r
-                       txStatus = startTransaction();\r
-               }\r
-\r
-               getTaxonService().saveTaxonAll(taxonStore.objects());\r
-\r
-               if (state.getConfig().isUseTransactions()) {\r
-                       commitTransaction(txStatus);\r
+       /**\r
+        * Ensures that empty strings are translated to null.\r
+        * @param genusOrUninomial\r
+        * @return\r
+        */\r
+       private String emptyToNull(String text) {\r
+               if (CdmUtils.isEmpty(text)) {\r
+                       return null;\r
+               } else {\r
+                       return text;\r
                }\r
-\r
-               return success;\r
        }\r
-       \r
 \r
 }\r