updates for markup import
authorAndreas Müller <a.mueller@bgbm.org>
Wed, 10 Aug 2011 13:46:59 +0000 (13:46 +0000)
committerAndreas Müller <a.mueller@bgbm.org>
Wed, 10 Aug 2011 13:46:59 +0000 (13:46 +0000)
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/markup/MarkupDocumentImport.java
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/markup/MarkupTransformer.java
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/markup/UnmatchedLeads.java

index e46d93c61931ad09f979917e14b3cf58de38d96a..a612e6feefa9ad6d231ae31634056a6dc04bbfb7 100644 (file)
@@ -38,6 +38,7 @@ import org.springframework.security.access.PermissionEvaluator;
 import org.springframework.security.authentication.AuthenticationManager;\r
 import org.springframework.security.core.Authentication;\r
 import org.springframework.stereotype.Component;\r
+import org.springframework.transaction.TransactionStatus;\r
 \r
 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;\r
 import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade.DerivedUnitType;\r
@@ -85,6 +86,7 @@ import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
 import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
 import eu.etaxonomy.cdm.model.occurrence.Collection;\r
 import eu.etaxonomy.cdm.model.occurrence.DerivedUnitBase;\r
+import eu.etaxonomy.cdm.model.occurrence.FieldObservation;\r
 import eu.etaxonomy.cdm.model.occurrence.Specimen;\r
 import eu.etaxonomy.cdm.model.reference.IArticle;\r
 import eu.etaxonomy.cdm.model.reference.IJournal;\r
@@ -106,42 +108,16 @@ import eu.etaxonomy.cdm.strategy.parser.SpecimenTypeParser.TypeInfo;
  * \r
  */\r
 @Component\r
