Project

General

Profile

Download (28.1 KB) Statistics
| Branch: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy 
4
* http://www.e-taxonomy.eu
5
* 
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.
8
*/
9

    
10
package eu.etaxonomy.cdm.io.redlist.bfnXml;
11

    
12
import java.util.ArrayList;
13
import java.util.Collection;
14
import java.util.LinkedHashMap;
15
import java.util.List;
16
import java.util.Map;
17
import java.util.UUID;
18

    
19
import org.apache.commons.lang.StringUtils;
20
import org.apache.log4j.Logger;
21
import org.jdom.Element;
22
import org.jdom.Namespace;
23
import org.springframework.stereotype.Component;
24
import org.springframework.transaction.TransactionStatus;
25

    
26
import eu.etaxonomy.cdm.api.service.IClassificationService;
27
import eu.etaxonomy.cdm.api.service.ITaxonService;
28
import eu.etaxonomy.cdm.common.ResultWrapper;
29
import eu.etaxonomy.cdm.common.XmlHelp;
30
import eu.etaxonomy.cdm.io.common.ICdmIO;
31
import eu.etaxonomy.cdm.model.common.CdmBase;
32
import eu.etaxonomy.cdm.model.common.Language;
33
import eu.etaxonomy.cdm.model.description.CategoricalData;
34
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
35
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
36
import eu.etaxonomy.cdm.model.description.Feature;
37
import eu.etaxonomy.cdm.model.description.State;
38
import eu.etaxonomy.cdm.model.description.TaxonDescription;
39
import eu.etaxonomy.cdm.model.description.TextData;
40
import eu.etaxonomy.cdm.model.location.NamedArea;
41
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
42
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
43
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
44
import eu.etaxonomy.cdm.model.name.NonViralName;
45
import eu.etaxonomy.cdm.model.name.Rank;
46
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
47
import eu.etaxonomy.cdm.model.taxon.Classification;
48
import eu.etaxonomy.cdm.model.taxon.Synonym;
49
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
50
import eu.etaxonomy.cdm.model.taxon.Taxon;
51
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
52
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
53
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
54
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
55
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
56
import eu.etaxonomy.cdm.strategy.parser.ParserProblem;
57
/**
58
 * 
59
 * @author a.oppermann
60
 * @date 04.07.2013
61
 *
62
 */
