correcting utf8 chars
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / eflora / EfloraTaxonImport.java
index b56846710ed0cbee123fd4bdb8c24d42d745d22a..f8d6d620554c9db078fd02a3f57e5ecfba193034 100644 (file)
@@ -33,6 +33,7 @@ import eu.etaxonomy.cdm.common.XmlHelp;
 import eu.etaxonomy.cdm.io.common.ICdmIO;\r
 import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;\r
 import eu.etaxonomy.cdm.io.eflora.UnmatchedLeads.UnmatchedLeadsKey;\r
+import eu.etaxonomy.cdm.model.agent.Person;\r
 import eu.etaxonomy.cdm.model.agent.Team;\r
 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;\r
 import eu.etaxonomy.cdm.model.common.AnnotatableEntity;\r
@@ -47,6 +48,7 @@ import eu.etaxonomy.cdm.model.common.Marker;
 import eu.etaxonomy.cdm.model.common.MarkerType;\r
 import eu.etaxonomy.cdm.model.common.Representation;\r
 import eu.etaxonomy.cdm.model.common.TimePeriod;\r
+import eu.etaxonomy.cdm.model.description.CommonTaxonName;\r
 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
 import eu.etaxonomy.cdm.model.description.Feature;\r
 import eu.etaxonomy.cdm.model.description.FeatureNode;\r
@@ -281,6 +283,8 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                                lastEntity = handleTaxonNotes(state, element, taxon);\r
                        }else if(elName.equalsIgnoreCase("chromosomes")){\r
                                lastEntity = handleChromosomes(state, element, taxon);\r
+                       }else if(elName.equalsIgnoreCase("vernacularnames")){\r
+                               handleVernaculars(state, element, taxon);\r
                        }else if(elName.equalsIgnoreCase("key")){\r
                                lastEntity = handleKeys(state, element, taxon);\r
                        }else if(elName.equalsIgnoreCase("references")){\r
@@ -297,11 +301,55 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
        }\r
        \r
        \r
+       private void handleVernaculars(EfloraImportState state, Element elVernacular, Taxon taxon) {\r
+               verifyNoAttribute(elVernacular);\r
+               verifyNoChildren(elVernacular, false);\r
+               String value = elVernacular.getTextNormalize();\r
+               Feature feature = Feature.COMMON_NAME();\r
+               value = replaceStart(value, "Noms vernaculaires");\r
+               String[] dialects = value.split(";");\r
+               for (String singleDialect : dialects){\r
+                       handleSingleDialect(taxon, singleDialect, feature, state);\r
+               }\r
+               return;\r
+       }\r
+\r
+\r
+       private void handleSingleDialect(Taxon taxon, String singleDialect, Feature feature, EfloraImportState state) {\r
+               singleDialect = singleDialect.trim();\r
+               TaxonDescription description = getDescription(taxon);\r
+               String reDialect = "\\(dial\\.\\s.*\\)";\r
+//             String reDialect = "\\(.*\\)";\r
+               Pattern patDialect = Pattern.compile(reDialect);\r
+               Matcher matcher = patDialect.matcher(singleDialect);\r
+               if (matcher.find()){\r
+                       String dialect = singleDialect.substring(matcher.start(), matcher.end());\r
+                       dialect = dialect.replace("(dial. ", "").replace(")", "");\r
+                       \r
+                       Language language = null;\r
+                       try {\r
+                               language = this.getLanguage(state, state.getTransformer().getLanguageUuid(dialect), dialect, dialect, dialect);\r
+                       } catch (UndefinedTransformerMethodException e) {\r
+                               logger.error(e.getMessage());\r
+                       }\r
+                       \r
+                       String commonNames = singleDialect.substring(0, matcher.start());\r
+                       String[] splitNames = commonNames.split(",");\r
+                       for (String commonNameString : splitNames){\r
+                               commonNameString = commonNameString.trim();\r
+                               CommonTaxonName commonName = CommonTaxonName.NewInstance(commonNameString, language);\r
+                               description.addElement(commonName);\r
+                       }\r
+               }else{\r
+                       logger.warn("No dialect match: " +  singleDialect);\r
+               }\r
+       }\r
+\r
+\r
        private void handleReferences(EfloraImportState state, Element elReferences, Taxon taxon, AnnotatableEntity lastEntity) {\r
                verifyNoAttribute(elReferences);\r
                verifyNoChildren(elReferences, true);\r
                String refString = elReferences.getTextNormalize(); \r
-//             refString = replaceStart(replaceStart(refString, "References:"), "Sources:");\r
                if (lastEntity == null){\r
                        logger.warn("No last entity defined: " + refString);\r
                        return;\r
@@ -309,22 +357,6 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                \r
                Annotation annotation = Annotation.NewInstance(refString, AnnotationType.EDITORIAL(), Language.DEFAULT());\r
                lastEntity.addAnnotation(annotation);\r
-\r
-//             ReferenceBase ref = ReferenceFactory.newGeneric();\r
-//             ref.setTitleCache(refString, true);\r
-//             if (lastEntity instanceof DescriptionElementBase){\r
-//                     DescriptionElementSource source = DescriptionElementSource.NewInstance(ref, null);\r
-//                     CdmBase.deproxy(lastEntity, DescriptionElementBase.class).addSource(source);\r
-//             }else if (lastEntity instanceof IdentifiableEntity){\r
-//                     IdentifiableSource source = IdentifiableSource.NewInstance(ref, null);\r
-//                     CdmBase.deproxy(lastEntity, IdentifiableEntity.class).addSource(source);\r
-//             }\r
-//             else{\r
-//                     logger.warn("lastEntity type not supported: " + lastEntity.getClass().getName());\r
-//             }\r
-               \r
-               logger.info("References need to be moved to their parent");\r
-\r
        }\r
 \r
 \r
@@ -639,7 +671,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                String chromosomesPart = getChromosomesPart(value);\r
                String references = value.replace(chromosomesPart, "").trim();\r
                chromosomesPart = chromosomesPart.replace(":", "").trim();\r
-               return addDescriptionElement(taxon, chromosomesPart, chromosomeFeature, references);    \r
+               return addDescriptionElement(state, taxon, chromosomesPart, chromosomeFeature, references);     \r
        }\r
 \r
 \r
