Project

General

Profile

« Previous | Next » 

Revision 43b37ce4

Added by Andreas Müller over 12 years ago

latest markup development

View differences:

cdmlib-io/src/main/java/eu/etaxonomy/cdm/io/markup/MarkupDocumentImport.java
334 334
			// "Start", 16);
335 335

  
336 336
		}
337

  
337
		
338 338
		return;
339 339

  
340 340
	}
......
421 421

  
422 422
	}
423 423

  
424
	private void handleTreatment(MarkupImportState state,
425
			XMLEventReader reader, XMLEvent parentEvent)
426
			throws XMLStreamException {
424
	private void handleTreatment(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent) throws XMLStreamException {
427 425
		checkNoAttributes(parentEvent);
428 426
		Taxon lastTaxon = null;
429 427
		while (reader.hasNext()) {
430 428
			XMLEvent next = readNoWhitespace(reader);
431 429
			if (isStartingElement(next, TAXON)) {
432
				Taxon thisTaxon = handleTaxon(state, reader,
433
						next.asStartElement());
434
				doTaxonRelation(state, thisTaxon, lastTaxon,
435
						parentEvent.getLocation());
430
				Taxon thisTaxon = handleTaxon(state, reader, next.asStartElement());
431
				doTaxonRelation(state, thisTaxon, lastTaxon, parentEvent.getLocation());
436 432
				lastTaxon = thisTaxon;
437 433
				// TODO for imports spanning multiple documents ?? Still needed?
438 434
				state.getConfig().setLastTaxonUuid(lastTaxon.getUuid());
439 435
			} else if (isMyEndingElement(next, parentEvent)) {
436
				Set<PolytomousKeyNode> keyNodesToSave = state.getPolytomousKeyNodesToSave();
437
				//better save the key then the nodes
438
				Set<PolytomousKey> keySet = new HashSet<PolytomousKey>();
439
				for (PolytomousKeyNode node : keyNodesToSave){
440
					PolytomousKey key = node.getKey();
441
					keySet.add(key);
442
				}
443
				save(keySet, state);
444
//				save(keyNodesToSave, state);
445

  
440 446
				return;
441 447
			} else {
442
				fireSchemaConflictEventExpectedStartTag(TAXON, reader);
443
				state.setUnsuccessfull();
448
				handleUnexpectedElement(next);
444 449
			}
445 450
		}
446 451
		return;
......
513 518

  
514 519
	private Classification createNewClassification(MarkupImportState state) {
515 520
		Classification result;
516
		result = Classification.NewInstance(state.getConfig()
517
				.getClassificationTitle());
521
		result = Classification.NewInstance(state.getConfig().getClassificationTitle());
518 522
		state.putTree(null, result);
519 523
		return result;
520 524
	}
......
534 538
			XMLEvent next = readNoWhitespace(reader);
535 539
			if (next.isEndElement()) {
536 540
				if (isMyEndingElement(next, parentEvent)) {
537

  
538 541
					checkMandatoryElement(hasTitle, parentEvent, TAXONTITLE);
539
					checkMandatoryElement(hasNomenclature, parentEvent,
540
							NOMENCLATURE);
541
					handleUnexpectedAttributes(parentEvent.getLocation(),
542
							attributes);
543

  
542
					checkMandatoryElement(hasNomenclature, parentEvent,	NOMENCLATURE);
543
					handleUnexpectedAttributes(parentEvent.getLocation(),attributes);
544
					
545
					makeKeyNodes(state, parentEvent);
544 546
					state.setCurrentTaxon(null);
547
					state.setCurrentTaxonNum(null);
545 548
					save(taxon, state);
546 549
					return taxon;
547 550
				} else {
......
614 617
				handleUnexpectedElement(next);
615 618
			}
616 619
		}
617
		// TODO handle missing end element
618
		throw new IllegalStateException("Taxon has no closing tag");
620
		throw new IllegalStateException("<Taxon> has no closing tag");
621
	}
622

  
623
	private void makeKeyNodes(MarkupImportState state, XMLEvent event) {
624
		Taxon taxon = state.getCurrentTaxon();
625
		String num = state.getCurrentTaxonNum();
626
		
627
		String nameString = CdmBase.deproxy(taxon.getName(), NonViralName.class).getNameCache();
628
		
629
		//try to find matching lead nodes 
630
		UnmatchedLeadsKey leadsKey = UnmatchedLeadsKey.NewInstance(num, nameString);
631
		Set<PolytomousKeyNode> matchingNodes = handleMatchingNodes(state, taxon, leadsKey);
632
		//same without using the num
633
		if (num != null){
634
			UnmatchedLeadsKey noNumLeadsKey = UnmatchedLeadsKey.NewInstance("", nameString);
635
			//TODO inform about differences
636
			handleMatchingNodes(state, taxon, noNumLeadsKey);
637
		}
638
		if (matchingNodes.isEmpty() && num != null){
639
			String message = "Taxon has num in taxontitle but no matching nodes exist: %s, Key: %s";
640
			message = String.format(message, num, leadsKey.toString());
641
			fireWarningEvent(message, event, 1);
642
		}
643
		
644
	}
645
	
646
	private Set<PolytomousKeyNode> handleMatchingNodes(MarkupImportState state, Taxon taxon, UnmatchedLeadsKey leadsKey) {
647
		Set<PolytomousKeyNode> matchingNodes = state.getUnmatchedLeads().getNodes(leadsKey);
648
		for (PolytomousKeyNode matchingNode : matchingNodes){
649
			state.getUnmatchedLeads().removeNode(leadsKey, matchingNode);
650
			matchingNode.setTaxon(taxon);
651
			state.getPolytomousKeyNodesToSave().add(matchingNode);
652
		}
653
		return matchingNodes;
619 654
	}
620 655

  
621 656
	private void handleKey(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent) throws XMLStreamException {
......
643 678
				popUnimplemented(next.asEndElement());
644 679
			} else if (next.isStartElement()) {
645 680
				if (isStartingElement(next, KEY_TITLE)) {
646
					String keyTitle = getCData(state, reader, next);
647
					if (isNotBlank(keyTitle)){
648
						key.setTitleCache(keyTitle, true);
649
					}
681
					handleKeyTitle(state, reader, next);
650 682
				} else if (isStartingElement(next, KEYNOTES)) {
651 683
					//TODO
652 684
					handleNotYetImplementedElement(next);
......
669 701

  
670 702
	}
671 703

  
672
	private void handleCouplet(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent, PolytomousKeyNode parentNode) throws XMLStreamException {
673
		// attributes
674
		Map<String, Attribute> attributes = getAttributes(parentEvent);
675
		//TODO
676
		String num = getAndRemoveRequiredAttributeValue(parentEvent, attributes, NUM);
704
	/**
705
	 * @param state
706
	 * @param reader
707
	 * @param key
708
	 * @param next
709
	 * @throws XMLStreamException
710
	 */
711
	private void handleKeyTitle(MarkupImportState state, XMLEventReader reader, XMLEvent next) throws XMLStreamException {
712
		PolytomousKey key = state.getCurrentKey();
713
		String keyTitle = getCData(state, reader, next);
714
		String standardTitles = "(?i)(Key\\sto\\sthe\\s(genera|species|varieties|forms))";
677 715
		
716
		if (isNotBlank(keyTitle) ){
717
			if (!state.getConfig().isReplaceStandardKeyTitles() || ! keyTitle.matches(standardTitles)){
718
				key.setTitleCache(keyTitle, true);
719
			}
720
		}
721
	}
722

  
723
	private void handleCouplet(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent, PolytomousKeyNode parentNode) throws XMLStreamException {
724
		String num = getOnlyAttribute(parentEvent, NUM, true);
725
		List<PolytomousKeyNode> childList = new ArrayList<PolytomousKeyNode>(); 
678 726
		
679 727
		while (reader.hasNext()) {
680 728
			XMLEvent next = readNoWhitespace(reader);
681 729
			if (isMyEndingElement(next, parentEvent)) {
730
				completeCouplet(state, parentEvent, parentNode, num, childList);
682 731
				return;
683 732
			} else if (isEndingElement(next, KEYNOTES)){
684 733
				popUnimplemented(next.asEndElement());
685 734
			} else if (isStartingElement(next, QUESTION)) {
686
				handleQuestion(state, reader, next, parentNode, num);
735
				handleQuestion(state, reader, next, childList);
687 736
			} else if (isStartingElement(next, KEYNOTES)) {
688 737
				//TODO
689 738
				handleNotYetImplementedElement(next);
......
694 743
		throw new IllegalStateException("<couplet> has no closing tag");
695 744
	}
696 745

  
697
	private void handleQuestion(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent, PolytomousKeyNode parentNode, String coupletNum) throws XMLStreamException {
746
	/**
747
	 * @param state
748
	 * @param parentEvent
749
	 * @param parentNode
750
	 * @param num
751
	 * @param childList
752
	 */
753
	private void completeCouplet(MarkupImportState state, XMLEvent parentEvent,
754
			PolytomousKeyNode parentNode, String num,
755
			List<PolytomousKeyNode> childList) {
756
		if (parentNode != null){
757
			for (PolytomousKeyNode childNode : childList){
758
				parentNode.addChild(childNode);
759
			}
760
		}else if (isNotBlank(num)){
761
			UnmatchedLeadsKey unmatchedKey = UnmatchedLeadsKey.NewInstance(state.getCurrentKey(), num);
762
			Set<PolytomousKeyNode> nodes = state.getUnmatchedLeads().getNodes(unmatchedKey);
763
			for(PolytomousKeyNode nodeToMatch: nodes){
764
				for (PolytomousKeyNode childNode : childList){
765
					nodeToMatch.addChild(childNode);
766
				}
767
				state.getUnmatchedLeads().removeNode(unmatchedKey, nodeToMatch);
768
			}
769
		}else{
770
			String message = "Parent num could not be matched. Please check if num (%s) is correct";
771
			message = String.format(message, num);
772
			fireWarningEvent(message, parentEvent, 6);
773
		}
774
	}
775

  
776
	private void handleQuestion(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent, List<PolytomousKeyNode> nodesList) throws XMLStreamException {
698 777
		// attributes
699 778
		Map<String, Attribute> attributes = getAttributes(parentEvent);
700 779
		//needed only for data lineage
701 780
		String questionNum = getAndRemoveRequiredAttributeValue(parentEvent, attributes, NUM);
702 781
		
703
		PolytomousKeyNode node = PolytomousKeyNode.NewInstance();
704
		if (parentNode != null){
705
			parentNode.addChild(node);
706
		}else if (isNotBlank(coupletNum)){
707
			
708
		}else{
709
			String message = "Parent num could not be determined. Please check if num (%s) is correct";
710
			message = String.format(message, coupletNum);
711
			fireWarningEvent(message, parentEvent, 6);
712
		}
782
		PolytomousKeyNode myNode = PolytomousKeyNode.NewInstance();
783
		myNode.setKey(state.getCurrentKey());  //to avoid NPE while computing num in PolytomousKeyNode in case this node is not matched correctly with a parent
784
		nodesList.add(myNode);
713 785
		
714 786
		while (reader.hasNext()) {
715 787
			XMLEvent next = readNoWhitespace(reader);
716 788
			if (isMyEndingElement(next, parentEvent)) {
717 789
				return;
718 790
			} else if (isEndingElement(next, TO_KEY)){
791
				//TODO
719 792
				popUnimplemented(next.asEndElement());
720 793
			} else if (isEndingElement(next, KEYNOTES)){
794
				//TODO
721 795
				popUnimplemented(next.asEndElement());
722 796
			
723 797
			} else if (isStartingElement(next, TEXT)) {
724 798
				String text = getCData(state, reader, next);
725 799
				KeyStatement statement = KeyStatement.NewInstance(text);
726
				node.setStatement(statement);
800
				myNode.setStatement(statement);
727 801
			} else if (isStartingElement(next, COUPLET)) {
728 802
				//TODO test
729
				handleCouplet(state, reader, next, node);
803
				handleCouplet(state, reader, next, myNode);
730 804
			} else if (isStartingElement(next, TO_COUPLET)) {
731
				handleToCouplet(state, reader, next, node);
805
				handleToCouplet(state, reader, next, myNode);
732 806
			} else if (isStartingElement(next, TO_TAXON)) {
733
				handleToTaxon(state, reader, next, node);
807
				handleToTaxon(state, reader, next, myNode);
734 808
			} else if (isStartingElement(next, TO_KEY)) {
735 809
				//TODO
736 810
				handleNotYetImplementedElement(next);
......
742 816
			}
743 817
		}
744 818
		throw new IllegalStateException("<question> has no closing tag");
745
		
746 819
	}
747 820

  
748 821
	private void handleToCouplet(MarkupImportState state, XMLEventReader reader, XMLEvent next, PolytomousKeyNode node) throws XMLStreamException {
......
883 956
	 * @return
884 957
	 * @throws XMLStreamException
885 958
	 */
886
	private String makeNotesString(MarkupImportState state,	XMLEventReader reader, String text, XMLEvent next)
887
			throws XMLStreamException {
959
	private String makeNotesString(MarkupImportState state,	XMLEventReader reader, String text, XMLEvent next) throws XMLStreamException {
888 960
		Map<String, String> stringMap = handleString(state, reader,	next);
889 961
		if (stringMap.size() == 0){
890 962
			String message = "No text available in <notes>";
......
973 1045
		return nc;
974 1046
	}
975 1047

  
976
	private String handleTaxonTitle(MarkupImportState state,
977
			XMLEventReader reader, XMLEvent parentEvent)
978
			throws XMLStreamException {
1048
	private String handleTaxonTitle(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent) throws XMLStreamException {
1049
		//attributes
979 1050
		String text = "";
980 1051
		Map<String, Attribute> attributes = getAttributes(parentEvent);
981 1052
		String rankAttr = getAndRemoveAttributeValue(attributes, RANK);
982 1053
		Rank rank = makeRank(state, rankAttr, false);
983
		// TODO
984
		// String numAttr = getAndRemoveAttributeValue(attributes, NUM);
985
		handleNotYetImplementedAttribute(attributes, NUM);
1054
		String num = getAndRemoveAttributeValue(attributes, NUM);
1055
		state.setCurrentTaxonNum(num);
986 1056
		checkNoAttributes(attributes, parentEvent);
987 1057

  
988 1058
		// TODO handle attributes
......
995 1065
					if (checkMandatoryText(text, parentEvent)) {
996 1066
						titleText = normalize(text);
997 1067
						UUID uuidTitle = MarkupTransformer.uuidTaxonTitle;
998
						ExtensionType titleExtension = this.getExtensionType(
999
								state, uuidTitle, "Taxon Title ",
1000
								"taxon title", "title");
1068
						ExtensionType titleExtension = this.getExtensionType(state, uuidTitle, "Taxon Title ","taxon title", "title");
1001 1069
						taxon.addExtension(titleText, titleExtension);
1002 1070
					}
1003 1071
					taxon.getName().setRank(rank);
......
1658 1726
			handleNotYetImplementedAttribute(attributes, LOST);
1659 1727
		}
1660 1728

  
1661
		NonViralName firstName = null;
1729
		NonViralName<?> firstName = null;
1662 1730
		Set<TaxonNameBase> names = homotypicalGroup.getTypifiedNames();
1663 1731
		if (names.isEmpty()) {
1664 1732
			String message = "There is no name in a homotypical group. Can't create the specimen type";
......
1733 1801
			}
1734 1802
		}
1735 1803
		// TODO handle missing end element
1736
		throw new IllegalStateException("Specimen type has no closing tag"); // TODO
1737
																				// Auto-generated
1738
																				// method
1739
																				// stub
1740

  
1804
		throw new IllegalStateException("Specimen type has no closing tag"); 
1741 1805
	}
1742 1806

  
1743 1807
	private void makeSpecimenType(MarkupImportState state,
......
1761 1825
			DerivedUnitBase typeSpecimen = facade.addDuplicate(collection,
1762 1826
					null, null, null, null);
1763 1827
			typeSpecimen.setCacheStrategy(new DerivedUnitFacadeCacheStrategy());
1764
			name.addSpecimenTypeDesignation((Specimen) typeSpecimen,
1765
					typeStatus, null, null, null, false, addToAllNamesInGroup);
1828
			name.addSpecimenTypeDesignation((Specimen) typeSpecimen, typeStatus, null, null, null, false, addToAllNamesInGroup);
1766 1829
		}
1767

  
1768 1830
	}
1769 1831

  
1770 1832
	private Collection createCollection(String code) {
......
1803 1865
		return result;
1804 1866
	}
1805 1867

  
1806
	private void handleCollection(MarkupImportState state,
1807
			XMLEventReader reader, XMLEvent parentEvent,
1808
			HomotypicalGroup homotypicalGroup, DerivedUnitFacade facade)
1868
	
1869
	private void handleCollection(MarkupImportState state, XMLEventReader reader, XMLEvent parentEvent, HomotypicalGroup homotypicalGroup, DerivedUnitFacade facade)
1809 1870
			throws XMLStreamException {
1810 1871
		checkNoAttributes(parentEvent);
1811 1872
		boolean hasCollector = false;
......
1955 2016

  
1956 2017
	}
1957 2018

  
1958
	private NamedArea createArea(String text, NamedAreaLevel areaLevel,
1959
			MarkupImportState state) {
2019
	private NamedArea createArea(String text, NamedAreaLevel areaLevel, MarkupImportState state) {
1960 2020
		NamedArea area = NamedArea.NewInstance(text, text, null);
1961 2021
		area.setLevel(areaLevel);
1962 2022
		save(area, state);
......
2629 2689
					TextData textData = handleChar(state, reader, next);
2630 2690
					taxonDescription.addElement(textData);
2631 2691
				} else if (isStartingElement(next, STRING)) {
2632
					lastDescriptionElement = makeFeatureString(state, reader,
2633
							feature, taxonDescription, lastDescriptionElement,next);
2692
					lastDescriptionElement = makeFeatureString(state, reader,feature, taxonDescription, lastDescriptionElement,next);
2634 2693
				} else if (isStartingElement(next, FIGURE_REF)) {
2635
					lastDescriptionElement = makeFeatureFigureRef(state, reader, taxonDescription, isDescription,
2636
							lastDescriptionElement, next);
2694
					lastDescriptionElement = makeFeatureFigureRef(state, reader, taxonDescription, isDescription, lastDescriptionElement, next);
2637 2695
				} else if (isStartingElement(next, REFERENCES)) {
2638 2696
					// TODO details/microcitation ??
2639 2697

  
......
2727 2785
	 * @return
2728 2786
	 * @throws XMLStreamException
2729 2787
	 */
2730
	private DescriptionElementBase makeFeatureString(MarkupImportState state,
2731
			XMLEventReader reader, Feature feature,
2732
			TaxonDescription taxonDescription,
2733
			DescriptionElementBase lastDescriptionElement, XMLEvent next)
2788
	private DescriptionElementBase makeFeatureString(MarkupImportState state,XMLEventReader reader, Feature feature,
2789
			TaxonDescription taxonDescription, DescriptionElementBase lastDescriptionElement, XMLEvent next)
2734 2790
			throws XMLStreamException {
2735 2791
		Map<String, String> subheadingMap = handleString(state, reader, next);
2736 2792
		for (String subheading : subheadingMap.keySet()) {
......
3066 3122
		while (reader.hasNext()) {
3067 3123
			XMLEvent next = readNoWhitespace(reader);
3068 3124
			if (isMyEndingElement(next, parentEvent)) {
3069
				if (StringUtils.isNotBlank(text)) {
3070
					subHeadingMap.put(currentSubheading, text.trim());
3071
				}
3125
				putCurrentSubheading(subHeadingMap, currentSubheading, text);
3072 3126
				return subHeadingMap;
3127
			} else if (isStartingElement(next, BR)) {
3128
				text += "<br/>";
3129
				isTextMode = false;
3130
			} else if (isEndingElement(next, BR)) {
3131
				isTextMode = true;
3073 3132
			} else if (isHtml(next)) {
3074 3133
				text += getXmlTag(next);
3075
			} else if (next.isEndElement()) {
3076
				if (isEndingElement(next, ANNOTATION)) {
3077
					popUnimplemented(next.asEndElement());
3078
				} else if (isEndingElement(next, BR)) {
3079
					isTextMode = true;
3080
				} else {
3081
					handleUnexpectedEndElement(next.asEndElement());
3082
				}
3083
			} else if (next.isStartElement()) {
3084
				if (isStartingElement(next, SUB_HEADING)) {
3085
					if (StringUtils.isNotBlank(text)) {
3086
						subHeadingMap.put(currentSubheading, text.trim());
3087
						text = ""; // reset
3088
					}
3089
					// TODO footnotes
3090
					currentSubheading = getCData(state, reader, next).trim();
3091
				} else if (isStartingElement(next, ANNOTATION)) {
3092
					handleNotYetImplementedElement(next);
3093
				} else if (isStartingElement(next, BR)) {
3094
					text += "<br/>";
3095
					isTextMode = false;
3096
				} else {
3097
					handleUnexpectedStartElement(next.asStartElement());
3098
				}
3134
			} else if (isStartingElement(next, SUB_HEADING)) {
3135
				text = putCurrentSubheading(subHeadingMap,currentSubheading, text);
3136
				// TODO footnotes
3137
				currentSubheading = getCData(state, reader, next).trim();
3099 3138
			} else if (next.isCharacters()) {
3100 3139
				if (!isTextMode) {
3101 3140
					String message = "String is not in text mode";
......
3103 3142
				} else {
3104 3143
					text += next.asCharacters().getData();
3105 3144
				}
3145
			} else if (isStartingElement(next, COLLECTION)) {
3146
				//TODO
3147
				handleNotYetImplementedElement(next);
3148
			} else if (isEndingElement(next, COLLECTION)) {
3149
				//TODO
3150
				popUnimplemented(next.asEndElement());
3151
			} else if (isStartingElement(next, ANNOTATION)) {
3152
				//TODO
3153
				handleNotYetImplementedElement(next);
3154
			} else if (isEndingElement(next, ANNOTATION)) {
3155
				//TODO
3156
				popUnimplemented(next.asEndElement());
3106 3157
			} else {
3107
				handleUnexpectedEndElement(next.asEndElement());
3158
				handleUnexpectedElement(next);
3108 3159
			}
3109 3160
		}
3110 3161
		throw new IllegalStateException("<String> has no closing tag");
3162
	}
3111 3163

  
3164
	/**
3165
	 * @param subHeadingMap
3166
	 * @param currentSubheading
3167
	 * @param text
3168
	 * @return
3169
	 */
3170
	private String putCurrentSubheading(Map<String, String> subHeadingMap, String currentSubheading, String text) {
3171
		if (StringUtils.isNotBlank(text)) {
3172
			text = removeStartingMinus(text);
3173
			subHeadingMap.put(currentSubheading, text.trim());
3174
		}
3175
		return "";
3112 3176
	}
3113 3177

  
3178
	private String removeStartingMinus(String string) {
3179
		string = replaceStart(string, "-");
3180
		string = replaceStart(string, "\u002d");
3181
		string = replaceStart(string, "\u2013");
3182
		string = replaceStart(string, "\u2014");
3183
		string = replaceStart(string, "--");
3184
		return string;
3185
	}
3186
	
3187
	/**
3188
	 * @param value
3189
	 * @param replacementString
3190
	 */
3191
	private String replaceStart(String value, String replacementString) {
3192
		if (value.startsWith(replacementString) ){
3193
			value = value.substring(replacementString.length()).trim();
3194
		}
3195
		while (value.startsWith("-") || value.startsWith("\u2014") ){
3196
			value = value.substring("-".length()).trim();
3197
		}
3198
		return value;
3199
	}
3200
	
3114 3201
	private String getXmlTag(XMLEvent event) {
3115 3202
		String result;
3116 3203
		if (event.isStartElement()) {

Also available in: Unified diff