-public class MarkupDocumentImport extends MarkupImportBase implements\r
-               ICdmIO<MarkupImportState> {\r
-       private static final String TO_COUPLET = "toCouplet";\r
-\r
-       private static final String TO_TAXON = "toTaxon";\r
-\r
-       private static final String TO_KEY = "toKey";\r
-\r
-       private static final String TEXT = "text";\r
-\r
-       private static final String QUESTION = "question";\r
-\r
-       private static final String COUPLET = "couplet";\r
-\r
-       private static final String KEYNOTES = "keynotes";\r
-\r
-       private static final String KEY_TITLE = "keyTitle";\r
-\r
-       private static final String IS_SPOTCHARACTERS = "isSpotcharacters";\r
+public class MarkupDocumentImport extends MarkupImportBase implements ICdmIO<MarkupImportState> {\r
+       private static final String FREQUENCY = "frequency";\r
 \r
-       private static final String REF_NUM = "refNum";\r
+       private static final String TAXONTYPE = "taxontype";\r
 \r
-       private static final String SERIALS_ABBREVIATIONS = "serialsAbbreviations";\r
+       private static final String DEDICATION = "dedication";\r
 \r
-       private static final String BIBLIOGRAPHY = "bibliography";\r
+       private static final String QUOTE = "quote";\r
 \r
-       private static final String HABITAT = "habitat";\r
-\r
-       private static final String LIFE_CYCLE_PERIODS = "lifeCyclePeriods";\r
-\r
-       private static final String DISTRIBUTION_LOCALITY = "distributionLocality";\r
-\r
-       private static final String REFERENCE = "reference";\r
-\r
-       private static final Logger logger = Logger\r
-                       .getLogger(MarkupDocumentImport.class);\r
+       private static final Logger logger = Logger.getLogger(MarkupDocumentImport.class);\r
 \r
        private static final boolean CREATE_NEW = true;\r
        private static final boolean IS_IMAGE_GALLERY = true;\r
@@ -157,20 +133,22 @@ public class MarkupDocumentImport extends MarkupImportBase implements
        private static final String ALTITUDE = "altitude";\r
        private static final String ANNOTATION = "annotation";\r
        private static final String AUTHOR = "author";\r
+       private static final String BIBLIOGRAPHY = "bibliography";\r
        private static final String BIOGRAPHIES = "biographies";\r
        private static final String BOLD = "bold";\r
        private static final String BR = "br";\r
        private static final String CHAR = "char";\r
        private static final String CITATION = "citation";\r
-       private static final String COLLECTION = "collection";\r
        private static final String COLLECTION_TYPE_STATUS = "collectionTypeStatus";\r
        private static final String COLLECTOR = "collector";\r
        private static final String COORDINATES = "coordinates";\r
+       private static final String COUPLET = "couplet";\r
        private static final String DATES = "dates";\r
        private static final String DEFAULT_MEDIA_URL = "defaultMediaUrl";\r
        private static final String DESTROYED = "destroyed";\r
        private static final String DETAILS = "details";\r
        private static final String DISTRIBUTION_LIST = "distributionList";\r
+       private static final String DISTRIBUTION_LOCALITY = "distributionLocality";\r
        private static final String EDITION = "edition";\r
        private static final String EDITORS = "editors";\r
        private static final String FEATURE = "feature";\r
@@ -185,7 +163,9 @@ public class MarkupDocumentImport extends MarkupImportBase implements
        private static final String FIELD_NUM = "fieldNum";\r
        private static final String FULL_NAME = "fullName";\r
        private static final String FULL_TYPE = "fullType";\r
+       private static final String GATHERING = "gathering";\r
        private static final String HEADING = "heading";\r
+       private static final String HABITAT = "habitat";\r
        private static final String HABITAT_LIST = "habitatList";\r
        private static final String HOMONYM = "homonym";\r
        private static final String HOMOTYPES = "homotypes";\r
@@ -193,9 +173,13 @@ public class MarkupDocumentImport extends MarkupImportBase implements
        private static final String INFRANK = "infrank";\r
        private static final String INFRAUT = "infraut";\r
        private static final String INFRPARAUT = "infrparaut";\r
+       private static final String IS_SPOTCHARACTERS = "isSpotcharacters";\r
        private static final String ISSUE = "issue";\r
        private static final String ITALICS = "italics";\r
        private static final String KEY = "key";\r
+       private static final String KEY_TITLE = "keyTitle";\r
+       private static final String KEYNOTES = "keynotes";\r
+       private static final String LIFE_CYCLE_PERIODS = "lifeCyclePeriods";\r
        private static final String LOCALITY = "locality";\r
        private static final String LOST = "lost";\r
        private static final String META_DATA = "metaData";\r
@@ -214,16 +198,24 @@ public class MarkupDocumentImport extends MarkupImportBase implements
        private static final String PUBNAME = "pubname";\r
        private static final String PUBTITLE = "pubtitle";\r
        private static final String PUBTYPE = "pubtype";\r
+       private static final String QUESTION = "question";\r
        private static final String RANK = "rank";\r
        private static final String REF = "ref";\r
+       private static final String REF_NUM = "refNum";\r
        private static final String REF_PART = "refPart";\r
+       private static final String REFERENCE = "reference";\r
        private static final String REFERENCES = "references";\r
        private static final String TAXON = "taxon";\r
        private static final String TAXONTITLE = "taxontitle";\r
+       private static final String TEXT = "text";\r
        private static final String TEXT_SECTION = "textSection";\r
+       private static final String TO_COUPLET = "toCouplet";\r
+       private static final String TO_KEY = "toKey";\r
+       private static final String TO_TAXON = "toTaxon";\r
        private static final String TYPE = "type";\r
        private static final String TYPE_STATUS = "typeStatus";\r
        private static final String TREATMENT = "treatment";\r
+       private static final String SERIALS_ABBREVIATIONS = "serialsAbbreviations";\r
        private static final String SPECIMEN_TYPE = "specimenType";\r
        private static final String STATUS = "status";\r
        private static final String STRING = "string";\r
@@ -269,13 +261,12 @@ public class MarkupDocumentImport extends MarkupImportBase implements
        }\r
 \r
        @Override\r
-       public void doInvoke(MarkupImportState state) {\r
-               fireProgressEvent("Start import markup document",\r
-                               "Before start of document");\r
-               fireWarningEvent("Test a warning", "At start", 17);\r
-\r
+       public void doInvoke(MarkupImportState state) { \r
+               fireProgressEvent("Start import markup document", "Before start of document");\r
+               \r
                Queue<CdmBase> outputStream = new LinkedList<CdmBase>();\r
 \r
+               TransactionStatus tx = startTransaction();\r
                // FIXME reset state\r
                doAllTheOldOtherStuff(state);\r
 \r
@@ -293,6 +284,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                        // publication\r
                        String elName = PUBLICATION;\r
                        boolean hasPublication = false;\r
+                       \r
                        while (reader.hasNext()) {\r
                                XMLEvent nextEvent = reader.nextEvent();\r
                                if (isStartingElement(nextEvent, elName)) {\r
@@ -308,20 +300,17 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                        fireSchemaConflictEventExpectedStartTag(elName, reader);\r
                                }\r
                        }\r
+                       commitTransaction(tx);\r
 \r
                        // //SAX\r
                        // ImportHandlerBase handler= new PublicationHandler(this);\r
                        // parseSAX(state, handler);\r
 \r
                } catch (FactoryConfigurationError e1) {\r
-                       fireWarningEvent(\r
-                                       "Some error occurred while setting up xml factory. Data can't be imported",\r
-                                       "Start", 16);\r
+                       fireWarningEvent("Some error occurred while setting up xml factory. Data can't be imported", "Start", 16);\r
                        state.setUnsuccessfull();\r
                } catch (XMLStreamException e1) {\r
-                       fireWarningEvent(\r
-                                       "An XMLStreamException occurred while parsing. Data can't be imported",\r
-                                       "Start", 16);\r
+                       fireWarningEvent("An XMLStreamException occurred while parsing. Data can't be imported", "Start", 16);\r
                        state.setUnsuccessfull();\r
                        // } catch (ParserConfigurationException e) {\r
                        // fireWarningEvent("A ParserConfigurationException occurred while parsing. Data can't be imported",\r
@@ -441,6 +430,13 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                        keySet.add(key);\r
                                }\r
                                save(keySet, state);\r
+                               //unmatched key leads\r
+                               UnmatchedLeads unmatched = state.getUnmatchedLeads();\r
+                               if (unmatched.size() > 0){\r
+                                       String message = "The following key leads are unmatched: %s";\r
+                                       message = String.format(message, state.getUnmatchedLeads().toString());\r
+                                       fireWarningEvent(message, next, 6);\r
+                               }\r
 //                             save(keyNodesToSave, state);\r
 \r
                                return;\r
@@ -458,7 +454,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
        private void doTaxonRelation(MarkupImportState state, Taxon taxon,\r
                        Taxon lastTaxon, Location dataLocation) {\r
 \r
-               Classification tree = makeTree(state);\r
+               Classification tree = makeTree(state, dataLocation);\r
                if (lastTaxon == null) {\r
                        tree.addChildTaxon(taxon, null, null, null);\r
                        return;\r
@@ -494,14 +490,16 @@ public class MarkupDocumentImport extends MarkupImportBase implements
 \r
        /**\r
         * @param state\r
+        * @param dataLocation \r
         * @return\r
         */\r
-       private Classification makeTree(MarkupImportState state) {\r
+       private Classification makeTree(MarkupImportState state, Location dataLocation) {\r
                Classification result = state.getTree(null);\r
                if (result == null) {\r
                        UUID uuid = state.getConfig().getClassificationUuid();\r
                        if (uuid == null) {\r
-                               logger.warn("No classification uuid is defined");\r
+                               String message = "No classification uuid is defined";\r
+                               fireWarningEvent(message, makeLocationStr(dataLocation), 6);\r
                                result = createNewClassification(state);\r
                        } else {\r
                                result = getClassificationService().find(uuid);\r
@@ -523,8 +521,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                return result;\r
        }\r
 \r
-       private Taxon handleTaxon(MarkupImportState state, XMLEventReader reader,\r
-                       StartElement parentEvent) throws XMLStreamException {\r
+       private Taxon handleTaxon(MarkupImportState state, XMLEventReader reader, StartElement parentEvent) throws XMLStreamException {\r
                // TODO progress monitoring\r
                Map<String, Attribute> attributes = getAttributes(parentEvent);\r
                Taxon taxon = createTaxonAndName(state, attributes);\r
@@ -542,7 +539,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                        checkMandatoryElement(hasNomenclature, parentEvent,     NOMENCLATURE);\r
                                        handleUnexpectedAttributes(parentEvent.getLocation(),attributes);\r
                                        \r
-                                       makeKeyNodes(state, parentEvent);\r
+                                       makeKeyNodes(state, parentEvent, taxonTitle);\r
                                        state.setCurrentTaxon(null);\r
                                        state.setCurrentTaxonNum(null);\r
                                        save(taxon, state);\r
@@ -620,23 +617,28 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                throw new IllegalStateException("<Taxon> has no closing tag");\r
        }\r
 \r
-       private void makeKeyNodes(MarkupImportState state, XMLEvent event) {\r
+       private void makeKeyNodes(MarkupImportState state, XMLEvent event, String taxonTitle) {\r
                Taxon taxon = state.getCurrentTaxon();\r
                String num = state.getCurrentTaxonNum();\r
                \r
                String nameString = CdmBase.deproxy(taxon.getName(), NonViralName.class).getNameCache();\r
+//             String nameString = taxonTitle;\r
                \r
                //try to find matching lead nodes \r
                UnmatchedLeadsKey leadsKey = UnmatchedLeadsKey.NewInstance(num, nameString);\r
                Set<PolytomousKeyNode> matchingNodes = handleMatchingNodes(state, taxon, leadsKey);\r
-               //same without using the num\r
-               if (num != null){\r
+               \r
+               if (num != null){//same without using the num\r
                        UnmatchedLeadsKey noNumLeadsKey = UnmatchedLeadsKey.NewInstance("", nameString);\r
-                       //TODO inform about differences\r
-                       handleMatchingNodes(state, taxon, noNumLeadsKey);\r
+                       Set<PolytomousKeyNode> noNumMatchingNodes = handleMatchingNodes(state, taxon, noNumLeadsKey);\r
+                       if(noNumMatchingNodes.size() > 0){\r
+                               String message ="Taxon matches additional key node when not considering <num> attribute in taxontitle. This may be correct but may also indicate an error.";\r
+                               fireWarningEvent(message, event, 1);\r
+                       }\r
                }\r
+               //report missing match, if num exists\r
                if (matchingNodes.isEmpty() && num != null){\r
-                       String message = "Taxon has num in taxontitle but no matching nodes exist: %s, Key: %s";\r
+                       String message = "Taxon has <num> attribute in taxontitle but no matching key nodes exist: %s, Key: %s";\r
                        message = String.format(message, num, leadsKey.toString());\r
                        fireWarningEvent(message, event, 1);\r
                }\r
@@ -659,7 +661,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                String isSpotcharacters = getAndRemoveAttributeValue(attributes, IS_SPOTCHARACTERS);\r
                if (isNotBlank(isSpotcharacters) ) {\r
                        //TODO isSpotcharacters\r
-                       String message = "isSpotcharacters not yet implemented for <key>";\r
+                       String message = "Attribute isSpotcharacters not yet implemented for <key>";\r
                        fireWarningEvent(message, parentEvent, 4);\r
                }\r
                \r
@@ -676,29 +678,23 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                return;\r
                        } else if (isEndingElement(next, KEYNOTES)){\r
                                popUnimplemented(next.asEndElement());\r
-                       } else if (next.isStartElement()) {\r
-                               if (isStartingElement(next, KEY_TITLE)) {\r
+                       } else if (isStartingElement(next, KEY_TITLE)) {\r
                                        handleKeyTitle(state, reader, next);\r
-                               } else if (isStartingElement(next, KEYNOTES)) {\r
-                                       //TODO\r
-                                       handleNotYetImplementedElement(next);\r
-                               } else if (isStartingElement(next, COUPLET)) {\r
-                                       PolytomousKeyNode node = null;\r
-                                       if (isFirstCouplet){\r
-                                               node = key.getRoot();\r
-                                               isFirstCouplet = false;\r
-                                       }\r
-                                       handleCouplet(state, reader, next, node);\r
-                               } else {\r
-                                       handleUnexpectedStartElement(next.asStartElement());\r
+                       } else if (isStartingElement(next, KEYNOTES)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isStartingElement(next, COUPLET)) {\r
+                               PolytomousKeyNode node = null;\r
+                               if (isFirstCouplet){\r
+                                       node = key.getRoot();\r
+                                       isFirstCouplet = false;\r
                                }\r
+                               handleCouplet(state, reader, next, node);\r
                        } else {\r
                                handleUnexpectedElement(next);\r
                        }\r
                }\r
                throw new IllegalStateException("<key> has no closing tag");\r
-               \r
-\r
        }\r
 \r
        /**\r
@@ -729,13 +725,14 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                        if (isMyEndingElement(next, parentEvent)) {\r
                                completeCouplet(state, parentEvent, parentNode, num, childList);\r
                                return;\r
-                       } else if (isEndingElement(next, KEYNOTES)){\r
-                               popUnimplemented(next.asEndElement());\r
                        } else if (isStartingElement(next, QUESTION)) {\r
                                handleQuestion(state, reader, next, childList);\r
                        } else if (isStartingElement(next, KEYNOTES)) {\r
                                //TODO\r
                                handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, KEYNOTES)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
                        } else {\r
                                handleUnexpectedElement(next);\r
                        }\r
@@ -787,13 +784,6 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                        XMLEvent next = readNoWhitespace(reader);\r
                        if (isMyEndingElement(next, parentEvent)) {\r
                                return;\r
-                       } else if (isEndingElement(next, TO_KEY)){\r
-                               //TODO\r
-                               popUnimplemented(next.asEndElement());\r
-                       } else if (isEndingElement(next, KEYNOTES)){\r
-                               //TODO\r
-                               popUnimplemented(next.asEndElement());\r
-                       \r
                        } else if (isStartingElement(next, TEXT)) {\r
                                String text = getCData(state, reader, next);\r
                                KeyStatement statement = KeyStatement.NewInstance(text);\r
@@ -805,12 +795,19 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                handleToCouplet(state, reader, next, myNode);\r
                        } else if (isStartingElement(next, TO_TAXON)) {\r
                                handleToTaxon(state, reader, next, myNode);\r
+                       \r
                        } else if (isStartingElement(next, TO_KEY)) {\r
                                //TODO\r
                                handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, TO_KEY)){\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
                        } else if (isStartingElement(next, KEYNOTES)) {\r
                                //TODO\r
                                handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, KEYNOTES)){\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
                        } else {\r
                                handleUnexpectedElement(next);\r
                        }\r
@@ -821,8 +818,8 @@ public class MarkupDocumentImport extends MarkupImportBase implements
        private void handleToCouplet(MarkupImportState state, XMLEventReader reader, XMLEvent next, PolytomousKeyNode node) throws XMLStreamException {\r
                String num = getOnlyAttribute(next, NUM, true);\r
                String cData = getCData(state, reader, next, false);\r
-               if (isNotBlank(cData)){\r
-                       String message = "CData ('%s') not handled";\r
+               if (isNotBlank(cData) && ! cData.equals(num)){\r
+                       String message = "CData ('%s') not handled in <toCouplet>";\r
                        message = String.format(message, cData);\r
                        fireWarningEvent(message, next, 4);\r
                }\r
@@ -846,7 +843,11 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                if (strGoto == null){\r
                        return "";\r
                }\r
-               String strGenusName = CdmBase.deproxy(taxon.getName(), NonViralName.class).getGenusOrUninomial();\r
+               \r
+               NonViralName<?> name = CdmBase.deproxy(taxon.getName(), NonViralName.class);\r
+               String strGenusName = name.getGenusOrUninomial();\r
+               \r
+               \r
                strGoto = strGoto.replaceAll("\\([^\\(\\)]*\\)", "");  //replace all brackets\r
                strGoto = strGoto.replaceAll("\\s+", " "); //replace multiple whitespaces by exactly one whitespace\r
                \r
@@ -857,15 +858,30 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                        if (isGenusAbbrev(single, strGenusName)){\r
                                split[i] = strGenusName;\r
                        }\r
-//                     if (isInfraSpecificMarker(single)){\r
-//                             String strSpeciesName = CdmBase.deproxy(taxon.getName(), NonViralName.class).getSpecificEpithet();\r
-//                             split[i] = strGenusName + " " + strSpeciesName + " ";\r
-//                     }\r
+                       if (isInfraSpecificMarker(single)){\r
+                               String strSpeciesEpi = name.getSpecificEpithet();\r
+                               if (isBlank(result)){\r
+                                       result += strGenusName + " " + strSpeciesEpi;\r
+                               }\r
+                       }\r
                        result = (result + " " + split[i]).trim();\r
                }\r
                return result;\r
        }\r
        \r
+\r
+       private boolean isInfraSpecificMarker(String single) {\r
+               try {\r
+                       if (Rank.getRankByAbbreviation(single).isInfraSpecific()){\r
+                               return true;\r
+                       }else{\r
+                               return false;\r
+                       }\r
+               } catch (UnknownCdmTypeException e) {\r
+                       return false;\r
+               }\r
+       }\r
+       \r
        private boolean isGenusAbbrev(String single, String strGenusName) {\r
                if (! single.matches("[A-Z]\\.?")) {\r
                        return false;\r
@@ -957,7 +973,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
         * @throws XMLStreamException\r
         */\r
        private String makeNotesString(MarkupImportState state, XMLEventReader reader, String text, XMLEvent next) throws XMLStreamException {\r
-               Map<String, String> stringMap = handleString(state, reader,     next);\r
+               Map<String, String> stringMap = handleString(state, reader,     next, null);\r
                if (stringMap.size() == 0){\r
                        String message = "No text available in <notes>";\r
                        fireWarningEvent(message, next, 4);\r
@@ -1110,58 +1126,39 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                // TODO handle attributes\r
                while (reader.hasNext()) {\r
                        XMLEvent next = readNoWhitespace(reader);\r
-                       if (next.isEndElement()) {\r
-                               if (isMyEndingElement(next, parentEvent)) {\r
-                                       text = CdmUtils.removeBrackets(text);\r
-                                       if (checkMandatoryText(text, parentEvent)) {\r
-                                               text = normalize(text);\r
-                                               dataHolder.writer = text;\r
-                                               dataHolder.footnotes = footnotes;\r
-\r
-                                               // Extension\r
-                                               UUID uuidWriterExtension = MarkupTransformer.uuidWriterExtension;\r
-                                               ExtensionType writerExtensionType = this\r
-                                                               .getExtensionType(state, uuidWriterExtension,\r
-                                                                               "Writer", "writer", "writer");\r
-                                               Extension extension = Extension.NewInstance();\r
-                                               extension.setType(writerExtensionType);\r
-                                               extension.setValue(text);\r
-                                               dataHolder.extension = extension;\r
-\r
-                                               // Annotation\r
-                                               UUID uuidWriterAnnotation = MarkupTransformer.uuidWriterAnnotation;\r
-                                               AnnotationType writerAnnotationType = this\r
-                                                               .getAnnotationType(state, uuidWriterAnnotation,\r
-                                                                               "Writer", "writer", "writer", null);\r
-                                               Annotation annotation = Annotation.NewInstance(text,\r
-                                                               writerAnnotationType, Language.DEFAULT());\r
-                                               dataHolder.annotation = annotation;\r
-\r
-                                               return dataHolder;\r
-                                       } else {\r
-                                               return null;\r
-                                       }\r
+                       if (isMyEndingElement(next, parentEvent)) {\r
+                               text = CdmUtils.removeBrackets(text);\r
+                               if (checkMandatoryText(text, parentEvent)) {\r
+                                       text = normalize(text);\r
+                                       dataHolder.writer = text;\r
+                                       dataHolder.footnotes = footnotes;\r
+\r
+                                       // Extension\r
+                                       UUID uuidWriterExtension = MarkupTransformer.uuidWriterExtension;\r
+                                       ExtensionType writerExtensionType = this\r
+                                                       .getExtensionType(state, uuidWriterExtension,\r
+                                                                       "Writer", "writer", "writer");\r
+                                       Extension extension = Extension.NewInstance();\r
+                                       extension.setType(writerExtensionType);\r
+                                       extension.setValue(text);\r
+                                       dataHolder.extension = extension;\r
+\r
+                                       // Annotation\r
+                                       UUID uuidWriterAnnotation = MarkupTransformer.uuidWriterAnnotation;\r
+                                       AnnotationType writerAnnotationType = this.getAnnotationType(state, uuidWriterAnnotation, "Writer", "writer", "writer", null);\r
+                                       Annotation annotation = Annotation.NewInstance(text, writerAnnotationType, Language.DEFAULT());\r
+                                       dataHolder.annotation = annotation;\r
+\r
+                                       return dataHolder;\r
                                } else {\r
-                                       if (isEndingElement(next, FOOTNOTE)) {\r
-                                               // NOT YET IMPLEMENTED\r
-                                               popUnimplemented(next.asEndElement());\r
-                                       } else {\r
-                                               handleUnexpectedEndElement(next.asEndElement());\r
-                                               state.setUnsuccessfull();\r
-                                       }\r
+                                       return null;\r
                                }\r
-                       } else if (next.isStartElement()) {\r
-                               if (isStartingElement(next, FOOTNOTE_REF)) {\r
-                                       FootnoteDataHolder footNote = handleFootnoteRef(state,\r
-                                                       reader, next);\r
-                                       if (footNote.isRef()) {\r
-                                               footnotes.add(footNote);\r
-                                       } else {\r
-                                               logger.warn("Non ref footnotes not yet impelemnted");\r
-                                       }\r
+                       } else if (isStartingElement(next, FOOTNOTE_REF)) {\r
+                               FootnoteDataHolder footNote = handleFootnoteRef(state, reader, next);\r
+                               if (footNote.isRef()) {\r
+                                       footnotes.add(footNote);\r
                                } else {\r
-                                       handleUnexpectedStartElement(next);\r
-                                       state.setUnsuccessfull();\r
+                                       logger.warn("Non ref footnotes not yet impelemnted");\r
                                }\r
                        } else if (next.isCharacters()) {\r
                                text += next.asCharacters().getData();\r
@@ -1171,7 +1168,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                state.setUnsuccessfull();\r
                        }\r
                }\r
-               return null;\r
+               throw new IllegalStateException("<writer> has no end tag");\r
        }\r
 \r
        private void registerFootnotes(MarkupImportState state,\r
@@ -1402,9 +1399,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                throw new IllegalStateException("<figureRef> has no end tag");\r
        }\r
 \r
-       private FootnoteDataHolder handleFootnote(MarkupImportState state,\r
-                       XMLEventReader reader, XMLEvent parentEvent)\r
-                       throws XMLStreamException {\r
+       private FootnoteDataHolder handleFootnote(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent) throws XMLStreamException {\r
                FootnoteDataHolder result = new FootnoteDataHolder();\r
                Map<String, Attribute> attributes = getAttributes(parentEvent);\r
                result.id = getAndRemoveAttributeValue(attributes, ID);\r
@@ -1472,9 +1467,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                return;\r
        }\r
 \r
-       private String handleFootnoteString(MarkupImportState state,\r
-                       XMLEventReader reader, XMLEvent parentEvent)\r
-                       throws XMLStreamException {\r
+       private String handleFootnoteString(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent) throws XMLStreamException {\r
                boolean isTextMode = true;\r
                String text = "";\r
                while (reader.hasNext()) {\r
@@ -1484,8 +1477,6 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                        } else if (next.isEndElement()) {\r
                                if (isEndingElement(next, FULL_NAME)) {\r
                                        popUnimplemented(next.asEndElement());\r
-                               } else if (isEndingElement(next, COLLECTION)) {\r
-                                       popUnimplemented(next.asEndElement());\r
                                } else if (isEndingElement(next, BR)) {\r
                                        isTextMode = true;\r
                                } else if (isHtml(next)) {\r
@@ -1496,8 +1487,8 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                        } else if (next.isStartElement()) {\r
                                if (isStartingElement(next, FULL_NAME)) {\r
                                        handleNotYetImplementedElement(next);\r
-                               } else if (isStartingElement(next, COLLECTION)) {\r
-                                       handleNotYetImplementedElement(next);\r
+                               } else if (isStartingElement(next, GATHERING)) {\r
+                                       text += handleInLineGathering(state, reader, next);\r
                                } else if (isStartingElement(next, REFERENCES)) {\r
                                        text += " " + handleInLineReferences(state, reader, next)+ " ";\r
                                } else if (isStartingElement(next, BR)) {\r
@@ -1513,15 +1504,8 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                        String message = "footnoteString is not in text mode";\r
                                        fireWarningEvent(message, next, 6);\r
                                } else {\r
-                                       text += next.asCharacters().getData().trim(); // getCData(state,\r
-                                                                                                                                       // reader,\r
-                                                                                                                                       // next);\r
-                                                                                                                                       // does not\r
-                                                                                                                                       // work as\r
-                                                                                                                                       // we have\r
-                                                                                                                                       // inner\r
-                                                                                                                                       // tags like\r
-                                                                                                                                       // <references>\r
+                                       text += next.asCharacters().getData().trim(); \r
+                                       // getCData(state, reader, next); does not work as we have inner tags like <references>\r
                                }\r
                        } else {\r
                                handleUnexpectedEndElement(next.asEndElement());\r
@@ -1531,6 +1515,16 @@ public class MarkupDocumentImport extends MarkupImportBase implements
 \r
        }\r
 \r
+       private String handleInLineGathering(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent) throws XMLStreamException {\r
+               DerivedUnitFacade facade = DerivedUnitFacade.NewInstance(DerivedUnitType.DerivedUnit.FieldObservation);\r
+               handleGathering(state, reader, parentEvent, null, facade);\r
+               FieldObservation fieldObservation = facade.innerFieldObservation();\r
+               String result = "<cdm:specimen uuid='%s'>%s</specimen>";\r
+               result = String.format(result, fieldObservation.getUuid(), fieldObservation.getTitleCache());\r
+               save(fieldObservation, state);\r
+               return result;  \r
+       }\r
+\r
        private String handleInLineReferences(MarkupImportState state,\r
                        XMLEventReader reader, XMLEvent parentEvent)\r
                        throws XMLStreamException {\r
@@ -1551,23 +1545,18 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                handleUnexpectedElement(next);\r
                        }\r
                }\r
-               // TODO handle missing end element\r
                throw new IllegalStateException("<References> has no closing tag");\r
        }\r
 \r
-       private String handleInLineReference(MarkupImportState state,\r
-                       XMLEventReader reader, XMLEvent parentEvent)\r
-                       throws XMLStreamException {\r
+       private String handleInLineReference(MarkupImportState state,XMLEventReader reader, XMLEvent parentEvent)throws XMLStreamException {\r
                Reference<?> reference = handleReference(state, reader, parentEvent);\r
-               String result = "<ref uuid='%s'>%s</ref>";\r
-               result = String.format(result, reference.getUuid(),\r
-                               reference.getTitleCache());\r
+               String result = "<cdm:ref uuid='%s'>%s</ref>";\r
+               result = String.format(result, reference.getUuid(), reference.getTitleCache());\r
+               save(reference, state);\r
                return result;\r
        }\r
 \r
-       private Reference<?> handleReference(MarkupImportState state,\r
-                       XMLEventReader reader, XMLEvent parentEvent)\r
-                       throws XMLStreamException {\r
+       private Reference<?> handleReference(MarkupImportState state,XMLEventReader reader, XMLEvent parentEvent)throws XMLStreamException {\r
                checkNoAttributes(parentEvent);\r
 \r
                boolean hasRefPart = false;\r
@@ -1780,9 +1769,8 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                        // homotypicalGroup);\r
                                } else if (isStartingElement(next, TYPE_STATUS)) {\r
                                        handleNotYetImplementedElement(next);\r
-                               } else if (isStartingElement(next, COLLECTION)) {\r
-                                       handleCollection(state, reader, next, homotypicalGroup,\r
-                                                       facade);\r
+                               } else if (isStartingElement(next, GATHERING)) {\r
+                                       handleGathering(state, reader, next, homotypicalGroup, facade);\r
                                } else if (isStartingElement(next, ORIGINAL_DETERMINATION)) {\r
                                        handleNotYetImplementedElement(next);\r
                                } else if (isStartingElement(next, SPECIMEN_TYPE)) {\r
@@ -1866,8 +1854,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
        }\r
 \r
        \r
-       private void handleCollection(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent, HomotypicalGroup homotypicalGroup, DerivedUnitFacade facade)\r
-                       throws XMLStreamException {\r
+       private void handleGathering(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent, HomotypicalGroup homotypicalGroup, DerivedUnitFacade facade) throws XMLStreamException {\r
                checkNoAttributes(parentEvent);\r
                boolean hasCollector = false;\r
                boolean hasFieldNum = false;\r
@@ -1948,9 +1935,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
 \r
        }\r
 \r
-       private void handleLocality(MarkupImportState state, XMLEventReader reader,\r
-                       XMLEvent parentEvent, DerivedUnitFacade facade)\r
-                       throws XMLStreamException {\r
+       private void handleLocality(MarkupImportState state, XMLEventReader reader,XMLEvent parentEvent, DerivedUnitFacade facade)throws XMLStreamException {\r
                String classValue = getClassOnlyAttribute(parentEvent);\r
                boolean isLocality = false;\r
                NamedAreaLevel areaLevel = null;\r
@@ -2072,8 +2057,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
         * @return\r
         * @throws XMLStreamException\r
         */\r
-       private NonViralName<?> handleNom(MarkupImportState state,\r
-                       XMLEventReader reader, XMLEvent parentEvent,\r
+       private NonViralName<?> handleNom(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent,\r
                        HomotypicalGroup homotypicalGroup) throws XMLStreamException {\r
                boolean isSynonym = false;\r
                boolean isNameType = state.isNameType();\r
@@ -2172,12 +2156,10 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                makeRankDecision(state, nameMap, name, event, infrank);\r
 \r
                // test consistency of rank and authors\r
-               testRankAuthorConsistency(name, event, authorStr, paraut, infrParAut,\r
-                               infrAut);\r
+               testRankAuthorConsistency(name, event, authorStr, paraut, infrParAut,infrAut);\r
 \r
                // authors\r
-               makeNomenclaturalAuthors(name, event, authorStr, paraut, infrParAut,\r
-                               infrAut);\r
+               makeNomenclaturalAuthors(name, event, authorStr, paraut, infrParAut,infrAut);\r
 \r
                // status\r
                // TODO handle pro parte, pro syn. etc.\r
@@ -2279,23 +2261,29 @@ public class MarkupDocumentImport extends MarkupImportBase implements
         * @param infrAut\r
         */\r
        private void makeNomenclaturalAuthors(NonViralName name, XMLEvent event,\r
-                       String authorStr, String paraut, String infrParAut, String infrAut) {\r
-               if (name.getRank().isInfraSpecific()) {\r
+                               String authorStr, String paraut, String infrParAut, String infrAut) {\r
+               if (name.getRank() != null && name.getRank().isInfraSpecific()) {\r
                        if (StringUtils.isNotBlank(infrAut)) {\r
                                INomenclaturalAuthor[] authorAndEx = authorAndEx(infrAut, event);\r
                                name.setCombinationAuthorTeam(authorAndEx[0]);\r
                                name.setExCombinationAuthorTeam(authorAndEx[1]);\r
                        }\r
                        if (StringUtils.isNotBlank(infrParAut)) {\r
-                               INomenclaturalAuthor[] authorAndEx = authorAndEx(infrParAut,\r
-                                               event);\r
+                               INomenclaturalAuthor[] authorAndEx = authorAndEx(infrParAut, event);\r
                                name.setBasionymAuthorTeam(authorAndEx[0]);\r
                                name.setExBasionymAuthorTeam(authorAndEx[1]);\r
                        }\r
                } else {\r
+                       if (name.getRank() == null){\r
+                               String message = "No rank defined. Check correct usage of authors!";\r
+                               fireWarningEvent(message, event, 4);\r
+                               if (isNotBlank(infrParAut) || isNotBlank(infrAut)){\r
+                                       authorStr = infrAut;\r
+                                       paraut = infrParAut;\r
+                               }\r
+                       }\r
                        if (StringUtils.isNotBlank(authorStr)) {\r
-                               INomenclaturalAuthor[] authorAndEx = authorAndEx(authorStr,\r
-                                               event);\r
+                               INomenclaturalAuthor[] authorAndEx = authorAndEx(authorStr, event);\r
                                name.setCombinationAuthorTeam(authorAndEx[0]);\r
                                name.setExCombinationAuthorTeam(authorAndEx[1]);\r
                        }\r
@@ -2326,6 +2314,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
        }\r
 \r
        /**\r
+        * Tests if the names rank is consistent with the given author strings.\r
         * @param name\r
         * @param event\r
         * @param authorStr\r
@@ -2334,19 +2323,20 @@ public class MarkupDocumentImport extends MarkupImportBase implements
         * @param infrAut\r
         */\r
        private void testRankAuthorConsistency(NonViralName name, XMLEvent event,\r
-                       String authorStr, String paraut, String infrParAut, String infrAut) {\r
+                                       String authorStr, String paraut, String infrParAut, String infrAut) {\r
+               if (name.getRank() == null){\r
+                       return;\r
+               }\r
                if (name.getRank().isInfraSpecific()) {\r
                        if (StringUtils.isBlank(infrParAut)\r
                                        && StringUtils.isNotBlank(infrAut)\r
-                                       && (StringUtils.isNotBlank(paraut) || StringUtils\r
-                                                       .isNotBlank(authorStr))) {\r
+                                       && (StringUtils.isNotBlank(paraut) || StringUtils.isNotBlank(authorStr))) {\r
                                String message = "Rank is infraspecicific but has only specific or higher author(s)";\r
                                fireWarningEvent(message, event, 4);\r
                        }\r
                } else {\r
                        // is not infraspecific\r
-                       if (StringUtils.isNotBlank(infrParAut)\r
-                                       || StringUtils.isNotBlank(infrAut)) {\r
+                       if (StringUtils.isNotBlank(infrParAut)  || StringUtils.isNotBlank(infrAut)) {\r
                                String message = "Rank is not infraspecicific but name has infra author(s)";\r
                                fireWarningEvent(message, event, 4);\r
                        }\r
@@ -2480,9 +2470,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
 \r
        }\r
 \r
-       private void handleRefPart(MarkupImportState state, XMLEventReader reader,\r
-                       XMLEvent parentEvent, Map<String, String> refMap)\r
-                       throws XMLStreamException {\r
+       private void handleRefPart(MarkupImportState state, XMLEventReader reader,XMLEvent parentEvent, Map<String, String> refMap) throws XMLStreamException {\r
                String classValue = getClassOnlyAttribute(parentEvent);\r
 \r
                String text = "";\r
@@ -2511,8 +2499,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
 \r
        }\r
 \r
-       private Reference createReference(MarkupImportState state,\r
-                       Map<String, String> refMap, XMLEvent parentEvent) {\r
+       private Reference createReference(MarkupImportState state, Map<String, String> refMap, XMLEvent parentEvent) {\r
                // TODO\r
                Reference reference;\r
 \r
@@ -2586,9 +2573,14 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                reference.setDatePublished(TimePeriod.parseString(year));\r
 \r
                // TODO\r
-               // ALTERNATEPUBTITLE\r
-               // ISSUE\r
-               // NOTES\r
+               String[] unhandledList = new String[]{ALTERNATEPUBTITLE, ISSUE, NOTES, STATUS};\r
+               for (String unhandled : unhandledList){\r
+                       String value = getAndRemoveMapKey(refMap, unhandled);\r
+                       if (isNotBlank(value)){\r
+                               this.handleNotYetImplementedAttributeValue(parentEvent, CLASS, unhandled);\r
+                       }\r
+               }\r
+               \r
                for (String key : refMap.keySet()) {\r
                        if (!DETAILS.equalsIgnoreCase(key)) {\r
                                this.fireUnexpectedAttributeValue(parentEvent, CLASS, key);\r
@@ -2638,85 +2630,77 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                }\r
        }\r
 \r
-       private void handleFeature(MarkupImportState state, XMLEventReader reader,\r
-                       XMLEvent parentEvent) throws XMLStreamException {\r
+       private void handleFeature(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent) throws XMLStreamException {\r
                String classValue = getClassOnlyAttribute(parentEvent);\r
                Feature feature = makeFeature(classValue, state, parentEvent);\r
                Taxon taxon = state.getCurrentTaxon();\r
-               TaxonDescription taxonDescription = getTaxonDescription(taxon, state\r
-                               .getConfig().getSourceReference(), NO_IMAGE_GALLERY, CREATE_NEW);\r
+               TaxonDescription taxonDescription = getTaxonDescription(taxon, state.getConfig().getSourceReference(), NO_IMAGE_GALLERY, CREATE_NEW);\r
                // TextData figureHolderTextData = null; //for use with one TextData for\r
                // all figure only\r
 \r
                boolean isDescription = feature.equals(Feature.DESCRIPTION());\r
                DescriptionElementBase lastDescriptionElement = null;\r
+               \r
                while (reader.hasNext()) {\r
                        XMLEvent next = readNoWhitespace(reader);\r
-                       if (next.isEndElement()) {\r
-                               if (isMyEndingElement(next, parentEvent)) {\r
-                                       return;\r
-                               } else {\r
-                                       if (isEndingElement(next, DISTRIBUTION_LIST)\r
-                                                       || isEndingElement(next, HABITAT_LIST)) {\r
-                                               // only handle list elements\r
-                                       } else {\r
-                                               handleUnexpectedEndElement(next.asEndElement());\r
-                                       }\r
+                       if (isMyEndingElement(next, parentEvent)) {\r
+                               return;\r
+                       } else if (isEndingElement(next, DISTRIBUTION_LIST) || isEndingElement(next, HABITAT_LIST)) { \r
+                               // only handle list elements\r
+                       } else if (isStartingElement(next, HEADING)) {\r
+                               makeFeatureHeading(state, reader, classValue, feature, next);\r
+                       } else if (isStartingElement(next, WRITER)) {\r
+                               makeFeatureWriter(state, reader, feature, taxon, next);\r
+//                     } else if (isStartingElement(next, DISTRIBUTION_LOCALITY)) {\r
+//                             if (!feature.equals(Feature.DISTRIBUTION())) {\r
+//                                     String message = "Distribution locality only allowed for feature of type 'distribution'";\r
+//                                     fireWarningEvent(message, next, 4);\r
+//                             }\r
+//                             handleDistributionLocality(state, reader, next);\r
+                       } else if (isStartingElement(next, DISTRIBUTION_LIST) || isStartingElement(next, HABITAT_LIST)) {\r
+                               // only handle single list elements\r
+                       } else if (isStartingElement(next, HABITAT)) {\r
+                               if (!(feature.equals(Feature.HABITAT())\r
+                                               || feature.equals(Feature.HABITAT_ECOLOGY()) \r
+                                               || feature.equals(Feature.ECOLOGY()))) {\r
+                                       String message = "Habitat only allowed for feature of type 'habitat','habitat ecology' or 'ecology'";\r
+                                       fireWarningEvent(message, next, 4);\r
                                }\r
-                       } else if (next.isStartElement()) {\r
-                               if (isStartingElement(next, HEADING)) {\r
-                                       makeFeatureHeading(state, reader, classValue, feature, next);\r
-                               } else if (isStartingElement(next, WRITER)) {\r
-                                       makeFeatureWriter(state, reader, feature, taxon, next);\r
-                               } else if (isStartingElement(next, DISTRIBUTION_LOCALITY)) {\r
-                                       if (!feature.equals(Feature.DISTRIBUTION())) {\r
-                                               String message = "Distribution locality only allowed for feature of type 'distribution'";\r
-                                               fireWarningEvent(message, next, 4);\r
-                                       }\r
-                                       handleDistributionLocality(state, reader, next);\r
-                               } else if (isStartingElement(next, DISTRIBUTION_LIST)\r
-                                               || isStartingElement(next, HABITAT_LIST)) {\r
-                                       // only handle single list elements\r
-                               } else if (isStartingElement(next, HABITAT)) {\r
-                                       if (!(feature.equals(Feature.HABITAT())\r
-                                                       || feature.equals(Feature.HABITAT_ECOLOGY()) || feature\r
-                                                       .equals(Feature.ECOLOGY()))) {\r
-                                               String message = "Habitat only allowed for feature of type 'habitat','habitat ecology' or 'ecology'";\r
-                                               fireWarningEvent(message, next, 4);\r
-                                       }\r
-                                       handleHabitat(state, reader, next);\r
-                               } else if (isStartingElement(next, CHAR)) {\r
-                                       TextData textData = handleChar(state, reader, next);\r
-                                       taxonDescription.addElement(textData);\r
-                               } else if (isStartingElement(next, STRING)) {\r
-                                       lastDescriptionElement = makeFeatureString(state, reader,feature, taxonDescription, lastDescriptionElement,next);\r
-                               } else if (isStartingElement(next, FIGURE_REF)) {\r
-                                       lastDescriptionElement = makeFeatureFigureRef(state, reader, taxonDescription, isDescription, lastDescriptionElement, next);\r
-                               } else if (isStartingElement(next, REFERENCES)) {\r
-                                       // TODO details/microcitation ??\r
-\r
-                                       List<Reference<?>> refs = handleReferences(state, reader, next);\r
-                                       if (!refs.isEmpty()) {\r
-                                               // TODO\r
-                                               Reference<?> descriptionRef = state.getConfig().getSourceReference();\r
-                                               TaxonDescription description = getTaxonDescription(taxon, descriptionRef, false, true);\r
-                                               TextData featurePlaceholder = getFeaturePlaceholder(state, description, feature, true);\r
-                                               for (Reference<?> citation : refs) {\r
-                                                       featurePlaceholder.addSource(null, null, citation, null);\r
-                                               }\r
-                                       } else {\r
-                                               String message = "No reference found in references";\r
-                                               fireWarningEvent(message, next, 6);\r
+                               handleHabitat(state, reader, next);\r
+                       } else if (isStartingElement(next, CHAR)) {\r
+                               TextData textData = handleChar(state, reader, next);\r
+                               taxonDescription.addElement(textData);\r
+                       } else if (isStartingElement(next, STRING)) {\r
+                               lastDescriptionElement = makeFeatureString(state, reader,feature, taxonDescription, lastDescriptionElement,next);\r
+                       } else if (isStartingElement(next, FIGURE_REF)) {\r
+                               lastDescriptionElement = makeFeatureFigureRef(state, reader, taxonDescription, isDescription, lastDescriptionElement, next);\r
+                       } else if (isStartingElement(next, REFERENCES)) {\r
+                               // TODO details/microcitation ??\r
+\r
+                               List<Reference<?>> refs = handleReferences(state, reader, next);\r
+                               if (!refs.isEmpty()) {\r
+                                       // TODO\r
+                                       Reference<?> descriptionRef = state.getConfig().getSourceReference();\r
+                                       TaxonDescription description = getTaxonDescription(taxon, descriptionRef, false, true);\r
+                                       TextData featurePlaceholder = getFeaturePlaceholder(state, description, feature, true);\r
+                                       for (Reference<?> citation : refs) {\r
+                                               featurePlaceholder.addSource(null, null, citation, null);\r
                                        }\r
                                } else {\r
-                                       handleUnexpectedStartElement(next);\r
+                                       String message = "No reference found in references";\r
+                                       fireWarningEvent(message, next, 6);\r
                                }\r
+                       } else if (isStartingElement(next, NUM)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, NUM)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
                        } else {\r
                                handleUnexpectedElement(next);\r
                        }\r
                }\r
-               // TODO handle missing end element\r
-               throw new IllegalStateException("Feature has no closing tag");\r
+               throw new IllegalStateException("<Feature> has no closing tag");\r
        }\r
 \r
        /**\r
@@ -2729,15 +2713,10 @@ public class MarkupDocumentImport extends MarkupImportBase implements
         * @return\r
         * @throws XMLStreamException\r
         */\r
-       private DescriptionElementBase makeFeatureFigureRef(\r
-                       MarkupImportState state, XMLEventReader reader,\r
-                       TaxonDescription taxonDescription, boolean isDescription,\r
-                       DescriptionElementBase lastDescriptionElement, XMLEvent next)\r
-                       throws XMLStreamException {\r
+       private DescriptionElementBase makeFeatureFigureRef(MarkupImportState state, XMLEventReader reader,TaxonDescription taxonDescription, \r
+                                       boolean isDescription, DescriptionElementBase lastDescriptionElement, XMLEvent next)throws XMLStreamException {\r
                FigureDataHolder figureHolder = handleFigureRef(state, reader, next);\r
-               Feature figureFeature = getFeature(state,\r
-                               MarkupTransformer.uuidFigures, "Figures", "Figures", "Fig.",\r
-                               null);\r
+               Feature figureFeature = getFeature(state,MarkupTransformer.uuidFigures, "Figures", "Figures", "Fig.",null);\r
                if (isDescription) {\r
                        TextData figureHolderTextData = null;\r
                        // if (figureHolderTextData == null){\r
@@ -2750,10 +2729,8 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                figureHolderTextData.addAnnotation(annotation);\r
                        }\r
                        if (StringUtils.isNotBlank(figureHolder.figurePart)) {\r
-                               String annotationText = "<figurePart>"\r
-                                               + figureHolder.figurePart.trim() + "</figurePart>";\r
-                               Annotation annotation = Annotation.NewInstance(annotationText,\r
-                                               AnnotationType.EDITORIAL(), Language.DEFAULT());\r
+                               String annotationText = "<figurePart>"+ figureHolder.figurePart.trim() + "</figurePart>";\r
+                               Annotation annotation = Annotation.NewInstance(annotationText,AnnotationType.EDITORIAL(), Language.DEFAULT());\r
                                figureHolderTextData.addAnnotation(annotation);\r
                        }\r
                        // if (StringUtils.isNotBlank(figureText)){\r
@@ -2781,14 +2758,14 @@ public class MarkupDocumentImport extends MarkupImportBase implements
         * @param feature\r
         * @param taxonDescription\r
         * @param lastDescriptionElement\r
+        * @param distributionList \r
         * @param next\r
         * @return\r
         * @throws XMLStreamException\r
         */\r
-       private DescriptionElementBase makeFeatureString(MarkupImportState state,XMLEventReader reader, Feature feature,\r
-                       TaxonDescription taxonDescription, DescriptionElementBase lastDescriptionElement, XMLEvent next)\r
-                       throws XMLStreamException {\r
-               Map<String, String> subheadingMap = handleString(state, reader, next);\r
+       private DescriptionElementBase makeFeatureString(MarkupImportState state,XMLEventReader reader, Feature feature, \r
+                               TaxonDescription taxonDescription, DescriptionElementBase lastDescriptionElement, XMLEvent next) throws XMLStreamException {\r
+               Map<String, String> subheadingMap = handleString(state, reader, next, feature);\r
                for (String subheading : subheadingMap.keySet()) {\r
                        Feature subheadingFeature = feature;\r
                        if (StringUtils.isNotBlank(subheading) && subheadingMap.size() > 1) {\r
@@ -2812,9 +2789,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
         * @param next\r
         * @throws XMLStreamException\r
         */\r
-       private void makeFeatureWriter(MarkupImportState state,\r
-                       XMLEventReader reader, Feature feature, Taxon taxon, XMLEvent next)\r
-                       throws XMLStreamException {\r
+       private void makeFeatureWriter(MarkupImportState state,XMLEventReader reader, Feature feature, Taxon taxon, XMLEvent next) throws XMLStreamException {\r
                WriterDataHolder writer = handleWriter(state, reader, next);\r
                if (isNotBlank(writer.writer)) {\r
                        // TODO\r
@@ -2839,9 +2814,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
         * @param next\r
         * @throws XMLStreamException\r
         */\r
-       private void makeFeatureHeading(MarkupImportState state,\r
-                       XMLEventReader reader, String classValue, Feature feature,\r
-                       XMLEvent next) throws XMLStreamException {\r
+       private void makeFeatureHeading(MarkupImportState state, XMLEventReader reader, String classValue, Feature feature, XMLEvent next) throws XMLStreamException {\r
                String heading = handleHeading(state, reader, next);\r
                if (StringUtils.isNotBlank(heading)) {\r
                        if (!heading.equalsIgnoreCase(classValue)) {\r
@@ -2866,8 +2839,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                }\r
        }\r
 \r
-       private List<Reference<?>> handleReferences(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent)\r
-                       throws XMLStreamException {\r
+       private List<Reference<?>> handleReferences(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent) throws XMLStreamException {\r
                // attributes\r
                Map<String, Attribute> attributes = getAttributes(parentEvent);\r
                String bibliography = getAndRemoveAttributeValue(attributes,\r
@@ -2937,8 +2909,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                throw new IllegalStateException("<References> has no closing tag");\r
        }\r
 \r
-       private void handleHabitat(MarkupImportState state, XMLEventReader reader,\r
-                       XMLEvent parentEvent) throws XMLStreamException {\r
+       private void handleHabitat(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent) throws XMLStreamException {\r
                checkNoAttributes(parentEvent);\r
                Taxon taxon = state.getCurrentTaxon();\r
                // TODO which ref to take?\r
@@ -2979,9 +2950,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                throw new IllegalStateException("<Habitat> has no closing tag");\r
        }\r
 \r
-       private String getTaggedCData(MarkupImportState state,\r
-                       XMLEventReader reader, XMLEvent parentEvent)\r
-                       throws XMLStreamException {\r
+       private String getTaggedCData(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent) throws XMLStreamException {\r
                checkNoAttributes(parentEvent);\r
 \r
                String text = getXmlTag(parentEvent);\r
@@ -3004,49 +2973,56 @@ public class MarkupDocumentImport extends MarkupImportBase implements
 \r
        }\r
 \r
-       private void handleDistributionLocality(MarkupImportState state,\r
-                       XMLEventReader reader, XMLEvent parentEvent)\r
-                       throws XMLStreamException {\r
-               String classValue = getClassOnlyAttribute(parentEvent);\r
+       private void handleDistributionLocality(MarkupImportState state,XMLEventReader reader, XMLEvent parentEvent)throws XMLStreamException {\r
+               Map<String, Attribute> attributes = getAttributes(parentEvent);\r
+               String classValue = getAndRemoveRequiredAttributeValue(parentEvent, attributes, CLASS);\r
+               String statusValue =getAndRemoveAttributeValue(attributes, STATUS);\r
+               String frequencyValue =getAndRemoveAttributeValue(attributes, FREQUENCY);\r
+               \r
 \r
                Taxon taxon = state.getCurrentTaxon();\r
                // TODO which ref to take?\r
-               Reference ref = state.getConfig().getSourceReference();\r
+               Reference<?> ref = state.getConfig().getSourceReference();\r
 \r
                String text = "";\r
                while (reader.hasNext()) {\r
                        XMLEvent next = readNoWhitespace(reader);\r
                        if (isMyEndingElement(next, parentEvent)) {\r
                                if (StringUtils.isNotBlank(text)) {\r
-                                       TaxonDescription description = getTaxonDescription(taxon,\r
-                                                       ref, false, true);\r
-                                       NamedAreaLevel level = makeNamedAreaLevel(state,\r
-                                                       classValue, next);\r
+                                       TaxonDescription description = getTaxonDescription(taxon, ref, false, true);\r
+                                       NamedAreaLevel level = makeNamedAreaLevel(state,classValue, next);\r
                                        NamedArea area = createArea(text, level, state);\r
 \r
                                        PresenceAbsenceTermBase<?> status = null;\r
-                                       Distribution distribution = Distribution.NewInstance(area,\r
-                                                       status);\r
+                                       try {\r
+                                               status = state.getTransformer().getPresenceTermByKey(statusValue);\r
+                                       } catch (UndefinedTransformerMethodException e) {\r
+                                               throw new RuntimeException(e);\r
+                                       }\r
+                                       Distribution distribution = Distribution.NewInstance(area,status);\r
                                        description.addElement(distribution);\r
+                                       if (isNotBlank(frequencyValue)){\r
+                                               String message = "The frequency attribute is currently not yet available in CDM";\r
+                                               fireWarningEvent(message, parentEvent, 6);\r
+                                       }\r
                                } else {\r
                                        String message = "Empty distribution locality";\r
                                        fireWarningEvent(message, next, 4);\r
                                }\r
                                return;\r
-                       } else if (next.isStartElement()) {\r
-                               if (isStartingElement(next, COORDINATES)) {\r
-                                       handleNotYetImplementedElement(next);\r
-                               } else {\r
-                                       handleUnexpectedStartElement(next.asStartElement());\r
-                               }\r
+                       } else if (isStartingElement(next, COORDINATES)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, COORDINATES)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
                        } else if (next.isCharacters()) {\r
                                text += next.asCharacters().getData();\r
                        } else {\r
                                handleUnexpectedEndElement(next.asEndElement());\r
                        }\r
                }\r
-               throw new IllegalStateException(\r
-                               "<DistributionLocality> has no closing tag");\r
+               throw new IllegalStateException("<DistributionLocality> has no closing tag");\r
        }\r
 \r
        /**\r
@@ -3061,8 +3037,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                try {\r
                        level = state.getTransformer().getNamedAreaLevelByKey(levelString);\r
                        if (level == null) {\r
-                               UUID levelUuid = state.getTransformer().getNamedAreaLevelUuid(\r
-                                               levelString);\r
+                               UUID levelUuid = state.getTransformer().getNamedAreaLevelUuid(levelString);\r
                                if (levelUuid == null) {\r
                                        String message = "Unknown distribution locality class (named area level): %s. Create new level instead.";\r
                                        message = String.format(message, levelString);\r
@@ -3077,9 +3052,7 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                return level;\r
        }\r
 \r
-       private String handleHeading(MarkupImportState state,\r
-                       XMLEventReader reader, XMLEvent parentEvent)\r
-                       throws XMLStreamException {\r
+       private String handleHeading(MarkupImportState state,XMLEventReader reader, XMLEvent parentEvent)throws XMLStreamException {\r
                checkNoAttributes(parentEvent);\r
 \r
                String text = "";\r
@@ -3103,9 +3076,16 @@ public class MarkupDocumentImport extends MarkupImportBase implements
 \r
        }\r
 \r
-       private Map<String, String> handleString(MarkupImportState state,\r
-                       XMLEventReader reader, XMLEvent parentEvent)\r
-                       throws XMLStreamException {\r
+       /**\r
+        * Handle string\r
+        * @param state\r
+        * @param reader\r
+        * @param parentEvent\r
+        * @param feature only needed for distributionLocalities\r
+        * @return\r
+        * @throws XMLStreamException\r
+        */\r
+       private Map<String, String> handleString(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent, Feature feature)throws XMLStreamException {\r
                // attributes\r
                String classValue = getClassOnlyAttribute(parentEvent, false);\r
                if (StringUtils.isNotBlank(classValue)) {\r
@@ -3135,6 +3115,13 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                text = putCurrentSubheading(subHeadingMap,currentSubheading, text);\r
                                // TODO footnotes\r
                                currentSubheading = getCData(state, reader, next).trim();\r
+                       } else if (isStartingElement(next, DISTRIBUTION_LOCALITY)) {\r
+                               if (feature != null && !feature.equals(Feature.DISTRIBUTION())) {\r
+                                       String message = "Distribution locality only allowed for feature of type 'distribution'";\r
+                                       fireWarningEvent(message, next, 4);\r
+                               }\r
+                               handleDistributionLocality(state, reader, next);\r
+                       \r
                        } else if (next.isCharacters()) {\r
                                if (!isTextMode) {\r
                                        String message = "String is not in text mode";\r
@@ -3142,10 +3129,46 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                } else {\r
                                        text += next.asCharacters().getData();\r
                                }\r
-                       } else if (isStartingElement(next, COLLECTION)) {\r
+                       } else if (isStartingElement(next, HEADING)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, HEADING)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, QUOTE)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, QUOTE)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, DEDICATION)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, DEDICATION)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, TAXONTYPE)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, TAXONTYPE)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, FULL_NAME)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, FULL_NAME)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       }else if (isStartingElement(next, REFERENCES)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, REFERENCES)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, GATHERING)) {\r
                                //TODO\r
                                handleNotYetImplementedElement(next);\r
-                       } else if (isEndingElement(next, COLLECTION)) {\r
+                       } else if (isEndingElement(next, GATHERING)) {\r
                                //TODO\r
                                popUnimplemented(next.asEndElement());\r
                        } else if (isStartingElement(next, ANNOTATION)) {\r
@@ -3154,6 +3177,48 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                        } else if (isEndingElement(next, ANNOTATION)) {\r
                                //TODO\r
                                popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, HABITAT)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, HABITAT)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, FIGURE_REF)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, FIGURE_REF)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, FIGURE)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, FIGURE)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, FOOTNOTE_REF)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, FOOTNOTE_REF)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, FOOTNOTE)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, FOOTNOTE)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, WRITER)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, WRITER)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
+                       } else if (isStartingElement(next, DATES)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, DATES)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
                        } else {\r
                                handleUnexpectedElement(next);\r
                        }\r
@@ -3240,6 +3305,12 @@ public class MarkupDocumentImport extends MarkupImportBase implements
                                TextData textData = TextData.NewInstance(feature);\r
                                textData.putText(Language.DEFAULT(), text);\r
                                return textData;\r
+                       } else if (isStartingElement(next, FIGURE_REF)) {\r
+                               //TODO\r
+                               handleNotYetImplementedElement(next);\r
+                       } else if (isEndingElement(next, FIGURE_REF)) {\r
+                               //TODO\r
+                               popUnimplemented(next.asEndElement());\r
                        } else if (next.isStartElement()) {\r
                                if (isStartingElement(next, ANNOTATION)) {\r
                                        handleNotYetImplementedElement(next);\r
@@ -3266,29 +3337,27 @@ public class MarkupDocumentImport extends MarkupImportBase implements
         * @return\r
         * @throws UndefinedTransformerMethodException\r
         */\r
-       private Feature makeFeature(String classValue, MarkupImportState state,\r
-                       XMLEvent parentEvent) {\r
+       private Feature makeFeature(String classValue, MarkupImportState state, XMLEvent parentEvent) {\r
                UUID uuid;\r
                try {\r
-                       Feature feature = state.getTransformer()\r
-                                       .getFeatureByKey(classValue);\r
+                       Feature feature = state.getTransformer().getFeatureByKey(classValue);\r
                        if (feature != null) {\r
                                return feature;\r
                        }\r
                        uuid = state.getTransformer().getFeatureUuid(classValue);\r
                        if (uuid == null) {\r
                                // TODO\r
-                               logger.warn("Uuid is null for " + classValue);\r
+                               String message = "Uuid is not defined for %s";\r
+                               message = String.format(message, classValue);\r
+                               fireWarningEvent(message, parentEvent, 8);\r
                        }\r
                        String featureText = StringUtils.capitalize(classValue);\r
 \r
                        // TODO eFlora vocabulary\r
                        TermVocabulary<Feature> voc = null;\r
-                       feature = getFeature(state, uuid, featureText, featureText,\r
-                                       classValue, voc);\r
+                       feature = getFeature(state, uuid, featureText, featureText, classValue, voc);\r
                        if (feature == null) {\r
-                               throw new NullPointerException(classValue\r
-                                               + " not recognized as a feature");\r
+                               throw new NullPointerException(classValue + " not recognized as a feature");\r
                        }\r
                        return feature;\r
                } catch (Exception e) {\r
index 2968519b11edcf1b4024338c9ff0db589f8a43fa..c94411f0032ad396091c3f76f4be5d34b5fc806c 100644 (file)
@@ -19,6 +19,7 @@ import eu.etaxonomy.cdm.io.common.mapping.InputTransformerBase;
 import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;\r
 import eu.etaxonomy.cdm.model.common.MarkerType;\r
 import eu.etaxonomy.cdm.model.description.Feature;\r
+import eu.etaxonomy.cdm.model.description.PresenceTerm;\r
 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;\r
 \r
 /**\r
@@ -60,12 +61,18 @@ public class MarkupTransformer extends InputTransformerBase {
        public static final UUID uuidFigure = UUID.fromString("5165cd6a-9b31-4a1f-8b30-04ab740c502c");\r
        public static final UUID uuidFigures = UUID.fromString("6dfb4e78-c67e-410c-8989-c1fb1295abf6");\r
        \r
+       \r
+       \r
+       \r
        public static final UUID uuidExtractedHabitat = UUID.fromString("d80511d2-a76c-48b8-b3aa-5fbd4a58fe5c");\r
-       public static final UUID uuidHabit = UUID.fromString("03487108-173a-4335-92be-05076af29155");\r
+//     public static final UUID uuidHabit = UUID.fromString("03487108-173a-4335-92be-05076af29155");\r
        public static final UUID uuidHabitat = UUID.fromString("fb16929f-bc9c-456f-9d40-dec987b36438");\r
        public static final UUID uuidHabitatEcology = UUID.fromString("9fdc4663-4d56-47d0-90b5-c0bf251bafbb");\r
        \r
        public static final UUID uuidChromosomes = UUID.fromString("c4a60319-4978-4692-9545-58d60cf8379e");\r
+       public static final UUID uuidPhylogeny = UUID.fromString("8bcffbeb-a849-4222-83f9-bfcbbc3baef9");\r
+       public static final UUID uuidHistory = UUID.fromString("6f9f0316-1c27-4e17-b96a-51332521f74e");\r
+       public static final UUID uuidCultivation = UUID.fromString("f10f34fb-53b9-43c2-bfd6-05ea475e8e0f");\r
        \r
        public static final UUID uuidNote = UUID.fromString("b9af1489-6b68-497f-8d4b-260a9f886827");\r
        public static final UUID uuidNotes = UUID.fromString("e31bb420-f39e-493d-b452-dd5e63dda443");\r
@@ -155,6 +162,8 @@ public class MarkupTransformer extends InputTransformerBase {
        public static final UUID uuidPerianth = UUID.fromString("bd1480bb-ce44-495f-a462-98db4ac80530");\r
        public static final UUID uuidScales = UUID.fromString("bd1480bb-ce44-495f-a462-98db4ac80530");\r
        public static final UUID uuidPerigoneTube = UUID.fromString("d1799423-31ce-4525-b0ba-8d7cc9240abf");\r
+       public static final UUID uuidPerigoneLobes = UUID.fromString("e309e1e3-8f60-4478-9b89-ca5069bc1622");\r
+       public static final UUID uuidPerigone = UUID.fromString("f026fc87-5fc6-4559-a7e5-e8832c20033d");\r
        public static final UUID uuidCorolla = UUID.fromString("9ff17ff9-cb59-4ad7-bfa1-1d67935e567f");\r
        public static final UUID uuidAnnulus = UUID.fromString("d9b93acb-9b49-45ef-8661-09e00081931f");\r
        public static final UUID uuidFemaleFlowers = UUID.fromString("2e06cea2-5993-417c-8d0d-81cb571aa17a");\r
@@ -217,14 +226,18 @@ public class MarkupTransformer extends InputTransformerBase {
        public UUID getFeatureUuid(String key)  throws UndefinedTransformerMethodException {\r
                if (CdmUtils.isEmpty(key)){return null;\r
 \r
+               \r
+               }else if (key.equalsIgnoreCase("cultivation")){return uuidCultivation;\r
+               }else if (key.equalsIgnoreCase("history")){return uuidHistory;\r
+               }else if (key.equalsIgnoreCase("phylogeny")){return uuidPhylogeny;\r
                }else if (key.equalsIgnoreCase("Chromosomes")){return uuidChromosomes;\r
-               }else if (key.equalsIgnoreCase("habit")){return uuidHabit;\r
                }else if (key.equalsIgnoreCase("Habitat")){return uuidHabitat;\r
                }else if (key.equalsIgnoreCase("Habitat & Ecology")){return uuidHabitatEcology;\r
                }else if (key.equalsIgnoreCase("Leaflets")){return uuidLeaflets;\r
                }else if (key.equalsIgnoreCase("Leaves")){return uuidLeaves;\r
                }else if (key.equalsIgnoreCase("Branchlets")){return uuidBranchlets;\r
                }else if (key.equalsIgnoreCase("lifeform")){return uuidLifeform;\r
+               }else if (key.equalsIgnoreCase("habit")){return uuidLifeform;\r
                }else if (key.equalsIgnoreCase("Inflorescences")){return uuidInflorescences;\r
                }else if (key.equalsIgnoreCase("Flowers")){return uuidFlowers;\r
                }else if (key.equalsIgnoreCase("Sepals")){return uuidSepals;\r
@@ -258,8 +271,8 @@ public class MarkupTransformer extends InputTransformerBase {
                }else if (key.equalsIgnoreCase("Fruit")){return uuidFruit;\r
                }else if (key.equalsIgnoreCase("Branch")){return uuidBranch;\r
                }else if (key.equalsIgnoreCase("Inflorescence")){return uuidInflorescence;\r
-               }else if (key.equalsIgnoreCase("male inflorescences")){return uuidMaleInflorescences;\r
-               }else if (key.equalsIgnoreCase("female inflorescences")){return uuidFemaleInflorescences;\r
+               }else if (key.equalsIgnoreCase("Male inflorescences")){return uuidMaleInflorescences;\r
+               }else if (key.equalsIgnoreCase("Female inflorescences")){return uuidFemaleInflorescences;\r
                \r
                }else if (key.equalsIgnoreCase("Calyx")){return uuidCalyx;\r
                }else if (key.equalsIgnoreCase("Seedling")){return uuidSeedling;\r
@@ -286,6 +299,9 @@ public class MarkupTransformer extends InputTransformerBase {
                }else if (key.equalsIgnoreCase("perianth")){return uuidPerianth;\r
                }else if (key.equalsIgnoreCase("scales")){return uuidScales;\r
                }else if (key.equalsIgnoreCase("perigone tube")){return uuidPerigoneTube;\r
+               }else if (key.equalsIgnoreCase("perigone")){return uuidPerigone;\r
+               }else if (key.equalsIgnoreCase("perigone lobes")){return uuidPerigoneLobes;\r
+               \r
                }else if (key.equalsIgnoreCase("corolla")){return uuidCorolla;\r
                }else if (key.equalsIgnoreCase("annulus")){return uuidAnnulus;\r
                }else if (key.equalsIgnoreCase("female flowers")){return uuidFemaleFlowers;\r
@@ -328,6 +344,7 @@ public class MarkupTransformer extends InputTransformerBase {
                }else if (key.equalsIgnoreCase("Flower morphology")){return uuidFlowerMorphology;\r
                }else if (key.equalsIgnoreCase("Pollination")){return uuidPollination;\r
                }else if (key.equalsIgnoreCase("Life cycle")){return uuidLifeCycle;\r
+               }else if (key.equalsIgnoreCase("lifehistory")){return uuidLifeCycle;\r
                }else if (key.equalsIgnoreCase("Fruits and embryology")){return uuidFruitsAndEmbryology;\r
                }else if (key.equalsIgnoreCase("Dispersal")){return uuidDispersal;\r
                }else if (key.equalsIgnoreCase("Phytochemistry")){return uuidPhytochemistry;\r
@@ -405,8 +422,7 @@ public class MarkupTransformer extends InputTransformerBase {
         * @see eu.etaxonomy.cdm.io.common.mapping.InputTransformerBase#getNamedAreaLevelUuid(java.lang.String)\r
         */\r
        @Override\r
-       public UUID getNamedAreaLevelUuid(String key)\r
-                       throws UndefinedTransformerMethodException {\r
+       public UUID getNamedAreaLevelUuid(String key) throws UndefinedTransformerMethodException {\r
                if (CdmUtils.isEmpty(key)){return null;\r
                }else if (key.equalsIgnoreCase("region")){return uuidRegion;\r
                }else if (key.equalsIgnoreCase("world")){return uuidWorld;\r
@@ -419,6 +435,31 @@ public class MarkupTransformer extends InputTransformerBase {
                        return null;\r
                }\r
        }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.common.mapping.InputTransformerBase#getPresenceTermByKey(java.lang.String)\r
+        */\r
+       @Override\r
+       public PresenceTerm getPresenceTermByKey(String key) throws UndefinedTransformerMethodException {\r
+               if (CdmUtils.isEmpty(key)){return null;\r
+               }else if (key.equalsIgnoreCase("endemic")){return PresenceTerm.ENDEMIC_FOR_THE_RELEVANT_AREA();\r
+               }else if (key.equalsIgnoreCase("cultivated")){return PresenceTerm.CULTIVATED();\r
+               }else{\r
+                       return null;\r
+               }\r
+       }\r
+\r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.io.common.mapping.InputTransformerBase#getPresenceTermUuid(java.lang.String)\r
+        */\r
+       @Override\r
+       public UUID getPresenceTermUuid(String key) throws UndefinedTransformerMethodException {\r
+               if (CdmUtils.isEmpty(key)){return null;\r
+//             }else if (key.equalsIgnoreCase("region")){return uuidRegion;\r
+               }else{\r
+                       return null;\r
+               }\r
+       }\r
        \r
        \r
        \r
index e43452ab16df77c7041915c6ea4312dfced7a578..2e60835f79cfdaaa9b5407678c6b3352ef18b0ed 100644 (file)
@@ -54,6 +54,7 @@ public class UnmatchedLeads {
                //taxonKey\r
                String numAndTaxon;\r
 \r
+               \r
                public boolean isInnerLead(){\r
                        return (key != null);\r
                }\r
@@ -160,6 +161,11 @@ public class UnmatchedLeads {
                return false;\r
        }\r
        \r
+\r
+       public int size(){\r
+               return map.size();\r
+       }\r
+       \r
        /**\r
         * SaveOrUpdates all polytomousKeyNodes in the unmatchedLeadsKey map.\r
         * Used to move nodes from one transaction to another.\r