@@ -723,8 +755,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
         * @param attribute\r
         * @return\r
         */\r
-       private TextData handleDescriptiveElement(EfloraImportState state,\r
-                       Element element, Taxon taxon, String classValue) {\r
+       private TextData handleDescriptiveElement(EfloraImportState state, Element element, Taxon taxon, String classValue) {\r
                TextData result = null;\r
                Feature feature = getFeature(classValue, state);\r
                if (feature == null){\r
@@ -733,7 +764,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                        String value = element.getValue();\r
                        value = replaceStart(value, "Notes");\r
                        value = replaceStart(value, "Note");\r
-                       result = addDescriptionElement(taxon, value, feature, null);\r
+                       result = addDescriptionElement(state, taxon, value, feature, null);\r
                }\r
                return result;\r
        }\r
@@ -757,7 +788,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                String value = element.getTextNormalize();\r
                value = replaceStart(value, "Uses");\r
                Feature feature = Feature.USES();\r
-               return addDescriptionElement(taxon, value, feature, null);\r
+               return addDescriptionElement(state, taxon, value, feature, null);\r
                \r
        }\r
 \r
@@ -775,7 +806,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                value = replaceStart(value, "Distribution");\r
                Feature feature = Feature.DISTRIBUTION();\r
                //distribution parsing almost impossible as there is lots of freetext in the distribution tag\r
-               return addDescriptionElement(taxon, value, feature, null);\r
+               return addDescriptionElement(state, taxon, value, feature, null);\r
        }\r
 \r
 \r
@@ -797,7 +828,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                        value = replaceStart(value, "Habitat");\r
                        feature = getFeature("Habitat", state);\r
                }\r
-               return addDescriptionElement(taxon, value, feature, null);\r
+               return addDescriptionElement(state, taxon, value, feature, null);\r
        }\r
 \r
 \r
@@ -810,13 +841,26 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                if (value.startsWith(replacementString) ){\r
                        value = value.substring(replacementString.length()).trim();\r
                }\r
-               if (value.startsWith("-") ){\r
+               while (value.startsWith("-") || value.startsWith("–") ){\r
                        value = value.substring("-".length()).trim();\r
                }\r
                return value;\r
        }\r
 \r
 \r
