include "unknown" as language
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / berlinModel / in / BerlinModelCommonNamesImport.java
index 0c775539c4410a5197ab475384233658aa02b134..e95a9238904ac45d0ab073e2c2791fbe1104534f 100644 (file)
@@ -11,30 +11,44 @@ package eu.etaxonomy.cdm.io.berlinModel.in;
 \r
 import java.sql.ResultSet;\r
 import java.sql.SQLException;\r
+import java.util.ArrayList;\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
+import java.util.SortedSet;\r
+import java.util.TreeSet;\r
+import java.util.UUID;\r
 \r
+import org.apache.commons.lang.StringUtils;\r
 import org.apache.log4j.Logger;\r
 import org.springframework.stereotype.Component;\r
 \r
-import eu.etaxonomy.cdm.io.berlinModel.BerlinModelTransformer;\r
-import eu.etaxonomy.cdm.io.common.ICdmIO;\r
-import eu.etaxonomy.cdm.io.common.IImportConfigurator;\r
-import eu.etaxonomy.cdm.io.common.MapWrapper;\r
+import eu.etaxonomy.cdm.common.CdmUtils;\r
+import eu.etaxonomy.cdm.io.berlinModel.in.validation.BerlinModelCommonNamesImportValidator;\r
+import eu.etaxonomy.cdm.io.common.IOValidator;\r
+import eu.etaxonomy.cdm.io.common.ResultSetPartitioner;\r
 import eu.etaxonomy.cdm.io.common.Source;\r
+import eu.etaxonomy.cdm.model.common.Annotation;\r
+import eu.etaxonomy.cdm.model.common.AnnotationType;\r
 import eu.etaxonomy.cdm.model.common.CdmBase;\r
-import eu.etaxonomy.cdm.model.description.Distribution;\r
-import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;\r
+import eu.etaxonomy.cdm.model.common.DescriptionElementSource;\r
+import eu.etaxonomy.cdm.model.common.Extension;\r
+import eu.etaxonomy.cdm.model.common.ExtensionType;\r
+import eu.etaxonomy.cdm.model.common.Language;\r
+import eu.etaxonomy.cdm.model.common.Representation;\r
+import eu.etaxonomy.cdm.model.description.CommonTaxonName;\r
 import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
 import eu.etaxonomy.cdm.model.location.NamedArea;\r
 import eu.etaxonomy.cdm.model.location.TdwgArea;\r
-import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
+import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
+import eu.etaxonomy.cdm.model.reference.Reference;\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
 \r
 /**\r
+ * \r
  * @author a.mueller\r
  * @created 20.03.2008\r
  * @version 1.0\r
@@ -43,151 +57,639 @@ import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
 public class BerlinModelCommonNamesImport  extends BerlinModelImportBase {\r
        private static final Logger logger = Logger.getLogger(BerlinModelCommonNamesImport.class);\r
 \r
-       private static int modCount = 10000;\r
+       public static final UUID REFERENCE_LANGUAGE_ISO639_2_UUID = UUID.fromString("40c4f8dd-3d9c-44a4-b77a-76e137a89a5f");\r
+       public static final UUID REFERENCE_LANGUAGE_STRING_UUID = UUID.fromString("2a1b678f-c27d-48c1-b43e-98fd0d426305");\r
+       public static final UUID STATUS_ANNOTATION_UUID = UUID.fromString("e3f7b80a-1286-458d-812c-5e818f731968");\r
+       \r
+       public static final String NAMESPACE = "common name";\r
+       \r
+       \r
+       private static final String pluralString = "common names";\r
+       private static final String dbTableName = "emCommonName";\r
+\r
+\r
+       //map that stores the regions (named areas) and makes them accessible via the regionFk\r
+       private Map<String, NamedArea> regionMap = new HashMap<String, NamedArea>();\r
+\r
+       \r
 \r
        public BerlinModelCommonNamesImport(){\r
                super();\r
        }\r
        \r
+       \r
+\r
+       @Override\r
+       protected String getIdQuery() {\r
+               String result = " SELECT CommonNameId FROM emCommonName ";\r
+               return result;\r
+       }\r
+\r
+\r
+\r
        /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getRecordQuery(eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportConfigurator)\r
         */\r
        @Override\r