63
//@Component("bfnXmlTaxonNameIO")
64
@Component
65
public class BfnXmlImportTaxonName extends BfnXmlImportBase implements ICdmIO<BfnXmlImportState> {
66

    
67
	
68
	private static final Logger logger = Logger.getLogger(BfnXmlImportTaxonName.class);
69

    
70
	private static final String strNomenclaturalCode = "Zoological";//"Botanical";
71
	private static int parsingProblemCounter = 0;
72
	private Map<Integer, Taxon> firstList;
73
	private Map<Integer, Taxon> secondList;
74
	
75
	
76
	public BfnXmlImportTaxonName(){
77
		super();
78
	}
79

    
80
	@Override
81
	public boolean doCheck(BfnXmlImportState state){
82
		boolean result = true;
83
		return result;
84
	}
85

    
86
	@Override
87
	@SuppressWarnings({"rawtypes" })
88
	public void doInvoke(BfnXmlImportState state){
89
		ITaxonService taxonService = getTaxonService();
90

    
91
		BfnXmlImportConfigurator config = state.getConfig();
92
		Element elDataSet = getDataSetElement(config);
93
		//TODO set Namespace
94
		Namespace bfnNamespace = config.getBfnXmlNamespace();
95
		
96
		List<?> contentXML = elDataSet.getContent();
97
		Element currentElement = null;
98
		for(Object object:contentXML){
99
		
100
			if(object instanceof Element){
101
				currentElement = (Element)object;
102
				//import taxon lists
103
				if(currentElement.getName().equalsIgnoreCase("ROTELISTEDATEN")){
104
					TransactionStatus tx = startTransaction();
105
					Map<UUID, TaxonBase> savedTaxonMap = extractTaxonNames(state, taxonService, config, currentElement, bfnNamespace);
106
					createOrUdateClassification(config, taxonService, savedTaxonMap, currentElement, state);
107
					commitTransaction(tx);
108
				}//import concept relations of taxon lists
109
				if(config.isHasSecondList()){
110
					if(currentElement.getName().equalsIgnoreCase("KONZEPTBEZIEHUNGEN")){
111
						TransactionStatus tx = startTransaction();
112
						extractTaxonConceptRelationShips(bfnNamespace,currentElement);
113
						commitTransaction(tx);
114
					}
115
				}
116
			}
117
		}
118
		return;
119
	}
120

    
121
	/**
122
	 * This method will parse the XML concept relationships and tries to map them into cdm relationship types.
123
	 * 
124
	 * @param bfnNamespace
125
	 * @param currentElement
126
	 */
127
	private void extractTaxonConceptRelationShips(Namespace bfnNamespace,
128
			Element currentElement) {
129
		String childName;
130
		String bfnElementName = "KONZEPTBEZIEHUNG";
131
		ResultWrapper<Boolean> success = ResultWrapper.NewInstance(true);
132
		List<Element> elConceptList = (List<Element>)currentElement.getChildren(bfnElementName, bfnNamespace);
133
		List<TaxonBase> updatedTaxonList = new ArrayList<TaxonBase>();
134
		for(Element element:elConceptList){
135
			
136
			childName = "TAXONYM1";
137
			Element elTaxon1 = XmlHelp.getSingleChildElement(success, element, childName, bfnNamespace, false);
138
			String taxNr1 = elTaxon1.getAttributeValue("taxNr");
139
			int int1 = Integer.parseInt(taxNr1);
140
			Taxon taxon1 = firstList.get(int1);
141
			TaxonBase<?> taxonBase1 = getTaxonService().load(taxon1.getUuid());
142
			taxon1 = (Taxon)taxonBase1;
143

    
144
			childName = "TAXONYM2";
145
			Element elTaxon2 = XmlHelp.getSingleChildElement(success, element, childName, bfnNamespace, false);
146
			String taxNr2 = elTaxon2.getAttributeValue("taxNr");
147
			int int2 = Integer.parseInt(taxNr2);
148
			Taxon taxon2 = secondList.get(int2);
149
			TaxonBase<?> taxonBase2 = getTaxonService().load(taxon2.getUuid());
150
			taxon2 = (Taxon) taxonBase2;
151
			
152
			childName = "STATUS";
153
			Element elConceptStatus = XmlHelp.getSingleChildElement(success, element, childName, bfnNamespace, false);
154
			String conceptStatusValue = elConceptStatus.getValue();
155
			conceptStatusValue = conceptStatusValue.replaceAll("\u00A0", "").trim();
156
			TaxonRelationshipType taxonRelationType = null;
157
			/**
158
			 * This if case only exists because it was decided not to have a included_in relationship type.
159
			 */
160
			if(conceptStatusValue.equalsIgnoreCase("<")){
161
				taxon2.addTaxonRelation(taxon1, TaxonRelationshipType.INCLUDES(), null, null);
162
			}else{
163
				try {
164
					taxonRelationType = BfnXmlTransformer.concept2TaxonRelation(conceptStatusValue);
165
				} catch (UnknownCdmTypeException e) {
166
					e.printStackTrace();
167
				}
168
				taxon1.addTaxonRelation(taxon2, taxonRelationType , null, null);
169
			}
170
			if(taxonRelationType != null && taxonRelationType.equals(TaxonRelationshipType.ALL_RELATIONSHIPS())){
171
				List<TaxonRelationship> relationsFromThisTaxon = (List<TaxonRelationship>) taxon1.getRelationsFromThisTaxon();
172
				TaxonRelationship taxonRelationship = relationsFromThisTaxon.get(0);
173
				taxonRelationship.setDoubtful(true);
174
			}
175
			updatedTaxonList.add(taxon2);
176
			updatedTaxonList.add(taxon1);
177
		}
178
		getTaxonService().saveOrUpdate(updatedTaxonList);
179
		logger.info("taxon relationships imported...");
180
	}
181

    
182
	/**
183
	 * This method stores the current imported maps in global variables to make
184
	 * them later available for matching the taxon relationships between these 
185
	 * imported lists.
186
	 *  
187
	 * @param config
188
	 * @param taxonMap
189
	 */
190
	private void prepareListforConceptImport(BfnXmlImportConfigurator config,Map<Integer, Taxon> taxonMap) {
191
		if(config.isFillSecondList()){
192
			secondList = taxonMap;
193
		}else{
194
			firstList = taxonMap;
195
		}
196
	}
197

    
198
	/**
199
	 * 
200
	 * @param state
201
	 * @param taxonService
202
	 * @param config
203
	 * @param elDataSet
204
	 * @param bfnNamespace
205
	 * @return
206
	 */
207
	private Map<UUID, TaxonBase> extractTaxonNames(BfnXmlImportState state,
208
			ITaxonService taxonService, BfnXmlImportConfigurator config,
209
			Element elDataSet, Namespace bfnNamespace) {
210
		logger.info("start make TaxonNames...");
211
		Map<Integer, Taxon> taxonMap = new LinkedHashMap<Integer, Taxon>();
212
		ResultWrapper<Boolean> success = ResultWrapper.NewInstance(true);
213
		String childName;
214
		boolean obligatory;
215
		String idNamespace = "TaxonName";
216
		
217
		childName = "TAXONYME";
218
		obligatory = false;
219
		Element elTaxonNames = XmlHelp.getSingleChildElement(success, elDataSet, childName, bfnNamespace, obligatory);
220

    
221
		String bfnElementName = "TAXONYM";
222
		List<Element> elTaxonList = (List<Element>)elTaxonNames.getChildren(bfnElementName, bfnNamespace);
223
		
224
		//for each taxonName
225
		for (Element elTaxon : elTaxonList){
226
			//create Taxon
227
			String taxonId = elTaxon.getAttributeValue("taxNr");
228
			childName = "WISSNAME";
229
			Element elWissName = XmlHelp.getSingleChildElement(success, elTaxon, childName, bfnNamespace, obligatory);
230
			String childElementName = "NANTEIL";
231
			Taxon taxon = createOrUpdateTaxon(success, idNamespace, config, bfnNamespace, elWissName, childElementName, state);
232
			
233
			//for each synonym
234
			childName = "SYNONYME";
235
			Element elSynonyms = XmlHelp.getSingleChildElement(success, elTaxon, childName, bfnNamespace, obligatory);
236
			if(elSynonyms != null){
237
				childElementName = "SYNONYM";
238
				createOrUpdateSynonym(taxon, success, obligatory, bfnNamespace, childElementName,elSynonyms, taxonId, state);
239
			}
240
			//for vernacular name
241
			childName = "DEUTSCHENAMEN";
242
			Element elVernacularName = XmlHelp.getSingleChildElement(success, elTaxon, childName, bfnNamespace, obligatory);
243
			if(elVernacularName != null){
244
				childElementName = "DNAME";
245
				createOrUpdateVernacularName(taxon, bfnNamespace, childElementName, elVernacularName, state);
246
			}
247
			//for each information concerning the taxon element
248
			//TODO Information block
249
			if(config.isDoInformationImport()){
250
				childName = "INFORMATIONEN";
251
				Element elInformations = XmlHelp.getSingleChildElement(success, elTaxon, childName, bfnNamespace, obligatory);
252
				if(elInformations != null){
253
					childElementName = "BEZUGSRAUM";
254
					createOrUpdateInformation(taxon, bfnNamespace, childElementName,elInformations, state);
255
				}
256
			}
257
			taxonMap.put(Integer.parseInt(taxonId), taxon);
258
		}
259
		
260
		//Quick'n'dirty to set concept relationships between two imported list
261
		prepareListforConceptImport(config, taxonMap);
262
		
263
		Map<UUID, TaxonBase> savedTaxonMap = taxonService.saveOrUpdate((Collection)taxonMap.values());
264
		//FIXME: after first list don't import metadata yet
265
		//TODO: import information for second taxon list.
266
		config.setDoInformationImport(false);
267
		logger.info("end makeTaxonNames ...");
268
		if (!success.getValue()){
269
			state.setUnsuccessfull();
270
		}
271
		return savedTaxonMap;
272
	}
273

    
274

    
275

    
276

    
277
	/**
278
	 * This will put the prior imported list into a classification
279
	 * 
280
	 * @param config 
281
	 * @param taxonService 
282
	 * @param config 
283
	 * @param savedTaxonMap 
284
	 * @param currentElement 
285
	 * @param state 
286
	 * @return 
287
	 */
288
	@SuppressWarnings("rawtypes")
289
	private boolean createOrUdateClassification(BfnXmlImportConfigurator config, ITaxonService taxonService, Map<UUID, TaxonBase> savedTaxonMap, Element currentElement, BfnXmlImportState state) {
290
		boolean isNewClassification = true;
291
		String classificationName = state.getFirstClassificationName();
292
		if(config.isFillSecondList()){
293
			classificationName = state.getSecondClassificationName();
294
		}
295
//		if(classificationName == null){
296
//			classificationName = config.getClassificationName();
297
//		}
298
		//TODO make classification name dynamically depending on its value in the XML.
299
		Classification classification = Classification.NewInstance(classificationName+" "+currentElement.getAttributeValue("inhalt"), state.getCompleteSourceRef());
300
		classification.addImportSource(Integer.toString(classification.getId()), classification.getTitleCache(), state.getCompleteSourceRef(), state.getCurrentMicroRef().toString());
301
//		List<Classification> classificationList = getClassificationService().list(Classification.class, null, null, null, VOC_CLASSIFICATION_INIT_STRATEGY);
302
//		for(Classification c : classificationList){
303
//			if(c.getTitleCache().equalsIgnoreCase(classification.getTitleCache())){
304
//				classification = c;
305
//				isNewClassification = false;
306
//			}
307
//		}
308
		
309
//		ArrayList<TaxonBase> taxonBaseList = (ArrayList<TaxonBase>) taxonService.list(TaxonBase.class, null, null, null, VOC_CLASSIFICATION_INIT_STRATEGY);
310
		for(TaxonBase tb:savedTaxonMap.values()){
311
			if(tb instanceof Taxon){
312
				TaxonBase tbase = CdmBase.deproxy(tb, TaxonBase.class);
313
				Taxon taxon = (Taxon)tbase;
314
				taxon = CdmBase.deproxy(taxon, Taxon.class);
315
				classification.addChildTaxon(taxon, null, null);
316
			}
317
		}
318
		IClassificationService classificationService = getClassificationService();
319
		classificationService.saveOrUpdate(classification);
320
		//set boolean for reference and internal mapping of concept relations
321
		if(config.isHasSecondList()){
322
			config.setFillSecondList(true);
323
		}
324
		return isNewClassification;
325
	}
326

    
327
	
328

    
329
	/**
330
	 * Matches the XML attributes against CDM entities.<BR> 
331
	 * Imports Scientific Name, Rank, etc. and creates a taxon.<br>
332
	 * <b>Existing taxon names won't be matched yet</b>
333
	 * 
334
	 * @param success
335
	 * @param idNamespace
336
	 * @param config
337
	 * @param bfnNamespace
338
	 * @param elTaxonName
339
	 * @param childElementName
340
	 * @param state 
341
	 * @return
342
	 */
343
	
344
	@SuppressWarnings({ "unchecked", "rawtypes" })
345
	private Taxon createOrUpdateTaxon(
346
			ResultWrapper<Boolean> success, String idNamespace,
347
			BfnXmlImportConfigurator config, Namespace bfnNamespace,
348
			Element elTaxonName, String childElementName, BfnXmlImportState state) {
349
		
350
		List<Element> elWissNameList = (List<Element>)elTaxonName.getChildren(childElementName, bfnNamespace);
351
		Rank rank = null;
352
		String strAuthor = null;
353
		String strSupplement = null;
354
		Taxon taxon = null;
355
		String uniqueID = null;
356
		String uriNameSpace = null;
357
//		Long uniqueID = null;
358
		for(Element elWissName:elWissNameList){
359

    
360
			if(elWissName.getAttributeValue("bereich", bfnNamespace).equalsIgnoreCase("Eindeutiger Code")){
361
				uriNameSpace = elWissName.getAttributeValue("bereich");
362
				String textNormalize = elWissName.getTextNormalize();
363
				if(StringUtils.isBlank(textNormalize)){
364
					uniqueID = "";
365
				}else{
366
					uniqueID = textNormalize;
367
				}
368
			}
369
			if(elWissName.getAttributeValue("bereich", bfnNamespace).equalsIgnoreCase("Autoren")){
370
				strAuthor = elWissName.getTextNormalize();
371
			}
372
			if(elWissName.getAttributeValue("bereich", bfnNamespace).equalsIgnoreCase("Rang")){
373
				String strRank = elWissName.getTextNormalize();
374
				rank = makeRank(strRank);
375
			}
376
			if(elWissName.getAttributeValue("bereich", bfnNamespace).equalsIgnoreCase("Zusätze")){
377
				strSupplement = elWissName.getTextNormalize();
378
			}
379
			if(elWissName.getAttributeValue("bereich", bfnNamespace).equalsIgnoreCase("wissName")){
380
				try{
381
					TaxonNameBase<?, ?> nameBase = parseNonviralNames(rank,strAuthor,strSupplement,elWissName);
382
					//TODO  extract to method?
383
					if(strSupplement != null && strSupplement.equalsIgnoreCase("nom. illeg.")){
384
						nameBase.addStatus(NomenclaturalStatus.NewInstance(NomenclaturalStatusType.ILLEGITIMATE()));
385
					}
386

    
387
					//					nameBase.setId(Integer.parseInt(strId));
388
					//ImportHelper.setOriginalSource(nameBase, config.getSourceReference(), strId, idNamespace);
389

    
390
					
391
					/**
392
					 *  BFN does not want any name matching yet
393
					 */
394
//					TaxonBase<?> taxonBase = null;
395
//					//TODO find best matching Taxa
396
//					Pager<TaxonNameBase> names = getNameService().findByTitle(null, nameBase.getTitleCache(), null, null, null, null, null, null);
397
//					//TODO  correct handling for pager
398
//					List<TaxonNameBase> nameList = names.getRecords();
399
//					if (nameList.isEmpty()){
400
//						taxonBase = Taxon.NewInstance(nameBase, config.getSourceReference());	
401
//					}else{
402
//						taxonBase = Taxon.NewInstance(nameList.get(0), config.getSourceReference());
403
//						if (nameList.size()>1){
404
//							logger.warn("More than 1 matching taxon name found for " + nameBase.getTitleCache());
405
//						}
406
//					}CurrentMicroRef
407

    
408
//					taxon = (Taxon) taxonBase;
409
					state.setCurrentMicroRef(state.getFirstListSecRef());
410
					if(config.isFillSecondList()){
411
						state.setCurrentMicroRef(state.getSecondListSecRef());
412
					}
413
					taxon = Taxon.NewInstance(nameBase, state.getCurrentMicroRef());
414
//					logger.info("Taxon Reference" + taxon.getSec().getTitle());
415
					//set NameSpace
416
					Element parentElement = elWissName.getParentElement();
417
					Element grandParentElement = parentElement.getParentElement();
418
//					Element newElement = new Element("prefix", parentElement.getName()+":"+parentElement.getAttribute("taxNr").getName());
419
//					Element newElement = new Element("element",grandParentElement.getName()+"-"+parentElement.getName()+"-"+elWissName.getName() , uriNameSpace);
420
//					config.setBfnXmlNamespace(newElement.getNamespace());
421
					
422
					taxon.addImportSource(uniqueID, grandParentElement.getName()+":"+parentElement.getName()+":"+elWissName.getName()+":"+uriNameSpace, state.getCompleteSourceRef(), state.getCurrentMicroRef().getTitle());
423
				} catch (UnknownCdmTypeException e) {
424
					success.setValue(false); 
425
				}
426
			}
427
		}
428
		return taxon;
429
	}
430
	
431
	/**
432
	 * Matches the XML attributes against CDM entities.<BR>
433
	 * Imports Scientific Name, Rank etc. and create a synonym.<br>
434
	 * <b>Existing synonym names won't be matched yet</b>
435
	 * 
436
	 * @param taxon
437
	 * @param success
438
	 * @param obligatory
439
	 * @param bfnNamespace
440
	 * @param childElementName
441
	 * @param elSynonyms
442
	 * @param taxonId
443
	 * @param config
444
	 * @param state 
445
	 */
446

    
447
	@SuppressWarnings({ "unchecked" })
448
	private void createOrUpdateSynonym(Taxon taxon, ResultWrapper<Boolean> success, boolean obligatory, Namespace bfnNamespace, 
449
			     String childElementName, Element elSynonyms, String taxonId, BfnXmlImportState state) {
450
		
451
		String childName;
452
		List<Element> elSynonymList = (List<Element>)elSynonyms.getChildren(childElementName, bfnNamespace);
453

    
454
		for(Element elSyn:elSynonymList){
455
			Rank rank = null;
456
			String strAuthor = null;
457
			String strSupplement = null;
458
			childName = "WISSNAME";
459
			Element elSynScientificName = XmlHelp.getSingleChildElement(success, elSyn, childName, bfnNamespace, obligatory);
460

    
461
			childElementName = "NANTEIL";
462
			List<Element> elSynDetails = (List<Element>)elSynScientificName.getChildren(childElementName, bfnNamespace);
463

    
464
			for(Element elSynDetail:elSynDetails){
465
				if(elSynDetail.getAttributeValue("bereich").equalsIgnoreCase("Rang")){
466
					String strRank = elSynDetail.getTextNormalize();
467
					rank = makeRank(strRank);
468
				}
469
				if(elSynDetail.getAttributeValue("bereich").equalsIgnoreCase("Autoren")){
470
					strAuthor = elSynDetail.getTextNormalize();
471
				}	
472
				if(elSynDetail.getAttributeValue("bereich", bfnNamespace).equalsIgnoreCase("Zusätze")){
473
					strSupplement = elSynDetail.getTextNormalize();
474
				}
475
				if(elSynDetail.getAttributeValue("bereich").equalsIgnoreCase("wissName")){
476
					try{
477
						TaxonNameBase<?, ?> nameBase = parseNonviralNames(rank,strAuthor,strSupplement,elSynDetail);
478

    
479
						//TODO find best matching Taxa
480
						Synonym synonym = Synonym.NewInstance(nameBase, state.getCurrentMicroRef());
481
						taxon.addSynonym(synonym, SynonymRelationshipType.SYNONYM_OF());
482
						
483
					} catch (UnknownCdmTypeException e) {
484
						logger.warn("Name with id " + taxonId + " has unknown nomenclatural code.");
485
						success.setValue(false); 
486
					}
487
				
488
				}
489
				
490
			}
491
		}
492
	}
493

    
494
	
495
	/**
496
	 * 
497
	 * @param taxon
498
	 * @param bfnNamespace
499
	 * @param childElementName
500
	 * @param elVernacularName
501
	 * @param state
502
	 */
503
	private void createOrUpdateVernacularName(Taxon taxon,
504
			Namespace bfnNamespace, String childElementName,
505
			Element elVernacularName, BfnXmlImportState state) {
506
		
507
		List<Element> elVernacularNameList = (List<Element>)elVernacularName.getChildren(childElementName, bfnNamespace);
508
		
509
		TaxonDescription taxonDescription = getTaxonDescription(taxon, false, true);
510
		
511
		for(Element elVernacular : elVernacularNameList){
512
			Element child = elVernacular.getChild("TRIVIALNAME");
513
			if(child != null){
514
				makeCommonName(taxonDescription, child, state);
515
			}
516
		}
517
		
518
	}
519
	
520
	/**
521
	 * 
522
	 * @param taxon
523
	 * @param bfnNamespace
524
	 * @param childElementName
525
	 * @param elInformations
526
	 * @param state
527
	 */
528

    
529
	@SuppressWarnings("unchecked")
530
	private void createOrUpdateInformation(Taxon taxon,
531
			Namespace bfnNamespace, String childElementName,
532
			Element elInformations, 
533
			BfnXmlImportState state) {
534

    
535
		List<Element> elInformationList = (List<Element>)elInformations.getChildren(childElementName, bfnNamespace);
536
        
537
		//TODO
538
		TaxonDescription taxonDescription = getTaxonDescription(taxon, false, true);
539
		for(Element elInfo:elInformationList){
540

    
541
			childElementName = "IWERT";
542
			List<Element> elInfoDetailList = (List<Element>)elInfo.getChildren(childElementName, bfnNamespace);
543

    
544
			for(Element elInfoDetail : elInfoDetailList){
545
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("RL Kat.")){
546
					makeFeatures(taxonDescription, elInfoDetail, state, false);
547
				}
548
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("Kat. +/-")){
549
					makeFeatures(taxonDescription, elInfoDetail, state, false);
550
				}
551
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("aktuelle Bestandsstituation")){
552
					makeFeatures(taxonDescription, elInfoDetail, state, false);
553
				}
554
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("langfristiger Bestandstrend")){
555
					makeFeatures(taxonDescription, elInfoDetail, state, false);
556
				}
