2 * Copyright (C) 2009 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.io
.markup
;
12 import java
.net
.MalformedURLException
;
14 import java
.util
.HashSet
;
17 import java
.util
.UUID
;
19 import javax
.xml
.stream
.Location
;
20 import javax
.xml
.stream
.XMLEventReader
;
21 import javax
.xml
.stream
.XMLStreamException
;
22 import javax
.xml
.stream
.events
.Attribute
;
23 import javax
.xml
.stream
.events
.StartElement
;
24 import javax
.xml
.stream
.events
.XMLEvent
;
26 import org
.apache
.commons
.lang
.StringUtils
;
27 import org
.apache
.log4j
.Logger
;
29 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.UndefinedTransformerMethodException
;
30 import eu
.etaxonomy
.cdm
.model
.agent
.TeamOrPersonBase
;
31 import eu
.etaxonomy
.cdm
.model
.common
.ExtensionType
;
32 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
33 import eu
.etaxonomy
.cdm
.model
.common
.OriginalSourceType
;
34 import eu
.etaxonomy
.cdm
.model
.common
.TermVocabulary
;
35 import eu
.etaxonomy
.cdm
.model
.description
.CommonTaxonName
;
36 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
37 import eu
.etaxonomy
.cdm
.model
.description
.Distribution
;
38 import eu
.etaxonomy
.cdm
.model
.description
.Feature
;
39 import eu
.etaxonomy
.cdm
.model
.description
.PolytomousKey
;
40 import eu
.etaxonomy
.cdm
.model
.description
.PolytomousKeyNode
;
41 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
42 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
43 import eu
.etaxonomy
.cdm
.model
.name
.CultivarPlantName
;
44 import eu
.etaxonomy
.cdm
.model
.name
.NonViralName
;
45 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
46 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
47 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceFactory
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
49 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
50 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
57 public class MarkupDocumentImportNoComponent
extends MarkupImportBase
{
58 @SuppressWarnings("unused")
59 private static final Logger logger
= Logger
.getLogger(MarkupDocumentImportNoComponent
.class);
61 private MarkupKeyImport keyImport
;
63 private MarkupModsImport modsImport
;
64 private MarkupFeatureImport featureImport
;
65 private MarkupSpecimenImport specimenImport
;
66 private MarkupNomenclatureImport nomenclatureImport
;
68 public MarkupDocumentImportNoComponent(MarkupDocumentImport docImport
) {
70 this.keyImport
= new MarkupKeyImport(docImport
);
71 this.specimenImport
= new MarkupSpecimenImport(docImport
);
72 this.nomenclatureImport
= new MarkupNomenclatureImport(docImport
, specimenImport
);
73 this.modsImport
= new MarkupModsImport(docImport
);
74 this.featureImport
= new MarkupFeatureImport(docImport
, specimenImport
, nomenclatureImport
);
77 public void doInvoke(MarkupImportState state
) throws XMLStreamException
{
78 XMLEventReader reader
= state
.getReader();
80 // publication (= root element)
81 String elName
= PUBLICATION
;
82 boolean hasPublication
= false;
84 while (reader
.hasNext()) {
85 XMLEvent nextEvent
= reader
.nextEvent();
86 if (isStartingElement(nextEvent
, elName
)) {
87 handlePublication(state
, reader
, nextEvent
, elName
);
88 hasPublication
= true;
89 } else if (nextEvent
.isEndDocument()) {
90 if (!hasPublication
) {
91 String message
= "No publication root element found";
92 fireWarningEvent(message
, nextEvent
, 8);
96 fireSchemaConflictEventExpectedStartTag(elName
, reader
);
105 private void handlePublication(MarkupImportState state
, XMLEventReader reader
, XMLEvent currentEvent
, String elName
) throws XMLStreamException
{
108 StartElement element
= currentEvent
.asStartElement();
109 Map
<String
, Attribute
> attributes
= getAttributes(element
);
110 String lang
= getAndRemoveAttributeValue(attributes
, "lang");
112 Language language
= getTermService().getLanguageByIso(lang
);
113 state
.setDefaultLanguage(language
);
116 handleUnexpectedAttributes(element
.getLocation(), attributes
, "noNamespaceSchemaLocation");
118 while (reader
.hasNext()) {
119 XMLEvent event
= readNoWhitespace(reader
);
120 // TODO cardinality of alternative
121 if (event
.isEndElement()) {
122 if (isEndingElement(event
, elName
)) {
125 if (isEndingElement(event
, BIOGRAPHIES
)) {
126 // NOT YET IMPLEMENTED
127 popUnimplemented(event
.asEndElement());
128 } else if (isEndingElement(event
, REFERENCES
)) {
129 // NOT YET IMPLEMENTED
130 popUnimplemented(event
.asEndElement());
131 } else if (isEndingElement(event
, TEXT_SECTION
)) {
132 // NOT YET IMPLEMENTED
133 popUnimplemented(event
.asEndElement());
134 } else if (isEndingElement(event
, ADDENDA
)) {
135 // NOT YET IMPLEMENTED
136 popUnimplemented(event
.asEndElement());
138 handleUnexpectedElement(event
);
141 } else if (event
.isStartElement()) {
142 if (isStartingElement(event
, META_DATA
)) {
143 handleMetaData(state
, reader
, event
);
144 } else if (isStartingElement(event
, TREATMENT
)) {
145 handleTreatment(state
, reader
, event
);
146 } else if (isStartingElement(event
, BIOGRAPHIES
)) {
147 handleNotYetImplementedElement(event
);
148 } else if (isStartingElement(event
, REFERENCES
)) {
149 handleNotYetImplementedElement(event
);
150 } else if (isStartingElement(event
, TEXT_SECTION
)) {
151 handleNotYetImplementedElement(event
);
152 } else if (isStartingElement(event
, ADDENDA
)) {
153 handleNotYetImplementedElement(event
);
155 handleUnexpectedStartElement(event
);
158 handleUnexpectedElement(event
);
161 throw new IllegalStateException("Publication has no ending element");
164 private void handleMetaData(MarkupImportState state
, XMLEventReader reader
, XMLEvent parentEvent
) throws XMLStreamException
{
165 checkNoAttributes(parentEvent
);
167 while (reader
.hasNext()) {
168 XMLEvent next
= readNoWhitespace(reader
);
169 if (isMyEndingElement(next
, parentEvent
)) {
171 } else if (isStartingElement(next
, DEFAULT_MEDIA_URL
)) {
172 String baseUrl
= getCData(state
, reader
, next
);
175 state
.setBaseMediaUrl(baseUrl
);
176 } catch (MalformedURLException e
) {
177 String message
= "defaultMediaUrl '%s' is not a valid URL";
178 message
= String
.format(message
, baseUrl
);
179 fireWarningEvent(message
, next
, 8);
181 } else if (isStartingElement(next
, MODS
)){
182 modsImport
.handleMods(state
, reader
, next
);
184 handleUnexpectedElement(next
);
187 throw new IllegalStateException("MetaData has no ending element");
191 private void handleTreatment(MarkupImportState state
, XMLEventReader reader
, XMLEvent parentEvent
) throws XMLStreamException
{
192 checkNoAttributes(parentEvent
);
193 Taxon lastTaxon
= null;
194 while (reader
.hasNext()) {
195 XMLEvent next
= readNoWhitespace(reader
);
196 if (isMyEndingElement(next
, parentEvent
)) {
197 Set
<PolytomousKeyNode
> keyNodesToSave
= state
.getPolytomousKeyNodesToSave();
198 //better save the key then the nodes
199 Set
<PolytomousKey
> keySet
= new HashSet
<PolytomousKey
>();
200 for (PolytomousKeyNode node
: keyNodesToSave
){
201 PolytomousKey key
= node
.getKey();
205 //unmatched key leads
206 UnmatchedLeads unmatched
= state
.getUnmatchedLeads();
207 if (unmatched
.size() > 0){
208 String message
= "The following key leads are unmatched: %s";
209 message
= String
.format(message
, state
.getUnmatchedLeads().toString());
210 fireWarningEvent(message
, next
, 6);
212 // save(keyNodesToSave, state);
215 } else if (isStartingElement(next
, TAXON
)) {
216 Taxon thisTaxon
= handleTaxon(state
, reader
, next
.asStartElement());
217 doTaxonRelation(state
, thisTaxon
, lastTaxon
, parentEvent
.getLocation());
218 if (state
.isTaxonInClassification() == true){
219 lastTaxon
= thisTaxon
;
220 // TODO for imports spanning multiple documents ?? Still needed?
221 state
.getConfig().setLastTaxonUuid(lastTaxon
.getUuid());
223 } else if (isStartingElement(next
, ADDENDA
)) {
224 handleNotYetImplementedElement(next
);
226 handleUnexpectedElement(next
);
236 private void doTaxonRelation(MarkupImportState state
, Taxon taxon
, Taxon lastTaxon
, Location dataLocation
) {
238 if (state
.isTaxonInClassification() == false){
242 Classification tree
= makeTree(state
, dataLocation
);
243 if (lastTaxon
== null) {
244 tree
.addChildTaxon(taxon
, null, null);
247 Rank thisRank
= taxon
.getName().getRank();
248 Rank lastRank
= lastTaxon
.getName().getRank();
249 if (lastRank
== null){
250 String message
= "Last rank was null. Can't create tree correctly";
251 fireWarningEvent(message
, makeLocationStr(dataLocation
), 12);
253 if (lastTaxon
.getTaxonNodes().size() > 0) {
254 TaxonNode lastNode
= lastTaxon
.getTaxonNodes().iterator().next();
255 if (thisRank
== null){
256 String message
= "Rank is undefined for taxon '%s'. Can't create classification without rank.";
257 message
= String
.format(message
, taxon
.getName().getTitleCache());
258 fireWarningEvent(message
, makeLocationStr(dataLocation
), 6);
259 }else if (thisRank
.isLower(lastRank
)) {
260 lastNode
.addChildTaxon(taxon
, null, null);
261 fillMissingEpithetsForTaxa(lastTaxon
, taxon
);
262 } else if (thisRank
.equals(lastRank
)) {
263 TaxonNode parent
= lastNode
.getParent();
264 if (parent
!= null) {
265 parent
.addChildTaxon(taxon
, null, null);
266 fillMissingEpithetsForTaxa(parent
.getTaxon(), taxon
);
268 tree
.addChildTaxon(taxon
, null, null);
270 } else if (thisRank
.isHigher(lastRank
)) {
271 TaxonNode parent
= lastNode
.getParent();
273 doTaxonRelation(state
, taxon
, parent
.getTaxon(), dataLocation
);
275 String warning
= "No parent available for lastNode. Classification can not be build correctly. Maybe the rank was missing for the lastNode";
276 fireWarningEvent(warning
, makeLocationStr(dataLocation
), 16);
277 //TODO what to do in this case (haven't spend time to think about yet
279 // TaxonNode parentNode = handleTaxonRelation(state, taxon,
280 // lastNode.getParent().getTaxon());
281 // parentNode.addChildTaxon(taxon, null, null, null);
284 String message
= "Last taxon has no node";
285 fireWarningEvent(message
, makeLocationStr(dataLocation
), 6);
293 * @param dataLocation
296 private Classification
makeTree(MarkupImportState state
, Location dataLocation
) {
297 Classification result
= state
.getTree(null);
298 if (result
== null) {
299 UUID uuid
= state
.getConfig().getClassificationUuid();
301 String message
= "No classification uuid is defined";
302 fireWarningEvent(message
, makeLocationStr(dataLocation
), 6);
303 result
= createNewClassification(state
);
305 result
= getClassificationService().find(uuid
);
306 if (result
== null) {
307 result
= createNewClassification(state
);
308 result
.setUuid(uuid
);
311 state
.putTree(null, result
);
317 private Classification
createNewClassification(MarkupImportState state
) {
318 Classification result
= Classification
.NewInstance(state
.getConfig().getClassificationName(), getDefaultLanguage(state
));
319 state
.putTree(null, result
);
323 private Taxon
handleTaxon(MarkupImportState state
, XMLEventReader reader
, StartElement parentEvent
) throws XMLStreamException
{
324 // TODO progress monitoring
325 Map
<String
, Attribute
> attributes
= getAttributes(parentEvent
);
326 Taxon taxon
= createTaxonAndName(state
, attributes
);
327 state
.setCurrentTaxon(taxon
);
328 state
.addNewFeatureSorterLists(taxon
.getUuid().toString());
330 boolean hasTitle
= false;
331 boolean hasNomenclature
= false;
332 String taxonTitle
= null;
334 Reference
<?
> descriptionReference
= state
.getConfig().getSourceReference();
335 while (reader
.hasNext()) {
336 XMLEvent next
= readNoWhitespace(reader
);
337 if (next
.isEndElement()) {
338 if (isMyEndingElement(next
, parentEvent
)) {
339 // checkMandatoryElement(hasTitle, parentEvent, TAXONTITLE);
340 checkMandatoryElement(hasNomenclature
, parentEvent
, NOMENCLATURE
);
341 boolean inClassification
= getAndRemoveBooleanAttributeValue(next
, attributes
, "inClassification", true);
342 state
.setTaxonInClassification(inClassification
);
343 handleUnexpectedAttributes(parentEvent
.getLocation(),attributes
);
344 if (taxon
.getName().getRank() == null){
345 String warning
= "No rank exists for taxon " + taxon
.getTitleCache();
346 fireWarningEvent(warning
, next
, 12);
347 taxon
.getName().setRank(Rank
.UNKNOWN_RANK());
350 keyImport
.makeKeyNodes(state
, parentEvent
, taxonTitle
);
351 state
.setCurrentTaxon(null);
352 state
.setCurrentTaxonNum(null);
353 if (taxon
.getName().getRank().isHigher(Rank
.GENUS())){
354 state
.setLatestGenusEpithet(null);
356 state
.setLatestGenusEpithet(((NonViralName
<?
>)taxon
.getName()).getGenusOrUninomial());
361 if (isEndingElement(next
, HEADING
)) {
362 // NOT YET IMPLEMENTED
363 popUnimplemented(next
.asEndElement());
364 } else if (isEndingElement(next
, TEXT_SECTION
)) {
365 // NOT YET IMPLEMENTED
366 popUnimplemented(next
.asEndElement());
367 } else if (isEndingElement(next
, REFERENCES
)) {
368 // NOT YET IMPLEMENTED
369 popUnimplemented(next
.asEndElement());
370 } else if (isEndingElement(next
, FIGURE_REF
)) {
371 // NOT YET IMPLEMENTED
372 popUnimplemented(next
.asEndElement());
374 handleUnexpectedEndElement(next
.asEndElement());
377 } else if (next
.isStartElement()) {
378 if (isStartingElement(next
, HEADING
)) {
379 handleNotYetImplementedElement(next
);
380 } else if (isStartingElement(next
, TAXONTITLE
)) {
381 taxonTitle
= handleTaxonTitle(state
, reader
, next
);
383 } else if (isStartingElement(next
, WRITER
)) {
384 makeKeyWriter(state
, reader
, taxon
, taxonTitle
, next
);
385 } else if (isStartingElement(next
, TEXT_SECTION
)) {
386 handleNotYetImplementedElement(next
);
387 } else if (isStartingElement(next
, KEY
)) {
388 keyImport
.handleKey(state
, reader
, next
);
389 } else if (isStartingElement(next
, NOMENCLATURE
)) {
390 nomenclatureImport
.handleNomenclature(state
, reader
, next
);
391 hasNomenclature
= true;
392 } else if (isStartingElement(next
, FEATURE
)) {
393 featureImport
.handleFeature(state
, reader
, next
);
394 } else if (isStartingElement(next
, NOTES
)) {
395 // TODO is this the correct way to handle notes?
396 String note
= handleNotes(state
, reader
, next
);
400 notesUuid
= state
.getTransformer().getFeatureUuid("notes");
401 Feature feature
= getFeature(state
, notesUuid
, "Notes", "Notes", "note", null);
402 TextData textData
= TextData
.NewInstance(feature
);
403 textData
.putText(getDefaultLanguage(state
), note
);
404 TaxonDescription description
= getTaxonDescription(taxon
, descriptionReference
, false, true);
405 description
.addElement(textData
);
406 } catch (UndefinedTransformerMethodException e
) {
407 String message
= "getFeatureUuid method not yet implemented";
408 fireWarningEvent(message
, next
, 8);
410 } else if (isStartingElement(next
, REFERENCES
)) {
411 handleNotYetImplementedElement(next
);
412 } else if (isStartingElement(next
, FIGURE_REF
)) {
413 TaxonDescription desc
= getTaxonDescription(taxon
, state
.getConfig().getSourceReference(), IMAGE_GALLERY
, CREATE_NEW
);
415 if (desc
.getElements().isEmpty()){
416 textData
= TextData
.NewInstance(Feature
.IMAGE());
417 desc
.addElement(textData
);
419 textData
= (TextData
)desc
.getElements().iterator().next();
420 featureImport
.makeFeatureFigureRef(state
, reader
, desc
, false, textData
, next
);
421 } else if (isStartingElement(next
, FIGURE
)) {
422 handleFigure(state
, reader
, next
, specimenImport
, nomenclatureImport
);
423 } else if (isStartingElement(next
, FOOTNOTE
)) {
424 FootnoteDataHolder footnote
= handleFootnote(state
, reader
, next
, specimenImport
, nomenclatureImport
);
425 if (footnote
.isRef()) {
426 String message
= "Ref footnote not implemented here";
427 fireWarningEvent(message
, next
, 4);
429 registerGivenFootnote(state
, footnote
);
432 handleUnexpectedStartElement(next
);
435 handleUnexpectedElement(next
);
438 throw new IllegalStateException("<Taxon> has no closing tag");
447 * @throws XMLStreamException
449 private void makeKeyWriter(MarkupImportState state
, XMLEventReader reader
, Taxon taxon
, String taxonTitle
, XMLEvent next
) throws XMLStreamException
{
450 WriterDataHolder writer
= handleWriter(state
, reader
, next
);
451 taxon
.addExtension(writer
.extension
);
452 // TODO what if taxonTitle comes later
453 if (StringUtils
.isNotBlank(taxonTitle
) && writer
.extension
!= null) {
454 Reference
<?
> sec
= ReferenceFactory
.newBookSection();
455 sec
.setTitle(taxonTitle
);
456 TeamOrPersonBase
<?
> author
= createAuthor(writer
.writer
);
457 sec
.setAuthorship(author
);
458 sec
.setInReference(state
.getConfig().getSourceReference());
460 registerFootnotes(state
, sec
, writer
.footnotes
);
462 String message
= "No taxontitle exists for writer";
463 fireWarningEvent(message
, next
, 6);
467 private String
handleNotes(MarkupImportState state
, XMLEventReader reader
,
468 XMLEvent parentEvent
) throws XMLStreamException
{
469 checkNoAttributes(parentEvent
);
472 while (reader
.hasNext()) {
473 XMLEvent next
= readNoWhitespace(reader
);
474 if (isMyEndingElement(next
, parentEvent
)) {
476 } else if (next
.isEndElement()) {
477 if (isEndingElement(next
, HEADING
)) {
478 popUnimplemented(next
.asEndElement());
479 } else if (isEndingElement(next
, WRITER
)) {
480 popUnimplemented(next
.asEndElement());
481 } else if (isEndingElement(next
, NUM
)) {
482 popUnimplemented(next
.asEndElement());
484 handleUnexpectedEndElement(next
.asEndElement());
486 } else if (next
.isStartElement()) {
487 if (isStartingElement(next
, HEADING
)) {
488 handleNotYetImplementedElement(next
);
489 } else if (isStartingElement(next
, SUB_HEADING
)) {
490 String subheading
= getCData(state
, reader
, next
).trim();
491 if (! isNoteHeading(subheading
)) {
492 fireNotYetImplementedElement(next
.getLocation(), next
.asStartElement().getName(), 0);
494 } else if (isStartingElement(next
, WRITER
)) {
495 handleNotYetImplementedElement(next
);
496 } else if (isStartingElement(next
, NUM
)) {
497 handleNotYetImplementedElement(next
);
498 } else if (isStartingElement(next
, STRING
)) {
499 // TODO why multiple strings in schema?
500 text
= makeNotesString(state
, reader
, text
, next
);
502 handleUnexpectedStartElement(next
.asStartElement());
505 handleUnexpectedElement(next
);
508 throw new IllegalStateException("<Notes> has no closing tag");
517 * @throws XMLStreamException
519 private String
makeNotesString(MarkupImportState state
, XMLEventReader reader
, String text
, XMLEvent next
) throws XMLStreamException
{
520 Map
<String
, String
> stringMap
= handleString(state
, reader
, next
, null);
521 if (stringMap
.size() == 0){
522 String message
= "No text available in <notes>";
523 fireWarningEvent(message
, next
, 4);
524 }else if (stringMap
.size() > 1){
525 String message
= "Subheadings not yet supported in <notes>";
526 fireWarningEvent(message
, next
, 4);
528 String firstSubheading
= stringMap
.keySet().iterator().next();
529 if ( firstSubheading
!= null && ! isNoteHeading (firstSubheading
) ) {
530 String message
= "Subheadings not yet supported in <notes>";
531 fireWarningEvent(message
, next
, 4);
534 for (String subheading
: stringMap
.keySet()){
536 text
+= stringMap
.get(subheading
);
541 private boolean isNoteHeading(String heading
) {
542 String excludePattern
= "(i?)(Notes?):?";
543 return heading
.matches(excludePattern
);
550 private Taxon
createTaxonAndName(MarkupImportState state
,
551 Map
<String
, Attribute
> attributes
) {
552 NonViralName
<?
> name
;
553 Rank rank
= null; //Rank.SPECIES(); // default
554 boolean isCultivar
= checkAndRemoveAttributeValue(attributes
, CLASS
, "cultivated");
556 name
= CultivarPlantName
.NewInstance(rank
);
558 name
= createNameByCode(state
, rank
);
560 Taxon taxon
= Taxon
.NewInstance(name
, state
.getConfig().getSourceReference());
561 if (checkAndRemoveAttributeValue(attributes
, CLASS
, "dubious")) {
562 taxon
.setDoubtful(true);
563 } else if (checkAndRemoveAttributeValue(attributes
, CLASS
, "excluded")) {
564 taxon
.setExcluded(true);
566 // TODO insufficient, new, expected
567 handleNotYetImplementedAttribute(attributes
, CLASS
);
569 // MarkerType markerType = getMarkerType(state, attrValue);
570 // if (markerType == null){
571 // logger.warn("Class attribute value for taxon not yet supported: " +
574 // taxon.addMarker(Marker.NewInstance(markerType, true));
577 // save(name, state);
578 // save(taxon, state);
582 private String
handleTaxonTitle(MarkupImportState state
, XMLEventReader reader
, XMLEvent parentEvent
) throws XMLStreamException
{
585 Map
<String
, Attribute
> attributes
= getAttributes(parentEvent
);
586 String rankAttr
= getAndRemoveAttributeValue(attributes
, RANK
);
587 Rank rank
= makeRank(state
, rankAttr
, false);
588 String num
= getAndRemoveAttributeValue(attributes
, NUM
);
589 state
.setCurrentTaxonNum(num
);
590 checkNoAttributes(attributes
, parentEvent
);
592 // TODO handle attributes
593 while (reader
.hasNext()) {
594 XMLEvent next
= readNoWhitespace(reader
);
595 if (next
.isEndElement()) {
596 if (isMyEndingElement(next
, parentEvent
)) {
597 Taxon taxon
= state
.getCurrentTaxon();
598 String titleText
= null;
599 if (checkMandatoryText(text
, parentEvent
)) {
600 titleText
= normalize(text
);
601 UUID uuidTitle
= MarkupTransformer
.uuidTaxonTitle
;
602 ExtensionType titleExtension
= this.getExtensionType(state
, uuidTitle
, "Taxon Title ","taxon title", "title");
603 taxon
.addExtension(titleText
, titleExtension
);
605 taxon
.getName().setRank(rank
);
606 // TODO check title exists
609 if (isEndingElement(next
, FOOTNOTE
)) {
610 // NOT YET IMPLEMENTED
611 popUnimplemented(next
.asEndElement());
613 handleUnexpectedEndElement(next
.asEndElement());
614 state
.setUnsuccessfull();
617 } else if (next
.isStartElement()) {
618 if (isStartingElement(next
, FOOTNOTE
)) {
619 handleNotYetImplementedElement(next
);
620 }else if (isStartingElement(next
, FOOTNOTE_REF
)) {
621 handleNotYetImplementedElement(next
);
623 handleUnexpectedStartElement(next
);
624 state
.setUnsuccessfull();
626 } else if (next
.isCharacters()) {
627 text
+= next
.asCharacters().getData();
630 handleUnexpectedElement(next
);
631 state
.setUnsuccessfull();