Revision 786696e3
Added by Andreas Müller over 10 years ago
cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/markup/MarkupNomenclatureImport.java | ||
---|---|---|
37 | 37 |
import eu.etaxonomy.cdm.model.name.Rank; |
38 | 38 |
import eu.etaxonomy.cdm.model.name.TaxonNameBase; |
39 | 39 |
import eu.etaxonomy.cdm.model.reference.IArticle; |
40 |
import eu.etaxonomy.cdm.model.reference.IBook; |
|
40 | 41 |
import eu.etaxonomy.cdm.model.reference.IJournal; |
41 | 42 |
import eu.etaxonomy.cdm.model.reference.Reference; |
42 | 43 |
import eu.etaxonomy.cdm.model.reference.ReferenceFactory; |
... | ... | |
45 | 46 |
import eu.etaxonomy.cdm.model.taxon.Taxon; |
46 | 47 |
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException; |
47 | 48 |
import eu.etaxonomy.cdm.strategy.parser.NameTypeParser; |
48 |
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl; |
|
49 | 49 |
import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser; |
50 | 50 |
|
51 | 51 |
/** |
... | ... | |
58 | 58 |
private static final Logger logger = Logger.getLogger(MarkupNomenclatureImport.class); |
59 | 59 |
|
60 | 60 |
|
61 |
private NonViralNameParserImpl parser = new NonViralNameParserImpl(); |
|
61 |
// private NonViralNameParserImpl parser = new NonViralNameParserImpl();
|
|
62 | 62 |
|
63 |
private MarkupKeyImport keyImport; |
|
64 | 63 |
private MarkupSpecimenImport specimenImport; |
65 | 64 |
|
66 |
public MarkupNomenclatureImport(MarkupDocumentImport docImport, |
|
67 |
MarkupKeyImport keyImport, MarkupSpecimenImport specimenImport) { |
|
65 |
public MarkupNomenclatureImport(MarkupDocumentImport docImport, MarkupSpecimenImport specimenImport) { |
|
68 | 66 |
super(docImport); |
69 |
this.keyImport = keyImport; |
|
70 | 67 |
this.specimenImport = specimenImport; |
71 | 68 |
} |
72 | 69 |
|
... | ... | |
98 | 95 |
boolean hasNom = false; |
99 | 96 |
while (reader.hasNext()) { |
100 | 97 |
XMLEvent next = readNoWhitespace(reader); |
101 |
if (next.isEndElement()) { |
|
102 |
if (isMyEndingElement(next, parentEvent)) { |
|
103 |
checkMandatoryElement(hasNom, parentEvent, NOM); |
|
104 |
return; |
|
105 |
} else { |
|
106 |
if (isEndingElement(next, NAME_TYPE)) { |
|
107 |
state.setNameType(false); |
|
108 |
} else if (isEndingElement(next, NOTES)) { |
|
109 |
// NOT YET IMPLEMENTED |
|
110 |
popUnimplemented(next.asEndElement()); |
|
111 |
} else { |
|
112 |
handleUnexpectedEndElement(next.asEndElement()); |
|
113 |
} |
|
114 |
} |
|
115 |
} else if (next.isStartElement()) { |
|
116 |
if (isStartingElement(next, NOM)) { |
|
117 |
NonViralName<?> name = handleNom(state, reader, next, homotypicalGroup); |
|
118 |
homotypicalGroup = name.getHomotypicalGroup(); |
|
119 |
hasNom = true; |
|
120 |
} else if (isStartingElement(next, NAME_TYPE)) { |
|
121 |
state.setNameType(true); |
|
122 |
handleNameType(state, reader, next, homotypicalGroup); |
|
123 |
} else if (isStartingElement(next, SPECIMEN_TYPE)) { |
|
124 |
specimenImport.handleSpecimenType(state, reader, next, |
|
125 |
homotypicalGroup); |
|
126 |
} else if (isStartingElement(next, NOTES)) { |
|
127 |
handleNotYetImplementedElement(next); |
|
128 |
} else { |
|
129 |
handleUnexpectedStartElement(next); |
|
130 |
} |
|
98 |
if (isMyEndingElement(next, parentEvent)) { |
|
99 |
checkMandatoryElement(hasNom, parentEvent, NOM); |
|
100 |
state.setLatestAuthorInHomotype(null); |
|
101 |
return; |
|
102 |
} else if (isEndingElement(next, NAME_TYPE)) { |
|
103 |
state.setNameType(false); |
|
104 |
} else if (isStartingElement(next, NOM)) { |
|
105 |
NonViralName<?> name = handleNom(state, reader, next, homotypicalGroup); |
|
106 |
homotypicalGroup = name.getHomotypicalGroup(); |
|
107 |
hasNom = true; |
|
108 |
} else if (isStartingElement(next, NAME_TYPE)) { |
|
109 |
state.setNameType(true); |
|
110 |
handleNameType(state, reader, next, homotypicalGroup); |
|
111 |
} else if (isStartingElement(next, SPECIMEN_TYPE)) { |
|
112 |
specimenImport.handleSpecimenType(state, reader, next, homotypicalGroup); |
|
113 |
} else if (isStartingElement(next, NOTES)) { |
|
114 |
handleNotYetImplementedElement(next); |
|
131 | 115 |
} else { |
132 | 116 |
handleUnexpectedElement(next); |
133 | 117 |
} |
134 | 118 |
} |
119 |
state.setLatestAuthorInHomotype(null); |
|
135 | 120 |
// TODO handle missing end element |
136 | 121 |
throw new IllegalStateException("Homotypes has no closing tag"); |
137 | 122 |
|
... | ... | |
208 | 193 |
* @return |
209 | 194 |
* @throws XMLStreamException |
210 | 195 |
*/ |
211 |
private NonViralName<?> handleNom(MarkupImportState state, |
|
212 |
XMLEventReader reader, XMLEvent parentEvent, |
|
213 |
HomotypicalGroup homotypicalGroup) throws XMLStreamException { |
|
196 |
private NonViralName<?> handleNom(MarkupImportState state, XMLEventReader reader, |
|
197 |
XMLEvent parentEvent, HomotypicalGroup homotypicalGroup) throws XMLStreamException { |
|
214 | 198 |
boolean isSynonym = false; |
215 | 199 |
boolean isNameType = state.isNameType(); |
216 | 200 |
// attributes |
... | ... | |
233 | 217 |
Map<String, String> nameMap = new HashMap<String, String>(); |
234 | 218 |
String text = ""; |
235 | 219 |
|
220 |
boolean nameFilled = false; |
|
236 | 221 |
while (reader.hasNext()) { |
237 | 222 |
XMLEvent next = readNoWhitespace(reader); |
238 | 223 |
if (isMyEndingElement(next, parentEvent)) { |
239 |
// fill the name with all data gathered |
|
240 |
fillName(state, nameMap, name, next); |
|
224 |
// fill the name with all data gathered, if not yet done before |
|
225 |
if (nameFilled == false){ |
|
226 |
fillName(state, nameMap, name, next); |
|
227 |
} |
|
241 | 228 |
handleNomText(state, parentEvent, text, isNameType); |
242 | 229 |
return name; |
243 | 230 |
} else if (isEndingElement(next, ANNOTATION)) { |
... | ... | |
251 | 238 |
} else if (isStartingElement(next, NAME)) { |
252 | 239 |
handleName(state, reader, next, nameMap); |
253 | 240 |
} else if (isStartingElement(next, CITATION)) { |
254 |
handleCitation(state, reader, next, name); |
|
241 |
//we need to fill the name here to have nomenclatural author available for the following citations |
|
242 |
fillName(state, nameMap, name, next); |
|
243 |
nameFilled = true; |
|
244 |
handleCitation(state, reader, next, name, nameMap); |
|
255 | 245 |
} else if (next.isCharacters()) { |
256 | 246 |
text += next.asCharacters().getData(); |
257 | 247 |
} else if (isStartingElement(next, HOMONYM)) { |
... | ... | |
358 | 348 |
nameMap.put(classValue, text); |
359 | 349 |
return; |
360 | 350 |
} else if (isStartingElement(next, ANNOTATION)) { |
361 |
handleNotYetImplementedElement(next); // TODO test |
|
362 |
// handleSimpleAnnotation |
|
351 |
handleNotYetImplementedElement(next); // TODO test handleSimpleAnnotation |
|
363 | 352 |
} else if (next.isCharacters()) { |
364 | 353 |
text += next.asCharacters().getData(); |
365 | 354 |
} else { |
... | ... | |
391 | 380 |
makeRankDecision(state, nameMap, name, event, infrank); |
392 | 381 |
|
393 | 382 |
// test consistency of rank and authors |
394 |
testRankAuthorConsistency(name, event, authorStr, paraut, |
|
395 |
infrParAut, infrAut); |
|
383 |
testRankAuthorConsistency(name, event, authorStr, paraut,infrParAut, infrAut); |
|
396 | 384 |
|
397 | 385 |
// authors |
398 |
makeNomenclaturalAuthors(name, event, authorStr, paraut, |
|
399 |
infrParAut, infrAut); |
|
386 |
makeNomenclaturalAuthors(state, event, name, authorStr, paraut, infrParAut, infrAut); |
|
400 | 387 |
} |
401 | 388 |
|
402 | 389 |
// status |
... | ... | |
409 | 396 |
try { |
410 | 397 |
// TODO handle trim earlier |
411 | 398 |
statusStr = statusStr.trim(); |
412 |
NomenclaturalStatusType nomStatusType = NomenclaturalStatusType |
|
413 |
.getNomenclaturalStatusTypeByAbbreviation(statusStr); |
|
399 |
NomenclaturalStatusType nomStatusType = NomenclaturalStatusType.getNomenclaturalStatusTypeByAbbreviation(statusStr); |
|
414 | 400 |
name.addStatus(NomenclaturalStatus.NewInstance(nomStatusType)); |
415 | 401 |
} catch (UnknownCdmTypeException e) { |
416 | 402 |
String message = "Status '%s' could not be recognized"; |
... | ... | |
508 | 494 |
} |
509 | 495 |
|
510 | 496 |
/** |
497 |
* @param state |
|
511 | 498 |
* @param name |
512 | 499 |
* @param event |
513 | 500 |
* @param authorStr |
... | ... | |
515 | 502 |
* @param infrParAut |
516 | 503 |
* @param infrAut |
517 | 504 |
*/ |
518 |
private void makeNomenclaturalAuthors(NonViralName name, XMLEvent event,
|
|
505 |
private void makeNomenclaturalAuthors(MarkupImportState state, XMLEvent event, NonViralName<?> name,
|
|
519 | 506 |
String authorStr, String paraut, String infrParAut, String infrAut) { |
520 | 507 |
if (name.getRank() != null && name.getRank().isInfraSpecific()) { |
521 | 508 |
if (StringUtils.isNotBlank(infrAut)) { |
... | ... | |
524 | 511 |
name.setExCombinationAuthorTeam(authorAndEx[1]); |
525 | 512 |
} |
526 | 513 |
if (StringUtils.isNotBlank(infrParAut)) { |
527 |
INomenclaturalAuthor[] authorAndEx = authorAndEx(infrParAut, |
|
528 |
event); |
|
514 |
INomenclaturalAuthor[] authorAndEx = authorAndEx(infrParAut,event); |
|
529 | 515 |
name.setBasionymAuthorTeam(authorAndEx[0]); |
530 | 516 |
name.setExBasionymAuthorTeam(authorAndEx[1]); |
531 | 517 |
} |
... | ... | |
539 | 525 |
} |
540 | 526 |
} |
541 | 527 |
if (StringUtils.isNotBlank(authorStr)) { |
542 |
INomenclaturalAuthor[] authorAndEx = authorAndEx(authorStr, |
|
543 |
event); |
|
528 |
INomenclaturalAuthor[] authorAndEx = authorAndEx(authorStr, event); |
|
544 | 529 |
name.setCombinationAuthorTeam(authorAndEx[0]); |
545 | 530 |
name.setExCombinationAuthorTeam(authorAndEx[1]); |
546 | 531 |
} |
... | ... | |
550 | 535 |
name.setExBasionymAuthorTeam(authorAndEx[1]); |
551 | 536 |
} |
552 | 537 |
} |
538 |
|
|
539 |
//remember author for following citations |
|
540 |
state.setLatestAuthorInHomotype((TeamOrPersonBase<?>)name.getCombinationAuthorTeam()); |
|
553 | 541 |
} |
554 | 542 |
|
555 |
private TeamOrPersonBase[] authorAndEx(String authorAndEx, XMLEvent xmlEvent) { |
|
543 |
private TeamOrPersonBase<?>[] authorAndEx(String authorAndEx, XMLEvent xmlEvent) {
|
|
556 | 544 |
authorAndEx = authorAndEx.trim(); |
557 |
TeamOrPersonBase[] result = new TeamOrPersonBase[2]; |
|
545 |
TeamOrPersonBase<?>[] result = new TeamOrPersonBase[2];
|
|
558 | 546 |
|
559 | 547 |
String[] split = authorAndEx.split("\\sex\\s"); |
560 | 548 |
if (split.length > 2) { |
... | ... | |
589 | 577 |
if (homotypicalGroup != null) { |
590 | 578 |
name.setHomotypicalGroup(homotypicalGroup); |
591 | 579 |
} |
592 |
SynonymRelationshipType synonymType = SynonymRelationshipType |
|
593 |
.HETEROTYPIC_SYNONYM_OF(); |
|
580 |
SynonymRelationshipType synonymType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(); |
|
594 | 581 |
if (taxon.getHomotypicGroup().equals(homotypicalGroup)) { |
595 | 582 |
synonymType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF(); |
596 | 583 |
} |
... | ... | |
602 | 589 |
} |
603 | 590 |
|
604 | 591 |
private void handleCitation(MarkupImportState state, XMLEventReader reader, |
605 |
XMLEvent parentEvent, NonViralName name) throws XMLStreamException {
|
|
592 |
XMLEvent parentEvent, NonViralName<?> name, Map<String, String> nameMap) throws XMLStreamException {
|
|
606 | 593 |
String classValue = getClassOnlyAttribute(parentEvent); |
607 | 594 |
|
608 | 595 |
state.setCitation(true); |
... | ... | |
611 | 598 |
while (reader.hasNext()) { |
612 | 599 |
XMLEvent next = readNoWhitespace(reader); |
613 | 600 |
if (isMyEndingElement(next, parentEvent)) { |
614 |
checkMandatoryElement(hasRefPart, parentEvent.asStartElement(), |
|
615 |
REF_PART); |
|
601 |
checkMandatoryElement(hasRefPart, parentEvent.asStartElement(), REF_PART); |
|
616 | 602 |
Reference<?> reference = createReference(state, refMap, next); |
617 | 603 |
String microReference = refMap.get(DETAILS); |
618 |
doCitation(state, name, classValue, reference, microReference, |
|
619 |
parentEvent); |
|
604 |
doCitation(state, name, classValue, reference, microReference, parentEvent); |
|
620 | 605 |
state.setCitation(false); |
621 | 606 |
return; |
622 | 607 |
} else if (isStartingElement(next, REF_PART)) { |
... | ... | |
662 | 647 |
|
663 | 648 |
} |
664 | 649 |
|
665 |
private void doCitation(MarkupImportState state, NonViralName name, |
|
666 |
String classValue, Reference reference, String microCitation, |
|
650 |
private void doCitation(MarkupImportState state, NonViralName<?> name,
|
|
651 |
String classValue, Reference<?> reference, String microCitation,
|
|
667 | 652 |
XMLEvent parentEvent) { |
668 | 653 |
if (PUBLICATION.equalsIgnoreCase(classValue)) { |
669 | 654 |
name.setNomenclaturalReference(reference); |
670 | 655 |
name.setNomenclaturalMicroReference(microCitation); |
671 | 656 |
} else if (USAGE.equalsIgnoreCase(classValue)) { |
672 | 657 |
Taxon taxon = state.getCurrentTaxon(); |
673 |
TaxonDescription td = getTaxonDescription(taxon, state.getConfig() |
|
674 |
.getSourceReference(), false, true); |
|
658 |
TaxonDescription td = getTaxonDescription(taxon, state.getConfig().getSourceReference(), false, true); |
|
675 | 659 |
TextData citation = TextData.NewInstance(Feature.CITATION()); |
676 | 660 |
// TODO name used in source |
677 | 661 |
citation.addSource(OriginalSourceType.PrimaryTaxonomicSource, null, null, reference, microCitation); |
678 | 662 |
td.addElement(citation); |
679 | 663 |
} else if (TYPE.equalsIgnoreCase(classValue)) { |
680 |
handleNotYetImplementedAttributeValue(parentEvent, CLASS, |
|
681 |
classValue); |
|
664 |
handleNotYetImplementedAttributeValue(parentEvent, CLASS, classValue); |
|
682 | 665 |
} else { |
683 | 666 |
// TODO Not yet implemented |
684 |
handleNotYetImplementedAttributeValue(parentEvent, CLASS, |
|
685 |
classValue); |
|
667 |
handleNotYetImplementedAttributeValue(parentEvent, CLASS, classValue); |
|
686 | 668 |
} |
687 | 669 |
} |
688 | 670 |
|
... | ... | |
697 | 679 |
* @param infrParAut |
698 | 680 |
* @param infrAut |
699 | 681 |
*/ |
700 |
private void testRankAuthorConsistency(NonViralName name, XMLEvent event, |
|
682 |
private void testRankAuthorConsistency(NonViralName<?> name, XMLEvent event,
|
|
701 | 683 |
String authorStr, String paraut, String infrParAut, String infrAut) { |
702 | 684 |
if (name.getRank() == null) { |
703 | 685 |
return; |
... | ... | |
738 | 720 |
String pages = getAndRemoveMapKey(refMap, PAGES); |
739 | 721 |
|
740 | 722 |
if (state.isCitation()) { |
741 |
if (volume != null || "journal".equalsIgnoreCase(type)) { |
|
742 |
IArticle article = ReferenceFactory.newArticle(); |
|
743 |
if (pubName != null) { |
|
744 |
IJournal journal = ReferenceFactory.newJournal(); |
|
745 |
journal.setTitle(pubName); |
|
746 |
article.setInJournal(journal); |
|
747 |
} |
|
748 |
reference = (Reference<?>) article; |
|
723 |
reference = handleCitationSpecific(state, type, authorStr, |
|
724 |
titleStr, titleCache, volume, edition, editors, pubName, pages, refMap, parentEvent); |
|
749 | 725 |
|
750 |
} else { |
|
751 |
// TODO |
|
752 |
if (pubName != null) { |
|
753 |
reference = ReferenceFactory.newBookSection(); |
|
754 |
} else { |
|
755 |
reference = ReferenceFactory.newBook(); |
|
756 |
} |
|
726 |
} else { // no citation |
|
727 |
reference = handleNonCitationSpecific(type, authorStr, titleStr, |
|
728 |
titleCache, volume, edition, editors, pubName); |
|
729 |
} |
|
730 |
|
|
731 |
//year |
|
732 |
TimePeriod timeperiod = TimePeriodParser.parseString(year); |
|
733 |
if (reference.getType().equals(ReferenceType.BookSection)){ |
|
734 |
reference.getInBook().setDatePublished(timeperiod); |
|
735 |
} |
|
736 |
reference.setDatePublished(timeperiod); |
|
737 |
|
|
738 |
// TODO |
|
739 |
String[] unhandledList = new String[] { ALTERNATEPUBTITLE, ISSUE, NOTES, STATUS }; |
|
740 |
for (String unhandled : unhandledList) { |
|
741 |
String value = getAndRemoveMapKey(refMap, unhandled); |
|
742 |
if (isNotBlank(value)) { |
|
743 |
this.handleNotYetImplementedAttributeValue(parentEvent, CLASS, unhandled); |
|
757 | 744 |
} |
758 |
// TODO use existing author from name or before |
|
759 |
TeamOrPersonBase<?> author = createAuthor(authorStr); |
|
760 |
reference.setAuthorTeam(author); |
|
745 |
} |
|
761 | 746 |
|
762 |
reference.setTitle(titleStr);
|
|
763 |
if (StringUtils.isNotBlank(titleCache)) {
|
|
764 |
reference.setTitleCache(titleCache, true);
|
|
747 |
for (String key : refMap.keySet()) {
|
|
748 |
if (!DETAILS.equalsIgnoreCase(key)) {
|
|
749 |
this.fireUnexpectedAttributeValue(parentEvent, CLASS, key);
|
|
765 | 750 |
} |
766 |
reference.setEdition(edition); |
|
767 |
reference.setEditor(editors); |
|
751 |
} |
|
752 |
|
|
753 |
return reference; |
|
754 |
} |
|
755 |
|
|
756 |
|
|
757 |
/** |
|
758 |
* Handles references used in the citation tag |
|
759 |
* @see #handleNonCitationSpecific(String, String, String, String, String, String, String, String) |
|
760 |
*/ |
|
761 |
private Reference<?> handleCitationSpecific(MarkupImportState state, |
|
762 |
String type, String authorStr, String titleStr, String titleCache, |
|
763 |
String volume, String edition, String editors, String pubName, String pages, Map<String, String> refMap, XMLEvent parentEvent) { |
|
764 |
|
|
765 |
if (titleStr != null){ |
|
766 |
String message = "Currently it is not expected that a titleStr exists in a citation"; |
|
767 |
fireWarningEvent(message, parentEvent, 4); |
|
768 |
} |
|
768 | 769 |
|
770 |
RefType refType = defineRefTypeForCitation(type, volume, editors, authorStr, pubName, parentEvent); |
|
771 |
Reference<?> reference; |
|
772 |
if (refType == RefType.Article) { |
|
773 |
IArticle article = ReferenceFactory.newArticle(); |
|
769 | 774 |
if (pubName != null) { |
770 |
Reference<?> inReference; |
|
771 |
if (reference.getType().equals(ReferenceType.Article)) { |
|
772 |
inReference = ReferenceFactory.newJournal(); |
|
773 |
} else { |
|
774 |
inReference = ReferenceFactory.newGeneric(); |
|
775 |
IJournal journal = ReferenceFactory.newJournal(); |
|
776 |
journal.setTitle(pubName); |
|
777 |
article.setInJournal(journal); |
|
778 |
article.setVolume(volume); |
|
779 |
if (isNotBlank(edition)){ |
|
780 |
String message = "Article must not have an edition."; |
|
781 |
fireWarningEvent(message, parentEvent, 4); |
|
775 | 782 |
} |
776 |
inReference.setTitle(pubName); |
|
777 |
reference.setInReference(inReference); |
|
778 | 783 |
} |
779 |
|
|
780 |
} else { // no citation |
|
781 |
if (volume != null || "journal".equalsIgnoreCase(type)) { |
|
782 |
IArticle article = ReferenceFactory.newArticle(); |
|
783 |
if (pubName != null) { |
|
784 |
IJournal journal = ReferenceFactory.newJournal(); |
|
785 |
journal.setTitle(pubName); |
|
786 |
article.setInJournal(journal); |
|
784 |
reference = (Reference<?>) article; |
|
785 |
} else if (refType == RefType.BookSection) { |
|
786 |
//Book Section |
|
787 |
reference = ReferenceFactory.newBookSection(); |
|
788 |
IBook book = ReferenceFactory.newBook(); |
|
789 |
reference.setInBook(book); |
|
790 |
book.setTitle(pubName); |
|
791 |
book.setVolume(volume); |
|
792 |
book.setEdition(edition); |
|
793 |
|
|
794 |
if (state.getConfig().isUseEditorAsInAuthorWhereNeeded()){ |
|
795 |
TeamOrPersonBase<?> inAuthor = createAuthor(editors); |
|
796 |
book.setAuthorTeam(inAuthor); |
|
797 |
editors = null; |
|
798 |
} |
|
799 |
} else if (refType == RefType.Book){ |
|
800 |
//Book |
|
801 |
reference = ReferenceFactory.newBook(); |
|
802 |
reference.setTitle(pubName); |
|
803 |
reference.setVolume(volume); |
|
804 |
reference.setEdition(edition); |
|
805 |
}else if (refType == RefType.Generic){ |
|
806 |
//Generic - undefinable |
|
807 |
// String message = "Can't define the type of the reference. Use generic instead"; |
|
808 |
// fireWarningEvent(message, parentEvent, 4); |
|
809 |
reference = ReferenceFactory.newGeneric(); |
|
810 |
reference.setTitle(pubName); |
|
811 |
reference.setEdition(edition); |
|
812 |
|
|
813 |
//volume indicates an in-reference |
|
814 |
if (isNotBlank(volume)){ |
|
815 |
Reference<?> partOf = ReferenceFactory.newGeneric(); |
|
816 |
partOf.setVolume(volume); |
|
817 |
partOf.setInReference(reference); |
|
818 |
reference = partOf; |
|
819 |
} |
|
820 |
}else if (refType == RefType.LatestUsed){ |
|
821 |
Reference<?> latestReference = state.getLatestReferenceInHomotype(); |
|
822 |
if (latestReference == null){ |
|
823 |
String message = "No former reference available for incomplete citation"; |
|
824 |
fireWarningEvent(message, parentEvent, 6); |
|
825 |
reference = ReferenceFactory.newGeneric(); |
|
826 |
}else{ |
|
827 |
if (latestReference.getInReference() != null){ |
|
828 |
reference = (Reference<?>)latestReference.clone(); |
|
829 |
}else{ |
|
830 |
String message = "Latest reference is not an in-reference. This is not yet handled."; |
|
831 |
fireWarningEvent(message, parentEvent, 6); |
|
832 |
reference = ReferenceFactory.newGeneric(); |
|
787 | 833 |
} |
788 |
reference = (Reference<?>) article; |
|
789 |
|
|
790 |
} else { |
|
791 |
Reference<?> bookOrPartOf = ReferenceFactory.newGeneric(); |
|
792 |
reference = bookOrPartOf; |
|
793 | 834 |
} |
794 |
|
|
795 |
// TODO type |
|
796 |
TeamOrPersonBase<?> author = createAuthor(authorStr); |
|
835 |
reference.setVolume(volume); |
|
836 |
if (isNotBlank(edition)){ |
|
837 |
String message = "Edition not yet handled for incomplete citations"; |
|
838 |
fireWarningEvent(message, parentEvent, 4); |
|
839 |
} |
|
840 |
|
|
841 |
}else{ |
|
842 |
String message = "Unhandled reference type: %s" ; |
|
843 |
fireWarningEvent(String.format(message, refType.toString()), parentEvent, 8); |
|
844 |
reference = ReferenceFactory.newGeneric(); |
|
845 |
} |
|
846 |
|
|
847 |
//author |
|
848 |
TeamOrPersonBase<?> author; |
|
849 |
if (isBlank(authorStr)){ |
|
850 |
if (refType != RefType.LatestUsed){ |
|
851 |
author = state.getLatestAuthorInHomotype(); |
|
852 |
reference.setAuthorTeam(author); |
|
853 |
} |
|
854 |
}else{ |
|
855 |
author = createAuthor(authorStr); |
|
856 |
state.setLatestAuthorInHomotype(author); |
|
797 | 857 |
reference.setAuthorTeam(author); |
858 |
} |
|
859 |
|
|
860 |
|
|
861 |
//title, titleCache |
|
862 |
handleTitlesInCitation(titleStr, titleCache, parentEvent, reference); |
|
863 |
|
|
864 |
//editors |
|
865 |
handleEditorsInCitation(edition, editors, reference, parentEvent); |
|
866 |
|
|
867 |
//pages |
|
868 |
handlePages(state, refMap, parentEvent, reference, pages); |
|
869 |
|
|
870 |
//remember reference for following citation |
|
871 |
state.setLatestReferenceInHomotype(reference); |
|
872 |
|
|
873 |
return reference; |
|
874 |
} |
|
875 |
|
|
876 |
private void handleEditorsInCitation(String edition, String editors, Reference<?> reference, XMLEvent parentEvent) { |
|
877 |
//editor |
|
878 |
reference.setEditor(editors); |
|
879 |
if ( editors != null){ |
|
880 |
String message = "Citation reference has an editor. This is unusual for a citation reference (appears regularly in <reference> references"; |
|
881 |
fireWarningEvent(message, parentEvent, 4); |
|
882 |
} |
|
883 |
} |
|
798 | 884 |
|
885 |
private void handleTitlesInCitation(String titleStr, String titleCache, |
|
886 |
XMLEvent parentEvent, Reference<?> reference) { |
|
887 |
if (isNotBlank(titleStr)){ |
|
799 | 888 |
reference.setTitle(titleStr); |
800 |
if (StringUtils.isNotBlank(titleCache)) { |
|
801 |
reference.setTitleCache(titleCache, true); |
|
802 |
} |
|
803 |
reference.setEdition(edition); |
|
804 |
reference.setEditor(editors); |
|
889 |
} |
|
890 |
//titleCache |
|
891 |
if (StringUtils.isNotBlank(titleCache)) { |
|
892 |
reference.setTitleCache(titleCache, true); |
|
893 |
} |
|
894 |
if (titleStr != null || titleCache != null){ |
|
895 |
String message = "Citation reference has a title or a full title. Both is unusual for a citation reference (appears regularly in <reference> references"; |
|
896 |
fireWarningEvent(message, parentEvent, 4); |
|
897 |
} |
|
898 |
} |
|
805 | 899 |
|
806 |
if (pubName != null) { |
|
807 |
Reference<?> inReference; |
|
808 |
if (reference.getType().equals(ReferenceType.Article)) { |
|
809 |
inReference = ReferenceFactory.newJournal(); |
|
810 |
} else { |
|
811 |
inReference = ReferenceFactory.newGeneric(); |
|
900 |
private enum RefType{ |
|
901 |
Article, |
|
902 |
BookSection, |
|
903 |
Book, |
|
904 |
Generic, |
|
905 |
LatestUsed |
|
906 |
} |
|
907 |
|
|
908 |
private RefType defineRefTypeForCitation(String type, String volume, String editors, |
|
909 |
String authorStr, String pubName, XMLEvent parentEvent) { |
|
910 |
if ("journal".equalsIgnoreCase(type)){ |
|
911 |
return RefType.Article; |
|
912 |
}else { |
|
913 |
if (editors == null){ |
|
914 |
//no editors |
|
915 |
if (pubName == null){ |
|
916 |
//looks like we need to use reference info from former citations here |
|
917 |
return RefType.LatestUsed; |
|
918 |
}else if (volume == null){ |
|
919 |
return RefType.Book; //Book must not have in-authors |
|
920 |
}else{ |
|
921 |
return RefType.Generic; |
|
922 |
} |
|
923 |
|
|
924 |
}else{ |
|
925 |
//editors |
|
926 |
if (pubName != null){ |
|
927 |
return RefType.BookSection; |
|
928 |
}else{ |
|
929 |
String message = "Unexpected state: Citation has editors but no pubName"; |
|
930 |
fireWarningEvent(message, parentEvent, 4); |
|
931 |
return RefType.Generic; |
|
812 | 932 |
} |
813 |
inReference.setTitle(pubName); |
|
814 |
reference.setInReference(inReference); |
|
815 | 933 |
} |
816 | 934 |
} |
817 |
reference.setVolume(volume); |
|
818 |
reference.setDatePublished(TimePeriodParser.parseString(year)); |
|
819 |
// TODO check if this is handled correctly in FM markup |
|
820 |
reference.setPages(pages); |
|
935 |
} |
|
821 | 936 |
|
822 |
// TODO |
|
823 |
String[] unhandledList = new String[] { ALTERNATEPUBTITLE, ISSUE, |
|
824 |
NOTES, STATUS }; |
|
825 |
for (String unhandled : unhandledList) { |
|
826 |
String value = getAndRemoveMapKey(refMap, unhandled); |
|
827 |
if (isNotBlank(value)) { |
|
828 |
this.handleNotYetImplementedAttributeValue(parentEvent, CLASS, |
|
829 |
unhandled); |
|
830 |
} |
|
937 |
|
|
938 |
private boolean isArticle(String type, String volume, String editors) { |
|
939 |
if ("journal".equalsIgnoreCase(type)){ |
|
940 |
return true; |
|
941 |
}else if (volume != null && editors == null){ |
|
942 |
return true; |
|
943 |
}else{ |
|
944 |
return false; |
|
831 | 945 |
} |
946 |
} |
|
832 | 947 |
|
833 |
for (String key : refMap.keySet()) { |
|
834 |
if (!DETAILS.equalsIgnoreCase(key)) { |
|
835 |
this.fireUnexpectedAttributeValue(parentEvent, CLASS, key); |
|
948 |
/** |
|
949 |
* in work |
|
950 |
* @return |
|
951 |
*/ |
|
952 |
private Reference<?> handleNonCitationSpecific(String type, String authorStr, |
|
953 |
String titleStr, String titleCache, String volume, String edition, |
|
954 |
String editors, String pubName) { |
|
955 |
Reference<?> reference; |
|
956 |
if (isArticle(type, volume, editors)) { |
|
957 |
IArticle article = ReferenceFactory.newArticle(); |
|
958 |
if (pubName != null) { |
|
959 |
IJournal journal = ReferenceFactory.newJournal(); |
|
960 |
journal.setTitle(pubName); |
|
961 |
article.setInJournal(journal); |
|
836 | 962 |
} |
963 |
reference = (Reference<?>) article; |
|
964 |
|
|
965 |
} else { |
|
966 |
Reference<?> bookOrPartOf = ReferenceFactory.newGeneric(); |
|
967 |
reference = bookOrPartOf; |
|
837 | 968 |
} |
838 | 969 |
|
970 |
// TODO type |
|
971 |
TeamOrPersonBase<?> author = createAuthor(authorStr); |
|
972 |
reference.setAuthorTeam(author); |
|
973 |
|
|
974 |
//title |
|
975 |
reference.setTitle(titleStr); |
|
976 |
if (StringUtils.isNotBlank(titleCache)) { |
|
977 |
reference.setTitleCache(titleCache, true); |
|
978 |
} |
|
979 |
|
|
980 |
//edition |
|
981 |
reference.setEdition(edition); |
|
982 |
reference.setEditor(editors); |
|
983 |
|
|
984 |
//pubName |
|
985 |
if (pubName != null) { |
|
986 |
Reference<?> inReference; |
|
987 |
if (reference.getType().equals(ReferenceType.Article)) { |
|
988 |
inReference = ReferenceFactory.newJournal(); |
|
989 |
} else { |
|
990 |
inReference = ReferenceFactory.newGeneric(); |
|
991 |
} |
|
992 |
inReference.setTitle(pubName); |
|
993 |
reference.setInReference(inReference); |
|
994 |
} |
|
995 |
|
|
996 |
//volume |
|
997 |
reference.setVolume(volume); |
|
839 | 998 |
return reference; |
840 | 999 |
} |
841 | 1000 |
|
1001 |
private void handlePages(MarkupImportState state, |
|
1002 |
Map<String, String> refMap, XMLEvent parentEvent, |
|
1003 |
Reference<?> reference, String pages) { |
|
1004 |
// TODO check if this is handled correctly in FM markup |
|
1005 |
boolean switchPages = state.getConfig().isHandlePagesAsDetailWhereNeeded(); |
|
1006 |
if (switchPages){ |
|
1007 |
if (pages != null ){ |
|
1008 |
String detail = refMap.get(DETAILS); |
|
1009 |
if (isBlank(detail)){ |
|
1010 |
if (pages.contains("-")){ |
|
1011 |
String message = "There is a pages tag with '-'. Unclear if this really means pages"; |
|
1012 |
fireWarningEvent(message, parentEvent, 8); |
|
1013 |
reference.setPages(pages); |
|
1014 |
}else{ |
|
1015 |
//handle pages as detail, this is at least true for Flora Malesiana |
|
1016 |
refMap.put(DETAILS, pages); |
|
1017 |
} |
|
1018 |
} |
|
1019 |
} |
|
1020 |
} |
|
1021 |
} |
|
1022 |
|
|
842 | 1023 |
public Reference<?> handleReference(MarkupImportState state, |
843 | 1024 |
XMLEventReader reader, XMLEvent parentEvent) |
844 | 1025 |
throws XMLStreamException { |
... | ... | |
849 | 1030 |
while (reader.hasNext()) { |
850 | 1031 |
XMLEvent next = readNoWhitespace(reader); |
851 | 1032 |
if (isMyEndingElement(next, parentEvent)) { |
852 |
checkMandatoryElement(hasRefPart, parentEvent.asStartElement(), |
|
853 |
REF_PART); |
|
1033 |
checkMandatoryElement(hasRefPart, parentEvent.asStartElement(), REF_PART); |
|
854 | 1034 |
Reference<?> reference = createReference(state, refMap, next); |
855 | 1035 |
return reference; |
856 | 1036 |
} else if (isStartingElement(next, REF_PART)) { |
Also available in: Unified diff
merge trunk into cdm3.3 branch