557
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("kurzfristiger Bestandstrend")){
558
					makeFeatures(taxonDescription, elInfoDetail, state, false);
559
				}
560
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("Risikofaktoren")){
561
					makeFeatures(taxonDescription, elInfoDetail, state, false);
562
				}
563
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("Verantwortlichkeit")){
564
					makeFeatures(taxonDescription, elInfoDetail, state, false);
565
				}
566
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("alte RL- Kat.")){
567
					makeFeatures(taxonDescription, elInfoDetail, state, false);
568
				}
569
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("Neobiota")){
570
					makeFeatures(taxonDescription, elInfoDetail, state, false);
571
				}
572
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("Eindeutiger Code")){
573
					makeFeatures(taxonDescription, elInfoDetail, state, false);
574
				}
575
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("Kommentar zur Taxonomie")){
576
					makeFeatures(taxonDescription, elInfoDetail, state, true);
577
				}
578
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("Kommentar zur Gefährdung")){
579
					makeFeatures(taxonDescription, elInfoDetail, state, true);
580
				}
581
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("Sonderfälle")){
582
					makeFeatures(taxonDescription, elInfoDetail, state, false);
583
				}
584
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("Letzter Nachweis")){
585
					makeFeatures(taxonDescription, elInfoDetail, state, true);
586
				}