-       protected boolean doCheck(IImportConfigurator config){\r
+       protected String getRecordQuery(BerlinModelImportConfigurator config) {\r
+               String recordQuery = "";\r
+               recordQuery = \r
+                       " SELECT emCommonName.CommonNameId, emCommonName.CommonName, PTaxon.RIdentifier AS taxonId, emCommonName.PTNameFk, emCommonName.RefFk AS refId, emCommonName.Status, " + \r
+                               " emCommonName.RegionFks, emCommonName.MisNameRefFk, emCommonName.NameInSourceFk , emCommonName.Created_When, emCommonName.Updated_When, emCommonName.Created_Who, emCommonName.Updated_Who, emCommonName.Note as Notes," + \r
+                       " regionLanguage.Language AS regionLanguage, languageCommonName.Language, languageCommonName.LanguageOriginal, languageCommonName.ISO639_1, languageCommonName.ISO639_2, " + \r
+                       " emLanguageRegion.Region, emLanguageReference.RefFk as languageRefRefFk, emLanguageReference.ReferenceShort, " + \r
+                       " emLanguageReference.ReferenceLong, emLanguageReference.LanguageFk, languageReferenceLanguage.Language AS refLanguage, " +\r
+                       " languageReferenceLanguage.ISO639_2 AS refLanguageIso639_2, regionLanguage.ISO639_2 AS regionLanguageIso, " +\r
+                       " misappliedTaxon.RIdentifier AS misappliedTaxonId " + \r
+               " FROM emLanguage as regionLanguage RIGHT OUTER JOIN " + \r
+                       " emLanguageRegion ON regionLanguage.LanguageId = emLanguageRegion.LanguageFk RIGHT OUTER JOIN " +\r
+                       " emLanguage AS languageReferenceLanguage RIGHT OUTER JOIN " +\r
+                       " emLanguageReference ON languageReferenceLanguage.LanguageId = emLanguageReference.LanguageFk RIGHT OUTER JOIN " +\r
+                       " emCommonName INNER JOIN " +\r
+                       " PTaxon ON emCommonName.PTNameFk = PTaxon.PTNameFk AND emCommonName.PTRefFk = PTaxon.PTRefFk ON " + \r
+                       " emLanguageReference.ReferenceId = emCommonName.LanguageRefFk LEFT OUTER JOIN " +\r
+                       " emLanguage AS languageCommonName ON emCommonName.LanguageFk = languageCommonName.LanguageId ON " + \r
+                       " emLanguageRegion.RegionId = emCommonName.RegionFks LEFT OUTER JOIN " +\r
+                       " PTaxon as misappliedTaxon ON emCommonName.PTNameFk = misappliedTaxon.PTNameFk AND emCommonName.MisNameRefFk = misappliedTaxon.PTRefFk " + \r
+                       " WHERE emCommonName.CommonNameId IN (" + ID_LIST_TOKEN + ")";\r
+               return recordQuery;\r
+       }\r
+       \r
+       \r
+\r
+       @Override\r
+       protected boolean doInvoke(BerlinModelImportState state) {\r
                boolean result = true;\r
-               logger.warn("Checking for Occurrence not yet implemented");\r
-               //result &= checkArticlesWithoutJournal(bmiConfig);\r
-               //result &= checkPartOfJournal(bmiConfig);\r
-               \r
+               try {\r
+                       result &= makeRegions(state);\r
+               } catch (Exception e) {\r
+                       logger.error("Error when creating common name regions:" + e.getMessage());\r
+                       result = false;\r
+               }\r
+               result &= super.doInvoke(state);\r
                return result;\r
        }\r
+       \r
+       /**\r
+        * @param state \r
+        * \r
+        */\r
+       private boolean makeRegions(BerlinModelImportState state) {\r
+               boolean result = true;\r
+               try {\r
+                       SortedSet<Integer> regionFks = new TreeSet<Integer>();\r
+                       Source source = state.getConfig().getSource();\r
+                       \r
+                       result = getRegionFks(result, regionFks, source);\r
+                       //concat filter string\r
+                       String sqlWhere = getSqlWhere(regionFks);\r
+                       \r
+                       //get E+M - TDWG Mapping\r
+                       Map<String, String> emTdwgMap = getEmTdwgMap(source);\r
+                       //fill regionMap\r
+                       fillRegionMap(source, sqlWhere, emTdwgMap);\r
+                       \r
+                       return result;\r
+               } catch (NumberFormatException e) {\r
+                       e.printStackTrace();\r
+                       return false;\r
+               } catch (SQLException e) {\r
+                       e.printStackTrace();\r
+                       return false;\r
+               }\r
+       }\r
+\r
 \r
        /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IImportConfigurator, eu.etaxonomy.cdm.api.application.CdmApplicationController, java.util.Map)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#doPartition(eu.etaxonomy.cdm.io.berlinModel.in.ResultSetPartitioner, eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState)\r
         */\r