+       /**\r
+        * @param value\r
+        * @param replacementString\r
+        */\r
+       protected String removeTrailing(String value, String replacementString) {\r
+               if (value == null){\r
+                       return null;\r
+               }\r
+               if (value.endsWith(replacementString) ){\r
+                       value = value.substring(0, value.length() - replacementString.length()).trim();\r
+               }\r
+               return value;\r
+       }\r
 \r
        /**\r
         * @param state\r
@@ -906,9 +950,9 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                \r
                List<Element> elements = elNom.getChildren();\r
                for (Element element : elements){\r
-                       if (element.getName().equals("name")){\r
+                       if (element.getName().equals("name") || element.getName().equals("homonym") ){\r
                                if (taxonBaseClassType == false){\r
-                                       logger.warn("Name tag not allowed in non taxon nom tag");\r
+                                       logger.warn("Name or homonym tag not allowed in non taxon nom tag");\r
                                }\r
                        }else{\r
                                unhandledNomChildren.add(element.getName());\r
@@ -925,13 +969,10 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
         * @param taxon\r
         * @param homotypicalGroup \r
         */\r
-       private void handleTypeRef(EfloraImportState state, Element elNom, Taxon taxon, HomotypicalGroup homotypicalGroup) {\r
+       protected void handleTypeRef(EfloraImportState state, Element elNom, Taxon taxon, HomotypicalGroup homotypicalGroup) {\r
                verifyNoChildren(elNom);\r
                String typeRef = elNom.getTextNormalize();\r
-               typeRef = replaceStart(typeRef, "-");\r
-               typeRef = replaceStart(typeRef, "\97");\r
-               typeRef = replaceStart(typeRef, "\u002d");\r
-               typeRef = replaceStart(typeRef, "\u2013");\r
+               typeRef = removeStartingTypeRefMinus(typeRef);\r
                \r
                String[] split = typeRef.split(":");\r
                if (split.length < 2){\r
@@ -959,6 +1000,20 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                }\r
        }\r
 \r
+\r
+       /**\r
+        * @param typeRef\r
+        * @return\r
+        */\r
+       protected String removeStartingTypeRefMinus(String typeRef) {\r
+               typeRef = replaceStart(typeRef, "-");\r
+               typeRef = replaceStart(typeRef, "—");\r
+               typeRef = replaceStart(typeRef, "\u002d");\r
+               typeRef = replaceStart(typeRef, "\u2013");\r
+               typeRef = replaceStart(typeRef, "--");\r
+               return typeRef;\r
+       }\r
+\r
        /**\r
         * @param typeType\r
         * @param typeText\r
@@ -979,7 +1034,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                //create name\r
                BotanicalName nameType = (BotanicalName)parser.parseFullName(typeText, NomenclaturalCode.ICBN, Rank.SPECIES());\r
                ((NameTypeDesignation) typeDesignation).setTypeName(nameType);\r
-               //TODO wie können NameTypes den Namen zugeordnet werden? -  wird aber vom Portal via NameCache matching gemacht\r
+               //TODO wie können NameTypes den Namen zugeordnet werden? -  wird aber vom Portal via NameCache matching gemacht\r
        }\r
 \r
 \r
@@ -996,7 +1051,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
         * @param typeText\r
         * @param typeDesignation\r
         */\r
-       private void makeSpecimenTypeDesignation(StringBuffer typeType, String typeText, TypeDesignationBase typeDesignation) {\r
+       protected void makeSpecimenTypeDesignation(StringBuffer typeType, String typeText, TypeDesignationBase typeDesignation) {\r
                if (typeType.toString().trim().equalsIgnoreCase("Type")){\r
                        //do nothing\r
                }else if (typeType.toString().trim().equalsIgnoreCase("Neotype") || typeType.toString().trim().equalsIgnoreCase("Neotypes")){\r
@@ -1138,7 +1193,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                                        logger.warn("Unhandled name class: " +  classValue);\r
                                }\r
                        }else if(element.getName().equals("homonym")){\r
-                               handleHomonym(element, name);\r
+                               handleHomonym(state, element, name);\r
                        }else{\r
                                // child element is not "name"\r
                                unhandledNomChildren.add(element.getName());\r
@@ -1162,7 +1217,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                }\r
                \r
                //test nom element has no text\r
-               if (StringUtils.isNotBlank(elNom.getTextNormalize().replace("\97", "").replace("\u002d","").replace("\u2013", ""))){\r
+               if (StringUtils.isNotBlank(elNom.getTextNormalize().replace("", "").replace("\u002d","").replace("\u2013", ""))){\r
                        String strElNom = elNom.getTextNormalize();\r
                        if ("?".equals(strElNom)){\r
                                handleQuestionMark(name, taxon);\r
@@ -1188,7 +1243,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
 \r
 \r
        //merge with handleNomTaxon     \r
-       private void handleHomonym(Element elHomonym, NonViralName upperName) {\r
+       private void handleHomonym(EfloraImportState state, Element elHomonym, NonViralName upperName) {\r
                verifyNoAttribute(elHomonym);\r
                \r
                //hommonym name\r
@@ -1207,6 +1262,8 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                                homonymName.setSpecificEpithet(value);\r
                        }else if (classValue.equalsIgnoreCase("author")){\r
                                handleNameAuthors(elName, homonymName);\r
+                       }else if (classValue.equalsIgnoreCase("paraut")){\r
+                               handleBasionymAuthor(state, elName, homonymName, true);\r
                        }else if (classValue.equalsIgnoreCase("pub")){\r
                                handleNomenclaturalReference(homonymName, value);\r
                        }else if (classValue.equalsIgnoreCase("note")){\r
@@ -1226,7 +1283,12 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                        TimePeriod nameYear = upperName.getNomenclaturalReference().getDatePublished();\r
                        homonymIsLater = homonymYear.getStart().compareTo(nameYear.getStart())  > 0;\r
                }else{\r
-                       logger.warn("Classification name has no nomenclatural reference");\r
+                       if (upperName.getNomenclaturalReference() == null){\r
+                               logger.warn("Homonym parent does not have a nomenclatural reference or year: " + upperName.getTitleCache());\r
+                       }\r
+                       if (homonymName.getNomenclaturalReference() == null){\r
+                               logger.warn("Homonym does not have a nomenclatural reference or year: " + homonymName.getTitleCache());\r
+                       }\r
                }\r
                if (homonymIsLater){\r
                        homonymName.addRelationshipToName(upperName, relType, null);\r
@@ -1266,7 +1328,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
         * @param name\r
         * @param value\r
         */\r
-       private TeamOrPersonBase handleNameUsage(Taxon taxon, NonViralName name, String referenceTitle, TeamOrPersonBase lastTeam) {\r
+       protected TeamOrPersonBase handleNameUsage(Taxon taxon, NonViralName name, String referenceTitle, TeamOrPersonBase lastTeam) {\r
                ReferenceBase ref = ReferenceFactory.newGeneric();\r
                referenceTitle = removeStartingSymbols(referenceTitle, ref);\r
                \r
@@ -1346,7 +1408,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
        }\r
 \r
 \r
-       private Team getReferenceAuthor (ReferenceBase ref) {\r
+       protected Team getReferenceAuthor (ReferenceBase ref) {\r
                boolean isCache = false;\r
                String referenceTitle = ref.getTitle();\r
                if (referenceTitle == null){\r
@@ -1396,7 +1458,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
         * @param name\r
         * @return\r
         */\r
-       private String parseHomonym(String detail, NonViralName name) {\r
+       protected String parseHomonym(String detail, NonViralName name) {\r
                String result;\r
                if (detail == null){\r
                        return detail;\r
@@ -1461,10 +1523,11 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
 \r
 \r
        /**\r
+        * @Xpath body/taxon/nomenclature/homotypes/nom/name[@class="pub"]\r
         * @param name\r
         * @param value\r
         */\r
-       private TeamOrPersonBase handleNomenclaturalReference(NonViralName name, String value) {\r
+       protected TeamOrPersonBase handleNomenclaturalReference(NonViralName name, String value) {\r
                ReferenceBase nomRef = ReferenceFactory.newGeneric();\r
                nomRef.setTitleCache(value, true);\r
                parseNomStatus(nomRef, name);\r
@@ -1486,7 +1549,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                if (strAuthor.endsWith(",")){\r
                        strAuthor = strAuthor.substring(0, strAuthor.length() -1);\r
                }\r
-               Team[] team = getTeam(strAuthor);\r
+               TeamOrPersonBase[] team = getTeam(strAuthor);\r
                if (name.getCombinationAuthorTeam() != null && overwrite == false){\r
                        logger.warn("Try to write combination author for a name that already has a combination author. Neglected.");\r
                }else{\r
@@ -1596,15 +1659,15 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
         * @param element\r
         * @param name\r
         */\r
-       private void handleBasionymAuthor(EfloraImportState state, Element element, NonViralName name, boolean overwrite) {\r
-               String strAuthor = element.getValue().trim();\r
+       private void handleBasionymAuthor(EfloraImportState state, Element elBasionymAuthor, NonViralName name, boolean overwrite) {\r
+               String strAuthor = elBasionymAuthor.getValue().trim();\r
                Pattern reBasionymAuthor = Pattern.compile("^\\(.*\\)$");\r
                if (reBasionymAuthor.matcher(strAuthor).matches()){\r
                        strAuthor = strAuthor.substring(1, strAuthor.length()-1);\r
                }else{\r
                        logger.warn("Brackets are missing for original combination author " + strAuthor);\r
                }\r
-               Team[] basionymTeam = getTeam(strAuthor);\r
+               TeamOrPersonBase[] basionymTeam = getTeam(strAuthor);\r
                if (name.getBasionymAuthorTeam() != null && overwrite == false){\r
                        logger.warn("Try to write basionym author for a name that already has a basionym author. Neglected.");\r
                }else{\r
@@ -1628,7 +1691,10 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                if (strAuthor.endsWith(",")){\r
                        strAuthor = strAuthor.substring(0, strAuthor.length() -1);\r
                }\r
-               Team[] team = getTeam(strAuthor);\r
+               if (strAuthor.indexOf("(") > -1 || strAuthor.indexOf(")") > -1){\r
+                       logger.warn("Author has brackets. Basionym authors should be handled in separate tags: " + strAuthor);\r
+               }\r
+               TeamOrPersonBase[] team = getTeam(strAuthor);\r
                name.setCombinationAuthorTeam(team[0]);\r
                name.setExCombinationAuthorTeam(team[1]);\r
        }\r
@@ -1638,8 +1704,8 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
         * @param strAuthor\r
         * @return\r
         */\r
-       private Team[] getTeam(String strAuthor) {\r
-               Team[] result = new Team[2];\r
+       private TeamOrPersonBase[] getTeam(String strAuthor) {\r
+               TeamOrPersonBase[] result = new TeamOrPersonBase[2];\r
                String[] split = strAuthor.split(" ex ");\r
                String strBaseAuthor = null;\r
                String strExAuthor = null;\r
@@ -1652,11 +1718,9 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                }else{\r
                        logger.warn("Could not parse (ex) author: " + strAuthor);\r
                }\r
-               \r
                result[0] = getUuidTeam(strBaseAuthor);\r
                if (result[0] == null){\r
-                       result[0] = Team.NewInstance();\r
-                       result[0].setTitleCache(strBaseAuthor, true);\r
+                       result[0] = parseSingleTeam(strBaseAuthor);\r
                        teamMap.put(strBaseAuthor, result[0].getUuid());\r
                }\r
                if (strExAuthor != null){\r
@@ -1672,13 +1736,41 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
        }\r
 \r
 \r
+       protected TeamOrPersonBase parseSingleTeam(String strBaseAuthor) {\r
+               TeamOrPersonBase result;\r
+               String[] split = strBaseAuthor.split("&");\r
+               if (split.length > 1){\r
+                       result = Team.NewInstance();\r
+                       for (String personString : split){\r
+                               Person person = makePerson(personString);\r
+                               ((Team)result).addTeamMember(person);\r
+                       }\r
+               }else{\r
+                       result = makePerson(strBaseAuthor.trim());\r
+               }\r
+               return result;\r
+       }\r
+\r
+\r
+       /**\r
+        * @param personString\r
+        * @return\r
+        */\r
+       private Person makePerson(String personString) {\r
+               personString = personString.trim();\r
+               Person person = Person.NewTitledInstance(personString);\r
+               person.setNomenclaturalTitle(personString);\r
+               return person;\r
+       }\r
+\r
+\r
        /**\r
         * @param result\r
         * @param strBaseAuthor\r
         */\r
-       private Team getUuidTeam(String strBaseAuthor) {\r
+       private TeamOrPersonBase getUuidTeam(String strBaseAuthor) {\r
                UUID uuidTeam = teamMap.get(strBaseAuthor);\r
-               return CdmBase.deproxy(getAgentService().find(uuidTeam), Team.class);\r
+               return CdmBase.deproxy(getAgentService().find(uuidTeam), TeamOrPersonBase.class);\r
        }\r
 \r
 \r
@@ -1714,7 +1806,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                                        logger.warn("Unhandled feature: " + classValue);\r
                                }else{\r
                                        String value = element.getValue();\r
-                                       addDescriptionElement(taxon, value, feature, null);\r
+                                       addDescriptionElement(state, taxon, value, feature, null);\r
                                }\r
                                \r
                        }\r
@@ -1731,7 +1823,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
         * @param taxon\r
         * @return\r
         */\r
-       private TaxonDescription getDescription(Taxon taxon) {\r
+       protected TaxonDescription getDescription(Taxon taxon) {\r
                for (TaxonDescription description : taxon.getDescriptions()){\r
                        if (! description.isImageGallery()){\r
                                return description;\r
@@ -1876,7 +1968,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
         * @param value\r
         * @param taxonNameBase \r
         */\r
-       private void handleGenus(String value, TaxonNameBase taxonName) {\r
+       protected void handleGenus(String value, TaxonNameBase taxonName) {\r
                Matcher matcher = rexGenusAuthor.matcher(value);\r
                if (matcher.find()){\r
                        String author = matcher.group();\r
@@ -1965,16 +2057,17 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
        }\r
 \r
 \r
-\r
        /**\r
+        * @param state \r
         * @param taxon\r
         * @param value\r
         * @param feature\r
         * @return \r
         */\r
-       private TextData addDescriptionElement(Taxon taxon, String value, Feature feature, String references) {\r
+       private TextData addDescriptionElement(EfloraImportState state, Taxon taxon, String value, Feature feature, String references) {\r
                TextData textData = TextData.NewInstance(feature);\r
-               textData.putText(value, Language.ENGLISH());\r
+               Language textLanguage = getDefaultLanguage(state);\r
+               textData.putText(value, textLanguage);\r
                TaxonDescription description = getDescription(taxon);\r
                description.addElement(textData);\r
                if (references != null){\r
@@ -1983,6 +2076,24 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
                return textData;\r
        }\r
 \r
+       private Language getDefaultLanguage(EfloraImportState state) {\r
+               UUID defaultLanguageUuid = state.getConfig().getDefaultLanguageUuid();\r
+               if (defaultLanguageUuid != null){\r
+                       Language result = state.getDefaultLanguage();\r
+                       if (result == null || ! result.getUuid().equals(defaultLanguageUuid)){\r
+                               result = (Language)getTermService().find(defaultLanguageUuid);\r
+                               state.setDefaultLanguage(result);\r
+                               if (result == null){\r
+                                       logger.warn("Default language for " + defaultLanguageUuid +  " does not exist.");\r
+                               }\r
+                       }\r
+                       return result;\r
+               }else{\r
+                       return Language.DEFAULT();\r
+               }\r
+       }\r
+\r
+\r
        /**\r
         * @param elNomenclature\r
         */\r
@@ -1996,7 +2107,7 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
        /**\r
         * @param elNomenclature\r
         */\r
-       private void verifyNoChildren(Element element) {\r
+       protected void verifyNoChildren(Element element) {\r
                verifyNoChildren(element, false);\r
        }\r
        \r
@@ -2020,10 +2131,16 @@ public class EfloraTaxonImport  extends EfloraImportBase implements ICdmIO<Eflor
        \r
        \r
 \r
-       private void parseNomStatus(ReferenceBase ref, NonViralName nonViralName) {\r
+       /**\r
+        * Parses the nomenclatural status from the references titleCache. If a nomenclatural status\r
+        * exists it is added to the name and the nom. status part of the references title cache is \r
+        * removed. Requires protected title cache.\r
+        * @param ref\r
+        * @param nonViralName\r
+        */\r
+       protected void parseNomStatus(ReferenceBase ref, NonViralName nonViralName) {\r
                String titleToParse = ref.getTitleCache();\r
                \r
-               \r
                String noStatusTitle = parser.parseNomStatus(titleToParse, nonViralName);\r
                if (! noStatusTitle.equals(titleToParse)){\r
                        ref.setTitleCache(noStatusTitle, true);\r