587
				if(elInfoDetail.getAttributeValue("standardname").equalsIgnoreCase("Weitere Kommentare")){
588
					makeFeatures(taxonDescription, elInfoDetail, state, true);
589
				}
590
			}
591
		}
592
	}
593

    
594
	
595
	
596
	private void makeCommonName(TaxonDescription taxonDescription,
597
			Element child, BfnXmlImportState state) {
598
		String commonNameValue = child.getValue();
599
		NamedArea area = getTermService().getAreaByTdwgAbbreviation("GER");
600
		CommonTaxonName commonName = CommonTaxonName.NewInstance(commonNameValue, Language.GERMAN(), area);
601
		taxonDescription.addElement(commonName);
602
	}
603

    
604
	
605
	/**
606
	 * 
607
	 * @param taxonDescription
608
	 * @param elInfoDetail
609
	 * @param state
610
	 * @param isTextData
611
	 */
612
	private void makeFeatures(
613
			TaxonDescription taxonDescription,
614
			Element elInfoDetail,
615
			BfnXmlImportState state,
616
			boolean isTextData) {
617
		
618
		String transformedRlKatValue = null;
619
		UUID featureUUID = null;
620
		UUID stateTermUUID = null;
621
		String strRlKatValue = elInfoDetail.getChild("WERT").getValue();
622
		String strRlKat = elInfoDetail.getAttributeValue("standardname");
623
		boolean randomStateUUID = false;
624
		try {
625
			featureUUID = BfnXmlTransformer.getRedlistFeatureUUID(strRlKat);
626
			transformedRlKatValue = BfnXmlTransformer.redListString2RedListCode(strRlKatValue);
627
		} catch (UnknownCdmTypeException e) {
628
			transformedRlKatValue = strRlKatValue;
629
		}
630
		Feature redListFeature = getFeature(state, featureUUID);
631
		State rlState = null;
632
		//if is text data a state is not needed
633
		if(!isTextData){
634
			try {
635
				stateTermUUID = BfnXmlTransformer.getRedlistStateTermUUID(transformedRlKatValue, strRlKat);
636
			} catch (UnknownCdmTypeException e) {
637
				stateTermUUID = UUID.randomUUID();
638
				randomStateUUID = true;
639
			}
640
			if(randomStateUUID || stateTermUUID == BfnXmlTransformer.stateTermEmpty){
641
				if(stateTermUUID == BfnXmlTransformer.stateTermEmpty)
642
					transformedRlKatValue = "keine Angabe";
643
				rlState = getStateTerm(state, stateTermUUID, transformedRlKatValue, transformedRlKatValue, transformedRlKatValue, null);
644
			}else{
645
				rlState = getStateTerm(state, stateTermUUID);
646
			}
647
		}
648
		if(isTextData){
649
			TextData textData = TextData.NewInstance(redListFeature);
650
			textData.putText(Language.GERMAN(), strRlKatValue);
651
			DescriptionElementBase descriptionElement = textData;
652
			taxonDescription.addElement(descriptionElement);
653
		}else{
654
			CategoricalData catData = CategoricalData.NewInstance(rlState, redListFeature);
655
			DescriptionElementBase descriptionElement = catData;
656
			taxonDescription.addElement(descriptionElement);
657
		}
658
	}