-       @Override\r
-       protected boolean doInvoke(BerlinModelImportState state){\r
-               \r
-               MapWrapper<TaxonBase> taxonMap = (MapWrapper<TaxonBase>)state.getStore(ICdmIO.TAXON_STORE);\r
-               MapWrapper<ReferenceBase> referenceMap = (MapWrapper<ReferenceBase>)state.getStore(ICdmIO.REFERENCE_STORE);\r
+       public boolean doPartition(ResultSetPartitioner partitioner, BerlinModelImportState state)  {\r
+               boolean success = true ;\r
                BerlinModelImportConfigurator config = state.getConfig();\r
+               Set<TaxonBase> taxaToSave = new HashSet<TaxonBase>();\r
+               Map<String, Taxon> taxonMap = (Map<String, Taxon>) partitioner.getObjectMap(BerlinModelTaxonImport.NAMESPACE);\r
+               Map<String, TaxonNameBase> taxonNameMap = (Map<String, TaxonNameBase>) partitioner.getObjectMap(BerlinModelTaxonNameImport.NAMESPACE);\r
                \r
-               if (true){\r
-                       return false;\r
-               }\r
-               \r
-               Set<TaxonBase> taxonStore = new HashSet<TaxonBase>();\r
-               Source source = config.getSource();\r
+               Map<String, Reference> biblioRefMap = (Map<String, Reference>) partitioner.getObjectMap(BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE);\r
+               Map<String, Reference> nomRefMap = (Map<String, Reference>) partitioner.getObjectMap(BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE);\r
                \r
-               String dbAttrName;\r
-               String cdmAttrName;\r
+               Map<String, Language> iso6392Map = new HashMap<String, Language>();\r
                \r
-               logger.info("start make occurrences ...");\r
+       //      logger.warn("MisappliedNameRefFk  not yet implemented for Common Names");\r
                \r
-               boolean delete = config.isDeleteAll();\r
-\r
-               try {\r
-                       //get data from database\r
-                       String strQuery = \r
-                                       " SELECT PTaxon.RIdentifier, emOccurrence.OccurrenceId, emOccurSumCat.emOccurSumCatId, emOccurSumCat.Short, emOccurSumCat.Description, " + \r
-                       " emOccurSumCat.OutputCode, emArea.AreaId, emArea.EMCode, emArea.ISOCode, emArea.TDWGCode, emArea.Unit, " + \r
-                       " emArea.Status, emArea.OutputOrder, emArea.eur, emArea.EuroMedArea " +\r
-                    " FROM emOccurrence INNER JOIN " + \r
-                       " emArea ON emOccurrence.AreaFk = emArea.AreaId INNER JOIN " +\r
-                       " PTaxon ON emOccurrence.PTNameFk = PTaxon.PTNameFk AND emOccurrence.PTRefFk = PTaxon.PTRefFk LEFT OUTER JOIN " +\r
-                        " emOccurSumCat ON emOccurrence.SummaryStatus = emOccurSumCat.emOccurSumCatId LEFT OUTER JOIN " + \r
-                        " emOccurrenceSource ON emOccurrence.OccurrenceId = emOccurrenceSource.OccurrenceFk " + \r
-                    " WHERE (1=1)";\r
-                       ResultSet rs = source.getResultSet(strQuery) ;\r
-\r
-                       int i = 0;\r
-                       //for each reference\r
+               ResultSet rs = partitioner.getResultSet();\r
+               try{\r
                        while (rs.next()){\r
+\r
+                               //create TaxonName element\r
+                               Object commonNameId = rs.getObject("CommonNameId");\r
+                               int taxonId = rs.getInt("taxonId");\r
+                               Object refId = rs.getObject("refId");\r
+                               Object ptNameFk = rs.getObject("PTNameFk");\r
+                               String commonNameString = rs.getString("CommonName");\r
+                               String iso639_2 = rs.getString("ISO639_2");\r
+                               String iso639_1 = rs.getString("ISO639_1");\r
+                               String languageString = rs.getString("Language");\r
+                               String originalLanguageString = rs.getString("LanguageOriginal");\r
+                               Object misNameRefFk = rs.getObject("MisNameRefFk");\r
+                               Object languageRefRefFk = rs.getObject("languageRefRefFk");\r
+                               String refLanguage = rs.getString("refLanguage");\r
+                               String refLanguageIso639_2 = rs.getString("refLanguageIso639_2");\r
+                               String status = rs.getString("Status");\r
+                               Object nameInSourceFk = rs.getObject("NameInSourceFk");\r
+                               Object misappliedTaxonId = rs.getObject("misappliedTaxonId");\r
                                \r
-                               if ((i++ % modCount) == 0 && i!= 1 ){ logger.info("Facts handled: " + (i-1));}\r
+                               //regions\r
+                               String region = rs.getString("Region");\r
+                               String regionFks  = rs.getString("RegionFks");\r
+                               String[] regionFkSplit = regionFks.split(",");\r
                                \r
-                               int occurrenceId = rs.getInt("OccurrenceId");\r
-                               int taxonId = rs.getInt("RIdentifier");\r
-                               String tdwgCode = rs.getString("TDWGCode");\r
-                               Integer emStatusId = (Integer)rs.getObject("emOccurSumCatId");\r
+                               //commonNameString\r
+                               if (CdmUtils.isEmpty(commonNameString)){\r
+                                       String message = "CommonName is empty or null. Do not import record for taxon " + taxonId;\r
+                                       logger.warn(message);\r
+                                       continue;\r
+                               }\r
                                \r
-                                       \r
-                               TaxonBase taxonBase = taxonMap.get(taxonId);\r
-                               if (taxonBase != null){\r
-                                       try {\r
-                                       \r
-                                               PresenceAbsenceTermBase<?> status = null;\r
-                                               if (emStatusId != null){\r
-                                                               status = BerlinModelTransformer.occStatus2PresenceAbsence(emStatusId);\r
-                                               }\r
-                                               \r
-                                               NamedArea tdwgArea = TdwgArea.getAreaByTdwgLabel(tdwgCode);\r
-                                               \r
-                                                       Taxon taxon;\r
-                                                       if ( taxonBase instanceof Taxon ) {\r
-                                                               taxon = (Taxon) taxonBase;\r
-                                                       }else{\r
-                                                               logger.warn("TaxonBase for Occurrence " + occurrenceId + " was not of type Taxon but: " + taxonBase.getClass().getSimpleName());\r
-                                                               continue;\r
-                                                       }\r
-                                                       \r
-                                                       if (tdwgArea != null){\r
-                                                               Distribution distribution = Distribution.NewInstance(tdwgArea, status);\r
-                                                               //TODO only one description per taxon (for all EM distributions)\r
-                                                               TaxonDescription taxonDescription = TaxonDescription.NewInstance();\r
-                                                               \r
-                                                               taxon.addDescription(taxonDescription);\r
-                                                               taxonStore.add(taxon);\r
-                                                       }\r
-                                                       \r
-                                               } catch (UnknownCdmTypeException e) {\r
-                                                       // TODO Auto-generated catch block\r
-                                                       e.printStackTrace();\r
-                                               }\r
-\r
-//                                             TODO\r
-//                                             sources\r
-//                                             references\r
+                               //taxon\r
+                               Taxon taxon = null;\r
+                               TaxonBase taxonBase = null;\r
+                               taxonBase  = taxonMap.get(String.valueOf(taxonId));\r
+                               if (taxonBase == null){\r
+                                       logger.warn("Taxon (" + taxonId + ") could not be found. Common name " + commonNameString + " not imported");\r
+                                       continue;\r
+                               }else if (! taxonBase.isInstanceOf(Taxon.class)){\r
+                                       logger.warn("taxon (" + taxonId + ") is not accepted. Can't import common name " +  commonNameId);\r
+                                       continue;\r
+                               }else{\r
+                                       taxon = CdmBase.deproxy(taxonBase, Taxon.class);\r
+                               }\r
                                \r
+                               //Language\r
+                               Language language = getAndHandleLanguage(iso6392Map, iso639_2, iso639_1, languageString, originalLanguageString);\r
+                               \r
+                               //CommonTaxonName\r
+                               List<CommonTaxonName> commonTaxonNames = new ArrayList<CommonTaxonName>();\r
+                               for (String regionFk : regionFkSplit){ \r
+                                       CommonTaxonName commonTaxonName;\r
+                                       if (commonTaxonNames.size() == 0){\r
+                                               commonTaxonName = CommonTaxonName.NewInstance(commonNameString, language);\r
+                                       }else{\r
+                                               commonTaxonName = (CommonTaxonName)commonTaxonNames.get(0).clone();\r
+                                       }\r
+                                       commonTaxonNames.add(commonTaxonName);\r
+                                       regionFk = regionFk.trim();\r
+                                       NamedArea area = regionMap.get(regionFk);\r
+                                       if (area == null){\r
+                                               logger.warn("Area for " + regionFk + " not defined.");\r
+                                       }else{\r
+                                               commonTaxonName.setArea(area);\r
+                                               TaxonDescription description = getDescription(taxon);\r
+                                               description.addElement(commonTaxonName);\r
+                                       }\r
+                               }\r
                                        \r
+                               //Reference/Source\r
+                               String strRefId = String.valueOf(refId);\r
+                               String languageRefFk = String.valueOf(languageRefRefFk);\r
+                               if (! CdmUtils.nullSafeEqual(strRefId, languageRefFk)){\r
+                                       logger.warn("CommonName.RefFk (" + CdmUtils.Nz(strRefId) + ") and LanguageReference.RefFk " + CdmUtils.Nz(languageRefFk) + " are not equal. I will import only languageRefFk");\r
+                               }\r
                                                \r
-//                                     //commonNames -> TODO move to separate IO\r
-//                                     String commonNameString;\r
-//                                     if (taxon.getName() != null){\r
-//                                             commonNameString = "Common " + taxon.getName().getTitleCache(); \r
-//                                     }else{\r
-//                                             commonNameString = "Common (null)";\r
-//                                     }\r
-//                                     Language language = bmiConfig.getFactLanguage();\r
-//                                     language = null;\r
-//                                     CommonTaxonName commonName = CommonTaxonName.NewInstance(commonNameString, language);\r
-//                                     taxonDescription.addElement(commonName);\r
+                               Reference reference = getReferenceOnlyFromMaps(biblioRefMap, nomRefMap, String.valueOf(languageRefRefFk));\r
+                               String microCitation = null;\r
+                               String originalNameString = null;\r
+                               \r
+                               TaxonNameBase nameUsedInSource = taxonNameMap.get(String.valueOf(nameInSourceFk));\r
+                               if (nameInSourceFk != null && nameUsedInSource == null){\r
+                                       logger.warn("Name used in source (" + nameInSourceFk + ") was not found");\r
+                               }\r
+                               DescriptionElementSource source = DescriptionElementSource.NewInstance(reference, microCitation, nameUsedInSource, originalNameString);\r
+                               for (CommonTaxonName commonTaxonName : commonTaxonNames){\r
+                                       commonTaxonName.addSource(source);\r
+                               }\r
+                               \r
+                               //MisNameRef\r
+                               if (misNameRefFk != null){\r
+                                       //Taxon misappliedName = getMisappliedName(biblioRefMap, nomRefMap, misNameRefFk, taxon);\r
+                                       Taxon misappliedName = null;\r
+                                       if (misappliedTaxonId != null){\r
+                                               misappliedName = taxonMap.get(String.valueOf(misappliedTaxonId));\r
+                                       }else{\r
+                                               TaxonNameBase taxonName = taxonNameMap.get(String.valueOf(ptNameFk));\r
+                                               Reference sec = getReferenceOnlyFromMaps(biblioRefMap, nomRefMap, String.valueOf(misNameRefFk));\r
+                                               if (taxonName == null || sec == null){\r
+                                                       logger.info("Taxon name or misapplied name reference is null for common name " + commonNameId);\r
+                                               }else{\r
+                                                       misappliedName = Taxon.NewInstance(taxonName, sec);\r
+                                                       taxaToSave.add(misappliedName);\r
+                                               }\r
+                                       }\r
+                                       if (misappliedName != null){\r
+                                               taxon.addMisappliedName(misappliedName, config.getSourceReference(), null);\r
+                                               TaxonDescription misappliedNameDescription = getDescription(misappliedName);\r
+                                               for (CommonTaxonName commonTaxonName : commonTaxonNames){\r
+                                                       CommonTaxonName commonNameClone = (CommonTaxonName)commonTaxonName.clone();\r
+                                                       misappliedNameDescription.addElement(commonNameClone);\r
+                                               }       \r
+                                       }else{\r
+                                               logger.warn("Misapplied name is null for common name " + commonNameId);\r
+                                       }\r
                                        \r
+                               }\r
+                               \r
+                               \r
+                               //reference extensions\r
+                               if (reference != null){\r
+                                       if (CdmUtils.isNotEmpty(refLanguage)){\r
+                                               ExtensionType refLanguageExtensionType = getExtensionType( state, REFERENCE_LANGUAGE_STRING_UUID, "reference language","The language of the reference","ref. lang.");\r
+                                               Extension.NewInstance(reference, refLanguage, refLanguageExtensionType);\r
+                                       }\r
                                        \r
+                                       if (CdmUtils.isNotEmpty(refLanguageIso639_2)){\r
+                                               ExtensionType refLanguageIsoExtensionType = getExtensionType( state, REFERENCE_LANGUAGE_ISO639_2_UUID, "reference language iso 639-2","The iso 639-2 code of the references language","ref. lang. 639-2");\r
+                                               Extension.NewInstance(reference, refLanguageIso639_2, refLanguageIsoExtensionType);\r
+                                       }\r
+                               }else if (CdmUtils.isNotEmpty(refLanguage) || CdmUtils.isNotEmpty(refLanguageIso639_2)){\r
+                                       logger.warn("Reference is null (" + languageRefRefFk + ") but refLanguage (" + CdmUtils.Nz(refLanguage) + ") or iso639_2 (" + CdmUtils.Nz(refLanguageIso639_2) + ") was not null");\r
+                               }\r
+                               \r
+                               //status\r
+                               if (CdmUtils.isNotEmpty(status)){\r
+                                       AnnotationType statusAnnotationType = getAnnotationType( state, STATUS_ANNOTATION_UUID, "status","The status of this object","status");\r
+                                       Annotation annotation = Annotation.NewInstance(status, statusAnnotationType, Language.DEFAULT());\r
+                                       for (CommonTaxonName commonTaxonName : commonTaxonNames){\r
+                                               commonTaxonName.addAnnotation(annotation);\r
+                                       }\r
                                        \r
-                               }else{\r
-                                       //TODO\r
-                                       logger.warn("Taxon for Fact " + occurrenceId + " does not exist in store");\r
                                }\r
-                               //put\r
+                               \r
+                               //Notes\r
+                               for (CommonTaxonName commonTaxonName : commonTaxonNames){\r
+                                       doIdCreatedUpdatedNotes(state, commonTaxonName, rs, String.valueOf(commonNameId), NAMESPACE);\r
+                               }\r
+                               partitioner.startDoSave();\r
+                               taxaToSave.add(taxon);\r
+\r
                        }\r
-                       logger.info("Taxa to save: " + taxonStore.size());\r
-                       getTaxonService().saveTaxonAll(taxonStore);     \r
-                       \r
-                       logger.info("end make occurrences ...");\r
-                       return true;\r
                } catch (SQLException e) {\r
                        logger.error("SQLException:" +  e);\r
                        return false;\r
+               } catch (ClassCastException e) {\r
+                       e.printStackTrace();\r
+               }       \r
+                       \r
+               //      logger.info( i + " names handled");\r
+               getTaxonService().save(taxaToSave);\r
+               return success;\r
+\r
+       }\r
+\r
+\r
+\r
+       /**\r
+        * Not used anymore. Use MisappliedName RIdentifier instead\r
+        * @param biblioRefMap\r
+        * @param nomRefMap\r
+        * @param misNameRefFk\r
+        * @param taxon\r
+        */\r
+       private boolean isFirstMisappliedName = true;\r
+       private Taxon getMisappliedName(Map<String, Reference> biblioRefMap, Map<String, Reference> nomRefMap, \r
+                       Object misNameRefFk, Taxon taxon) {\r
+               Taxon misappliedTaxon = null;\r
+               Reference misNameRef = getReferenceOnlyFromMaps(biblioRefMap, nomRefMap, String.valueOf(misNameRefFk));\r
+               misappliedTaxon = Taxon.NewInstance(taxon.getName(), misNameRef);\r
+               Set<String> includeProperty = new HashSet<String>();\r
+               try {\r
+//                     //IMatchStrategy matchStrategy = DefaultMatchStrategy.NewInstance(TaxonBase.class);\r
+//                     //List<TaxonBase> misappliedList1 = getCommonService().findMatching(misappliedTaxon, matchStrategy);\r
+                       List<TaxonBase> misappliedList = getTaxonService().list(misappliedTaxon, includeProperty, null, null, null, null);\r
+                       if (misappliedList.size() > 0){\r
+                               misappliedTaxon = CdmBase.deproxy(misappliedList.get(0), Taxon.class);\r
+                       }\r
+               } catch (ClassCastException e) {\r
+                       logger.error(e.getMessage());\r
+                       if (isFirstMisappliedName){\r
+                               e.printStackTrace();\r
+                               isFirstMisappliedName = false;\r
+                       }\r
                }\r
+               return misappliedTaxon;\r
+       }\r
+\r
 \r
+\r
+       /**\r
+        * @param iso6392Map\r
+        * @param iso639_2\r
+        * @param languageString\r
+        * @param originalLanguageString\r
+        * @return\r
+        */\r
+       private Language getAndHandleLanguage(Map<String, Language> iso639Map,  String iso639_2, String iso639_1, String languageString, String originalLanguageString) {\r
+               Language language;\r
+               if (CdmUtils.isNotEmpty(iso639_2)|| CdmUtils.isNotEmpty(iso639_1)  ){\r
+                       //TODO test performance, implement in state\r
+                       language = getLanguageFromIsoMap(iso639Map, iso639_2, iso639_1);\r
+                       \r
+                       if (language == null){\r
+                               language = getTermService().getLanguageByIso(iso639_2);\r
+                               iso639Map.put(iso639_2, language);\r
+                               if (language == null){\r
+                                       language = getTermService().getLanguageByIso(iso639_1);\r
+                                       iso639Map.put(iso639_1, language);\r
+                               }\r
+                               if (language == null){\r
+                                       logger.warn("Language for code ISO693-2 '" + iso639_2 + "' and ISO693-1 '" + iso639_1 + "' was not found");\r
+                               }\r
+                       }\r
+               } else if ("unknown".equals(languageString)){\r
+                       language = Language.UNKNOWN_LANGUAGE();\r
+               }else{\r
+                       logger.warn("language ISO 639_1 and ISO 639_2 were empty for " + languageString);\r
+                       language = null;\r
+               }\r
+               addOriginalLanguage(language, originalLanguageString);\r
+               return language;\r
+       }\r
+\r
+\r
+       /**\r
+        * @param iso639Map\r
+        * @param iso639_2\r
+        * @param iso639_1\r
+        * @return\r
+        */\r
+       private Language getLanguageFromIsoMap(Map<String, Language> iso639Map, String iso639_2, String iso639_1) {\r
+               Language language;\r
+               language = iso639Map.get(iso639_2);\r
+               if (language == null){\r
+                       language = iso639Map.get(iso639_1);\r
+               }\r
+               return language;\r
+       }\r
+\r
+       /**\r
+        * @param language\r
+        * @param originalLanguageString\r
+        */\r
+       private void addOriginalLanguage(Language language,     String originalLanguageString) {\r
+               if (CdmUtils.isEmpty(originalLanguageString)){\r
+                       return;\r
+               }else if (language == null){\r
+                       logger.warn("Language could not be defined, but originalLanguageString exists: " + originalLanguageString);\r
+               }else {\r
+                       Representation representation = language.getRepresentation(language);\r
+                       if (representation == null){\r
+                               language.addRepresentation(Representation.NewInstance(originalLanguageString, originalLanguageString, originalLanguageString, language));\r
+                               getTermService().saveOrUpdate(language);\r
+                       }\r
+               }\r
+               \r
+       }\r
+       \r
+\r
+\r
+       /**\r
+        * @param result\r
+        * @param regionFks\r
+        * @param source\r
+        * @return\r
+        * @throws SQLException\r
+        */\r
+       private boolean getRegionFks(boolean result, SortedSet<Integer> regionFks,\r
+                       Source source) throws SQLException {\r
+               String sql = " SELECT DISTINCT RegionFks FROM emCommonName";\r
+               ResultSet rs = source.getResultSet(sql);\r
+               while (rs.next()){\r
+                       String strRegionFks = rs.getString("RegionFks"); \r
+                       String[] regionFkArray = strRegionFks.split(",");\r
+                       for (String regionFk: regionFkArray){\r
+                               regionFk = regionFk.trim();\r
+                               if (! StringUtils.isNumeric(regionFk) || "".equals(regionFk)  ){\r
+                                       result = false;\r
+                                       logger.warn("RegionFk is not numeric: " + regionFk);\r
+                               }else{\r
+                                       regionFks.add(Integer.valueOf(regionFk));\r
+                               }\r
+                       }\r
+               }\r
+               return result;\r
+       }\r
+\r
+\r
+\r
+       /**\r
+        * @param source\r
+        * @param sqlWhere\r
+        * @param emTdwgMap\r
+        * @throws SQLException\r
+        */\r
+       private void fillRegionMap(Source source, String sqlWhere,\r
+                       Map<String, String> emTdwgMap) throws SQLException {\r
+               String sql;\r
+               ResultSet rs;\r
+               sql = " SELECT RegionId, Region FROM emLanguageRegion WHERE RegionId IN ("+ sqlWhere+ ") ";\r
+               rs = source.getResultSet(sql);\r
+               while (rs.next()){\r
+                       Object regionId = rs.getObject("RegionId");\r
+                       String region = rs.getString("Region");\r
+                       String[] splitRegion = region.split("-");\r
+                       if (splitRegion.length <= 1){\r
+                               NamedArea newArea = NamedArea.NewInstance(region, region, null);\r
+                               getTermService().save(newArea);\r
+                               regionMap.put(String.valueOf(regionId), newArea);\r
+                               logger.warn("Found new area: " +  region);\r
+                       }else if (splitRegion.length == 2){\r
+                               String emCode = splitRegion[1].trim();\r
+                               String tdwgCode = emTdwgMap.get(emCode);\r
+                               if (StringUtils.isNotBlank(tdwgCode) ){\r
+                                       NamedArea tdwgArea = getNamedArea(tdwgCode);\r
+                                       regionMap.put(String.valueOf(regionId), tdwgArea);\r
+                               }else{\r
+                                       logger.warn("emCode did not map to valid tdwgCode: " +  CdmUtils.Nz(emCode) + "->" + CdmUtils.Nz(tdwgCode));\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+\r
+       /**\r
+        * @param tdwgCode\r
+        */\r
+       private NamedArea getNamedArea(String tdwgCode) {\r
+               NamedArea area;\r
+               if (tdwgCode.equalsIgnoreCase("Ab")){\r
+                       area = NamedArea.NewInstance("Azerbaijan (including Nakhichevan)", "Azerbaijan & Nakhichevan", "Ab");\r
+                       getTermService().save(area);\r
+               }else if (tdwgCode.equalsIgnoreCase("Rf")){\r
+                       area = NamedArea.NewInstance("The Russian Federation", "The Russian Federation", "Rf");\r
+                       getTermService().save(area);\r
+               }else if (tdwgCode.equalsIgnoreCase("Uk")){\r
+                       area = NamedArea.NewInstance("Ukraine (including Crimea)", "Ukraine & Crimea", "Uk");\r
+                       getTermService().save(area);\r
+               }else{\r
+                       area = TdwgArea.getAreaByTdwgAbbreviation(tdwgCode);\r
+               }\r
+               return area;\r
+       }\r
+\r
+\r
+\r
+       /**\r
+        * @param regionFks\r
+        * @return\r
+        */\r
+       private String getSqlWhere(SortedSet<Integer> regionFks) {\r
+               String sqlWhere = "";\r
+               for (Integer regionFk : regionFks){\r
+                       sqlWhere += regionFk + ","; \r
+               }\r
+               sqlWhere = sqlWhere.substring(0, sqlWhere.length()-1);\r
+               return sqlWhere;\r
+       }\r
+\r
+\r
+\r
+       /**\r
+        * @param source\r
+        * @throws SQLException\r
+        */\r
+       private Map<String, String> getEmTdwgMap(Source source) throws SQLException {\r
+               String sql;\r
+               ResultSet rs;\r
+               Map<String, String> emTdwgMap = new HashMap<String, String>();\r
+               sql = " SELECT EmCode, TDWGCode FROM emArea ";\r
+               rs = source.getResultSet(sql);\r
+               while (rs.next()){\r
+                       String emCode = rs.getString("EMCode");\r
+                       String TDWGCode = rs.getString("TDWGCode");\r
+                       if (StringUtils.isNotBlank(emCode) ){\r
+                               emCode = emCode.trim();\r
+                               if (emCode.equalsIgnoreCase("Ab") || emCode.equalsIgnoreCase("Rf")|| emCode.equalsIgnoreCase("Uk") ){\r
+                                       emTdwgMap.put(emCode, emCode);\r
+                               }else if (StringUtils.isNotBlank(TDWGCode)){\r
+                                       emTdwgMap.put(emCode, TDWGCode.trim());\r
+                               }\r
+                       }\r
+               }\r
+               return emTdwgMap;\r
+       }\r
+\r
+\r
+\r
+\r
+       /**\r
+        * Returns the first non-image gallery description. Creates a new one if no description exists.\r
+        * @param taxon\r
+        * @return\r
+        */\r
+       private TaxonDescription getDescription(Taxon taxon) {\r
+               TaxonDescription result = null;\r
+               for (TaxonDescription taxonDescription : taxon.getDescriptions()){\r
+                       if (! taxonDescription.isImageGallery()){\r
+                               result = taxonDescription;\r
+                       }\r
+               }\r
+               if (result == null){\r
+                       result = TaxonDescription.NewInstance(taxon);\r
+               }\r
+               return result;\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getRelatedObjectsForPartition(java.sql.ResultSet)\r
+        */\r
+       public Map<Object, Map<String, ? extends CdmBase>> getRelatedObjectsForPartition(ResultSet rs) {\r
+               String nameSpace;\r
+               Class cdmClass;\r
+               Set<String> idSet;\r
+               Map<Object, Map<String, ? extends CdmBase>> result = new HashMap<Object, Map<String, ? extends CdmBase>>();\r
+               \r
+               try{\r
+                       Set<String> taxonIdSet = new HashSet<String>();\r
+                       Set<String> nameIdSet = new HashSet<String>();\r
+                       Set<String> referenceIdSet = new HashSet<String>();\r
+                       while (rs.next()){\r
+                               handleForeignKey(rs, taxonIdSet, "taxonId");\r
+                               handleForeignKey(rs, taxonIdSet, "misappliedTaxonId");\r
+                               handleForeignKey(rs, referenceIdSet, "refId");\r
+                               handleForeignKey(rs, referenceIdSet, "languageRefRefFk");\r
+                               handleForeignKey(rs, nameIdSet, "NameInSourceFk");\r
+                               handleForeignKey(rs, nameIdSet, "PTNameFk");\r
+                               handleForeignKey(rs, referenceIdSet, "MisNameRefFk");\r
+                       }\r
+                       \r
+                       //name map\r
+                       nameSpace = BerlinModelTaxonNameImport.NAMESPACE;\r
+                       cdmClass = TaxonNameBase.class;\r
+                       idSet = nameIdSet;\r
+                       Map<String, TaxonNameBase> nameMap = (Map<String, TaxonNameBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, nameMap);\r
+\r
+                       //name map\r
+                       nameSpace = BerlinModelTaxonImport.NAMESPACE;\r
+                       cdmClass = Taxon.class;\r
+                       idSet = taxonIdSet;\r
+                       Map<String, TaxonNameBase> taxonMap = (Map<String, TaxonNameBase>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, taxonMap);\r
+\r
+                       //nom reference map\r
+                       nameSpace = BerlinModelReferenceImport.NOM_REFERENCE_NAMESPACE;\r
+                       cdmClass = Reference.class;\r
+                       idSet = referenceIdSet;\r
+                       Map<String, Reference> nomReferenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, nomReferenceMap);\r
+\r
+                       //biblio reference map\r
+                       nameSpace = BerlinModelReferenceImport.BIBLIO_REFERENCE_NAMESPACE;\r
+                       cdmClass = Reference.class;\r
+                       idSet = referenceIdSet;\r
+                       Map<String, Reference> biblioReferenceMap = (Map<String, Reference>)getCommonService().getSourcedObjectsByIdInSource(cdmClass, idSet, nameSpace);\r
+                       result.put(nameSpace, biblioReferenceMap);\r
+\r
+               } catch (SQLException e) {\r
+                       throw new RuntimeException(e);\r
+               } catch (NullPointerException nep){\r
+                       logger.error("NullPointerException in getRelatedObjectsForPartition()");\r
+               }\r
+               return result;\r
+       }\r
+               \r
+\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)\r
+        */\r
+       @Override\r
+       protected boolean doCheck(BerlinModelImportState state){\r
+               IOValidator<BerlinModelImportState> validator = new BerlinModelCommonNamesImportValidator();\r
+               return validator.validate(state);\r
+       }\r
+                                               \r
+                                               \r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getTableName()\r
+        */\r
+       @Override\r
+       protected String getTableName() {\r
+               return dbTableName;\r
+       }\r
+                                                       \r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportBase#getPluralString()\r
+        */\r
+       @Override\r
+       public String getPluralString() {\r
+               return pluralString;\r
        }\r
 \r
        /* (non-Javadoc)\r
         * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)\r
         */\r
-       protected boolean isIgnore(IImportConfigurator config){\r
-               return ! config.isDoOccurrence();\r
+       protected boolean isIgnore(BerlinModelImportState state){\r
+               return ! state.getConfig().isDoCommonNames();\r
        }\r
-       \r
+\r
 }\r