659
	
660
	/**
661
	 * Returns the rank represented by the rank element.<br>
662
	 * Returns <code>null</code> if the element is null.<br>
663
	 * Returns <code>null</code> if the code and the text are both either empty or do not exists.<br>
664
	 * Returns the rank represented by the code attribute, if the code attribute is not empty and could be resolved.<br>
665
	 * If the code could not be resolved it returns the rank represented most likely by the elements text.<br>
666
	 * Returns UNKNOWN_RANK if code attribute and element text could not be resolved.
667
	 * @param strRank bfn rank element
668
	 * @return 
669
	 */
670
	protected static Rank makeRank(String strRank){
671
		Rank result;
672
 		if (strRank == null){
673
			return null;
674
		}	
675
		Rank codeRank = null;
676
		try {
677
			codeRank = BfnXmlTransformer.rankCode2Rank(strRank);
678
		} catch (UnknownCdmTypeException e1) {
679
			codeRank = Rank.UNKNOWN_RANK();
680
		}
681
		//codeRank exists
682
		if ( (codeRank != null) && !codeRank.equals(Rank.UNKNOWN_RANK())){
683
			result = codeRank;
684
		}
685
		//codeRank does not exist
686
		else{
687
			result = codeRank;
688
			logger.warn("string rank used, because code rank does not exist or was not recognized: " + codeRank.toString() +" "+strRank);
689
		}
690
		return result;
691
	}
692

    
693
	/**
694
	 * @param rank
695
	 * @param strAuthor
696
	 * @param strSupplement 
697
	 * @param elWissName
698
	 * @return
699
	 * @throws UnknownCdmTypeException
700
	 */
701
	private TaxonNameBase<?, ?> parseNonviralNames(Rank rank, String strAuthor, String strSupplement, Element elWissName)
702
			throws UnknownCdmTypeException {
703
		TaxonNameBase<?,?> taxonNameBase = null;
704

    
705
		NomenclaturalCode nomCode = BfnXmlTransformer.nomCodeString2NomCode(strNomenclaturalCode);
706
		//Todo check author
707
		String strScientificName = elWissName.getTextNormalize();
708
		if(strSupplement != null && !strSupplement.isEmpty()){
709
			strScientificName = StringUtils.remove(strScientificName, strSupplement);
710
		}
711

    
712
		NonViralName<?> nonViralName = null;
713
		NonViralNameParserImpl parser = NonViralNameParserImpl.NewInstance();
714
		nonViralName = parser.parseFullName(strScientificName, nomCode, rank);
715
		if(nonViralName.hasProblem()){
716
//			logger.info("Problems: "+nonViralName.hasProblem());
717
			//TODO handle parsing Problems
718
			
719
			for(ParserProblem p:nonViralName.getParsingProblems()){
720
				
721
				logger.info(++parsingProblemCounter + " " +nonViralName.toString() +" "+p.toString());
722
			}
723
		}
724
		Rank parsedRank = nonViralName.getRank();
725
		if(parsedRank != rank){
726
			nonViralName.setRank(rank);
727
		}
728
			
729
//		nonViralName.setNameCache(strScientificName);
730
		taxonNameBase = nonViralName;
731
		return taxonNameBase;
732
	}
733
	
734
	@Override
735
	protected boolean isIgnore(BfnXmlImportState state){
736
		return ! state.getConfig().isDoTaxonNames();
737
	}
738
}
(6-6/7)