Project

General

Profile

Download (50.5 KB) Statistics
| Branch: | Tag: | 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.specimen.abcd206.in;
11

    
12
import java.io.IOException;
13
import java.io.InputStream;
14
import java.net.MalformedURLException;
15
import java.net.URI;
16
import java.net.URL;
17
import java.util.ArrayList;
18
import java.util.HashMap;
19
import java.util.Iterator;
20
import java.util.List;
21
import java.util.Set;
22
import java.util.concurrent.CopyOnWriteArrayList;
23

    
24
import javax.xml.parsers.DocumentBuilder;
25
import javax.xml.parsers.DocumentBuilderFactory;
26
import javax.xml.parsers.ParserConfigurationException;
27

    
28
import org.apache.commons.lang.StringUtils;
29
import org.apache.log4j.Logger;
30
import org.springframework.stereotype.Component;
31
import org.springframework.transaction.TransactionStatus;
32
import org.w3c.dom.Document;
33
import org.w3c.dom.Element;
34
import org.w3c.dom.NodeList;
35
import org.xml.sax.SAXException;
36

    
37
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
38
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade.DerivedUnitType;
39
import eu.etaxonomy.cdm.io.common.ICdmIO;
40
import eu.etaxonomy.cdm.io.specimen.SpecimenImportBase;
41
import eu.etaxonomy.cdm.io.specimen.UnitsGatheringArea;
42
import eu.etaxonomy.cdm.io.specimen.UnitsGatheringEvent;
43
import eu.etaxonomy.cdm.model.agent.Institution;
44
import eu.etaxonomy.cdm.model.agent.Team;
45
import eu.etaxonomy.cdm.model.common.CdmBase;
46
import eu.etaxonomy.cdm.model.common.DescriptionElementSource;
47
import eu.etaxonomy.cdm.model.common.Language;
48
import eu.etaxonomy.cdm.model.description.Feature;
49
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
50
import eu.etaxonomy.cdm.model.description.TaxonDescription;
51
import eu.etaxonomy.cdm.model.location.NamedArea;
52
import eu.etaxonomy.cdm.model.media.Media;
53
import eu.etaxonomy.cdm.model.name.BacterialName;
54
import eu.etaxonomy.cdm.model.name.BotanicalName;
55
import eu.etaxonomy.cdm.model.name.CultivarPlantName;
56
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
57
import eu.etaxonomy.cdm.model.name.NonViralName;
58
import eu.etaxonomy.cdm.model.name.Rank;
59
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
60
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
61
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
62
import eu.etaxonomy.cdm.model.name.ZoologicalName;
63
import eu.etaxonomy.cdm.model.occurrence.Collection;
64
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
65
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
66
import eu.etaxonomy.cdm.model.occurrence.DerivedUnitBase;
67
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
68
import eu.etaxonomy.cdm.model.occurrence.FieldObservation;
69
import eu.etaxonomy.cdm.model.occurrence.Fossil;
70
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
71
import eu.etaxonomy.cdm.model.occurrence.LivingBeing;
72
import eu.etaxonomy.cdm.model.occurrence.Observation;
73
import eu.etaxonomy.cdm.model.occurrence.Specimen;
74
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
75
import eu.etaxonomy.cdm.model.reference.Reference;
76
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
77
import eu.etaxonomy.cdm.model.taxon.Classification;
78
import eu.etaxonomy.cdm.model.taxon.Taxon;
79
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
80
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
81
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
82

    
83
/**
84
 * @author p.kelbert
85
 * @created 20.10.2008
86
 * @version 1.0
87
 */
88
@Component
89
public class Abcd206Import extends
90
SpecimenImportBase<Abcd206ImportConfigurator, Abcd206ImportState>
91
implements ICdmIO<Abcd206ImportState> {
92
	private static final Logger logger = Logger.getLogger(Abcd206Import.class);
93
	private static String prefix = "";
94

    
95
	private Classification classification = null;
96
	private Reference<?> ref = null;
97

    
98
	private Abcd206ImportState abcdstate;
99
	private Abcd206DataHolder dataHolder;
100
	private DerivedUnitBase derivedUnitBase;
101

    
102
	private TransactionStatus tx;
103

    
104
	private Abcd206XMLFieldGetter abcdFileGetter;
105

    
106
	public Abcd206Import() {
107
		super();
108
	}
109

    
110
	@Override
111
	protected boolean doCheck(Abcd206ImportState state) {
112
		logger.warn("Checking not yet implemented for "
113
				+ this.getClass().getSimpleName());
114
		this.abcdstate = state;
115
		return true;
116
	}
117

    
118
	/**
119
	 * getClassification : get the classification declared in the ImportState
120
	 * 
121
	 * @param state
122
	 * @return
123
	 */
124
	private void setClassification(Abcd206ImportState state) {
125
		if (classification == null) {
126
			String name = state.getConfig().getClassificationName();
127

    
128
			classification = Classification.NewInstance(name, ref,
129
					Language.DEFAULT());
130
			if (state.getConfig().getClassificationUuid() != null) {
131
				classification.setUuid(state.getConfig()
132
						.getClassificationUuid());
133
			}
134
			getClassificationService().saveOrUpdate(classification);
135
			refreshTransaction();
136
		}
137
	}
138

    
139
	@Override
140
	public void doInvoke(Abcd206ImportState state) {
141
		abcdstate = state;
142
		tx = startTransaction();
143

    
144
		logger.info("INVOKE Specimen Import from ABCD2.06 XML ");
145
		URI sourceName = this.abcdstate.getConfig().getSource();
146
		NodeList unitsList = getUnitsNodeList(sourceName);
147

    
148
		this.abcdstate.getConfig().getClassificationName();
149
		this.abcdstate.getConfig().getClassificationUuid();
150

    
151
		ref = this.abcdstate.getConfig().getSourceReference();
152
		setClassification(abcdstate);
153

    
154
		if (unitsList != null) {
155
			String message = "nb units to insert: " + unitsList.getLength();
156
			logger.info(message);
157
			updateProgress(this.abcdstate, message);
158
			dataHolder = new Abcd206DataHolder();
159

    
160
			abcdFileGetter = new Abcd206XMLFieldGetter(dataHolder, prefix);
161

    
162
			for (int i = 0; i < unitsList.getLength(); i++) {
163

    
164
				// logger.info("UNIT NUMBER " + i);
165
				this.setUnitPropertiesXML((Element) unitsList.item(i));
166
				refreshTransaction();
167
				this.handleSingleUnit(i);
168

    
169
				// compare the ABCD elements added in to the CDM and the
170
				// unhandled ABCD elements
171
				compareABCDtoCDM(sourceName, dataHolder.knownABCDelements);
172

    
173
				// reset the ABCD elements added in CDM
174
				// knownABCDelements = new ArrayList<String>();
175
				dataHolder.allABCDelements = new HashMap<String, String>();
176

    
177
				refreshTransaction();
178

    
179
			}
180
		}
181
		commitTransaction(tx);
182
		return;
183

    
184
	}
185

    
186
	/*
187
	 * Return the list of root nodes for an ABCD 2.06 XML file
188
	 * 
189
	 * @param fileName: the file's location
190
	 * 
191
	 * @return the list of root nodes ("Unit")
192
	 */
193
	protected NodeList getUnitsNodeList(URI urlFileName) {
194
		NodeList unitList = null;
195
		try {
196
			DocumentBuilderFactory factory = DocumentBuilderFactory
197
					.newInstance();
198
			DocumentBuilder builder = factory.newDocumentBuilder();
199
			URL url = urlFileName.toURL();
200
			Object o = url.getContent();
201
			InputStream is = (InputStream) o;
202
			Document document = builder.parse(is);
203
			Element root = document.getDocumentElement();
204
			// logger.info("root nodename " + root.getNodeName());
205
			unitList = root.getElementsByTagName("Unit");
206
			if (unitList.getLength() == 0) {
207
				unitList = root.getElementsByTagName("abcd:Unit");
208
				prefix = "abcd:";
209
			}
210
		} catch (Exception e) {
211
			logger.warn(e);
212
		}
213
		return unitList;
214
	}
215

    
216
	/*
217
	 * Stores the unit with its Gathering informations in the CDM
218
	 */
219
	private void handleSingleUnit(int i) {
220
		logger.info("handleSingleUnit");
221

    
222
		try {
223
			updateProgress(this.abcdstate, "Importing data for unit: "
224
					+ dataHolder.unitID);
225

    
226

    
227
			// create facade
228
			DerivedUnitFacade derivedUnitFacade = getFacade();
229
			derivedUnitBase = derivedUnitFacade.innerDerivedUnit();
230

    
231
			//			getOccurrenceService().saveOrUpdate(derivedUnitBase);
232
			//			refreshTransaction();
233

    
234
			/**
235
			 * GATHERING EVENT
236
			 */
237

    
238
			// gathering event
239
			UnitsGatheringEvent unitsGatheringEvent = new UnitsGatheringEvent(
240
					getTermService(), dataHolder.locality, dataHolder.languageIso,
241
					dataHolder.longitude, dataHolder.latitude,
242
					dataHolder.gatheringAgentList);
243

    
244
			// country
245
			UnitsGatheringArea unitsGatheringArea = new UnitsGatheringArea(
246
					dataHolder.isocountry, dataHolder.country,
247
					getOccurrenceService());
248
			NamedArea areaCountry = unitsGatheringArea.getArea();
249

    
250
			// other areas
251
			unitsGatheringArea = new UnitsGatheringArea(dataHolder.namedAreaList);
252
			ArrayList<NamedArea> nas = unitsGatheringArea.getAreas();
253
			for (NamedArea namedArea : nas) {
254
				unitsGatheringEvent.addArea(namedArea);
255
			}
256

    
257
			// copy gathering event to facade
258
			GatheringEvent gatheringEvent = unitsGatheringEvent.getGatheringEvent();
259
			derivedUnitFacade.setLocality(gatheringEvent.getLocality());
260
			derivedUnitFacade.setExactLocation(gatheringEvent.getExactLocation());
261
			derivedUnitFacade.setCollector(gatheringEvent.getCollector());
262
			derivedUnitFacade.setCountry(areaCountry);
263
			derivedUnitFacade.addCollectingAreas(unitsGatheringArea.getAreas());
264

    
265
			// TODO exsiccatum
266

    
267
			// add fieldNumber
268
			derivedUnitFacade.setFieldNumber(dataHolder.fieldNumber);
269

    
270
			// //add Multimedia URLs
271
			if (dataHolder.multimediaObjects.size() != -1) {
272
				for (String multimediaObject : dataHolder.multimediaObjects) {
273
					Media media;
274
					try {
275
						media = getImageMedia(multimediaObject, READ_MEDIA_DATA,
276
								false);
277
						derivedUnitFacade.addDerivedUnitMedia(media);
278
					} catch (MalformedURLException e) {
279
						// TODO Auto-generated catch block
280
						e.printStackTrace();
281
					}
282

    
283
				}
284
			}
285

    
286
			/**
287
			 * merge AND STORE DATA
288
			 */
289
			getTermService().saveOrUpdate(areaCountry);// TODO save area sooner
290

    
291
			for (NamedArea area : nas) {
292
				getTermService().saveOrUpdate(area);// merge it sooner (foreach
293
				// area)
294
			}
295
			getTermService().saveLanguageData(unitsGatheringEvent.getLocality());
296

    
297
			// handle collection data
298
			setCollectionData(this.abcdstate.getConfig(), derivedUnitFacade);
299

    
300

    
301
			getOccurrenceService().saveOrUpdate(derivedUnitBase);
302
			refreshTransaction();
303

    
304
			// getOccurrenceService().saveOrUpdate(derivedUnitFacade.innerFieldObservation());
305

    
306
			// handle identifications
307
			handleIdentifications(this.abcdstate.getConfig(), derivedUnitFacade);
308

    
309
			/*
310
			 * getOccurrenceService().saveOrUpdate(
311
			 * derivedUnitFacade.innerFieldObservation());
312
			 */
313

    
314

    
315
			logger.info("saved ABCD specimen ...");
316

    
317
		} catch (Exception e) {
318
			logger.warn("Error when reading record!!");
319
			e.printStackTrace();
320
			this.abcdstate.setUnsuccessfull();
321
		}
322

    
323
		return;
324
	}
325

    
326
	/**
327
	 * setCollectionData : store the collection object into the
328
	 * derivedUnitFacade
329
	 * 
330
	 * @param config
331
	 */
332
	private void setCollectionData(Abcd206ImportConfigurator config,
333
			DerivedUnitFacade derivedUnitFacade) {
334
		// set catalogue number (unitID)
335
		derivedUnitFacade.setCatalogNumber(dataHolder.unitID);
336
		derivedUnitFacade.setAccessionNumber(dataHolder.accessionNumber);
337
		// derivedUnitFacade.setCollectorsNumber(dataHolder.collectorsNumber);
338

    
339
		/**
340
		 * INSTITUTION & COLLECTION
341
		 */
342
		// manage institution
343
		Institution institution = this.getInstitution(
344
				dataHolder.institutionCode, config);
345
		// manage collection
346
		Collection collection = this.getCollection(dataHolder.collectionCode,
347
				institution, config);
348
		// link specimen & collection
349
		derivedUnitFacade.setCollection(collection);
350
	}
351

    
352
	/**
353
	 * getFacade : get the DerivedUnitFacade based on the recordBasis
354
	 * 
355
	 * @return DerivedUnitFacade
356
	 */
357
	private DerivedUnitFacade getFacade() {
358
		// logger.info("GETFACADE");
359
		/**
360
		 * SPECIMEN OR OBSERVATION OR LIVING
361
		 */
362
		// DerivedUnitBase derivedThing = null;
363
		DerivedUnitType type = null;
364

    
365
		// create specimen
366
		if (dataHolder.recordBasis != null) {
367
			if (dataHolder.recordBasis.toLowerCase().startsWith("s")
368
					|| dataHolder.recordBasis.toLowerCase()
369
					.contains("specimen")) {// specimen
370
				type = DerivedUnitType.Specimen;
371
			}
372
			if (dataHolder.recordBasis.toLowerCase().startsWith("o")) {
373
				type = DerivedUnitType.Observation;
374
			}
375
			if (dataHolder.recordBasis.toLowerCase().contains("fossil"))
376
				type = DerivedUnitType.Fossil;
377

    
378
			if (dataHolder.recordBasis.toLowerCase().startsWith("l")) {
379
				type = DerivedUnitType.LivingBeing;
380
			}
381
			if (type == null) {
382
				logger.info("The basis of record does not seem to be known: "
383
						+ dataHolder.recordBasis);
384
				type = DerivedUnitType.DerivedUnit;
385
			}
386
			// TODO fossils?
387
		} else {
388
			logger.info("The basis of record is null");
389
			type = DerivedUnitType.DerivedUnit;
390
		}
391
		DerivedUnitFacade derivedUnitFacade = DerivedUnitFacade
392
				.NewInstance(type);
393
		return derivedUnitFacade;
394
	}
395

    
396
	/*
397
	 * Store the unit's properties into variables Look which unit is the
398
	 * preferred one Look what kind of name it is supposed to be, for the
399
	 * parsing (Botanical, Zoological)
400
	 * 
401
	 * @param racine: the root node for a single unit
402
	 */
403
	private void setUnitPropertiesXML(Element root) {
404
		try {
405
			NodeList group;
406

    
407
			// try{afficherInfos(racine, 0);}catch (Exception e)
408
			// {logger.info(e);}
409
			group = root.getChildNodes();
410
			// logger.info("prefix et ident : "+prefix+"Identifications");
411
			// logger.info("ABCD ELEMENT not stored: "+group.item(i).getNodeName().toString()+" - value: "+group.item(i).getTextContent());
412
			for (int i = 0; i < group.getLength(); i++) {
413
				if (group.item(i).getNodeName()
414
						.equals(prefix + "Identifications")) {
415
					group = group.item(i).getChildNodes();
416
					break;
417
				}
418
			}
419
			dataHolder.identificationList = new ArrayList<String>();
420
			dataHolder.statusList = new ArrayList<SpecimenTypeDesignationStatus>();
421
			dataHolder.atomisedIdentificationList = new ArrayList<HashMap<String, String>>();
422
			dataHolder.referenceList = new ArrayList<String>();
423
			dataHolder.multimediaObjects = new ArrayList<String>();
424

    
425
			abcdFileGetter.getScientificNames(group);
426
			abcdFileGetter.getType(root);
427

    
428
			// logger.info("this.identificationList "+this.identificationList.toString());
429
			abcdFileGetter.getIDs(root);
430
			abcdFileGetter.getRecordBasis(root);
431
			abcdFileGetter.getMultimedia(root);
432
			abcdFileGetter.getNumbers(root);
433
			abcdFileGetter.getGeolocation(root);
434
			abcdFileGetter.getGatheringPeople(root);
435
			boolean referencefound = abcdFileGetter.getReferences(root);
436
			if (!referencefound) {
437
				dataHolder.referenceList.add(ref.getTitleCache());
438
			}
439

    
440
		} catch (Exception e) {
441
			logger.info("Error occured while parsing XML file" + e);
442
		}
443
	}
444

    
445
	private Institution getInstitution(String institutionCode,
446
			Abcd206ImportConfigurator config) {
447
		Institution institution;
448
		List<Institution> institutions;
449
		try {
450
			// logger.info(dataHolder.institutionCode);
451
			institutions = getAgentService().searchInstitutionByCode(
452
					dataHolder.institutionCode);
453
		} catch (Exception e) {
454
			institutions = new ArrayList<Institution>();
455
		}
456
		if (institutions.size() == 0 || !config.isReUseExistingMetadata()) {
457
			// logger.info("Institution (agent) unknown or not allowed to reuse existing metadata");
458
			// create institution
459
			institution = Institution.NewInstance();
460
			institution.setCode(dataHolder.institutionCode);
461
		} else {
462
			// logger.info("Institution (agent) already in the db");
463
			institution = institutions.get(0);
464
		}
465
		// logger.info("getinstitution " + institution.toString());
466
		return institution;
467
	}
468

    
469
	/*
470
	 * Look if the Collection does already exists
471
	 * 
472
	 * @param collectionCode: a string
473
	 * 
474
	 * @param institution: the current Institution
475
	 * 
476
	 * @param app
477
	 * 
478
	 * @return the Collection (existing or new)
479
	 */
480
	private Collection getCollection(String collectionCode,
481
			Institution institution, Abcd206ImportConfigurator config) {
482
		Collection collection = Collection.NewInstance();
483
		List<Collection> collections;
484
		try {
485
			collections = getCollectionService().searchByCode(
486
					dataHolder.collectionCode);
487
		} catch (Exception e) {
488
			collections = new ArrayList<Collection>();
489
		}
490
		if (collections.size() == 0 || !config.isReUseExistingMetadata()) {
491
			// logger.info("Collection not found or do not reuse existing metadata  "
492
			//		+ dataHolder.collectionCode);
493
			// create new collection
494
			collection.setCode(dataHolder.collectionCode);
495
			collection.setCodeStandard("GBIF");
496
			collection.setInstitute(institution);
497
		} else {
498
			boolean collectionFound = false;
499
			for (int i = 0; i < collections.size(); i++) {
500
				collection = collections.get(i);
501
				try {
502
					if (collection.getInstitute().getCode()
503
							.equalsIgnoreCase(institution.getCode())) {
504
						// found a collection with the same code and the same
505
						// institution
506
						collectionFound = true;
507
						break;
508
					}
509
				} catch (NullPointerException e) {
510
				}
511
			}
512
			if (!collectionFound) {
513
				collection.setCode(dataHolder.collectionCode);
514
				collection.setCodeStandard("GBIF");
515
				collection.setInstitute(institution);
516
			}
517

    
518
		}
519
		return collection;
520
	}
521

    
522
	/**
523
	 * join DeterminationEvent to the Taxon Object
524
	 * 
525
	 * @param taxon
526
	 *            : current Taxon Object
527
	 * @param preferredFlag
528
	 *            : preferred name, boolean
529
	 * @param config
530
	 *            : current ABCD Import configurator
531
	 */
532

    
533
	private void linkDeterminationEvent(Taxon taxon, boolean preferredFlag,
534
			Abcd206ImportConfigurator config, 
535
			DerivedUnitFacade derivedFacade) {
536
		// logger.info("start linkdetermination with taxon:" + taxon.getUuid()+", "+taxon);
537

    
538
		refreshTransaction();
539

    
540

    
541
		try {
542
			taxon = (Taxon) getTaxonService().find(taxon.getUuid());
543
		} catch (Exception e) {
544
			// logger.info("taxon uptodate");
545
		}
546

    
547
		DeterminationEvent determinationEvent = DeterminationEvent.NewInstance();
548
		determinationEvent.setTaxon(taxon);
549
		determinationEvent.setPreferredFlag(preferredFlag);
550
		
551
		determinationEvent.setIdentifiedUnit(derivedUnitBase);
552

    
553
		derivedUnitBase.addDetermination(determinationEvent);
554
		refreshTransaction();
555
		////		
556
		//		Set<DerivationEvent> dset = derivedUnitBase.getDeterminations();
557
		//		logger.info("dset: "+dset);
558

    
559
		try {
560
			// logger.info("NB TYPES INFO: "+ dataHolder.statusList.size());
561
			for (SpecimenTypeDesignationStatus specimenTypeDesignationstatus : dataHolder.statusList) {
562
				if (specimenTypeDesignationstatus != null) {
563
					// logger.info("specimenTypeDesignationstatus :"+ specimenTypeDesignationstatus);
564
					try {
565
						taxon = (Taxon) getTaxonService().find(taxon.getUuid());
566
						
567
					} catch (Exception e) {
568
						// logger.info("taxon uptodate");
569
					}
570
					specimenTypeDesignationstatus = (SpecimenTypeDesignationStatus) getTermService().find(specimenTypeDesignationstatus.getUuid());
571
					//Designation
572
					TaxonNameBase<?,?> name = taxon.getName();
573
					SpecimenTypeDesignation designation = SpecimenTypeDesignation.NewInstance();
574
					
575
					designation.setTypeStatus(specimenTypeDesignationstatus);
576
					designation.setTypeSpecimen(derivedUnitBase);
577
					name.addTypeDesignation(designation, true);
578
					refreshTransaction();
579

    
580
				}
581
			}
582
		} catch (Exception e) {
583
			logger.warn("PB addding SpecimenType " + e);
584
		}
585

    
586
		for (String strReference : dataHolder.referenceList) {
587
			Reference<?> reference = ReferenceFactory.newGeneric();
588
			reference.setTitleCache(strReference, true);
589
            getReferenceService().saveOrUpdate(reference);
590

    
591
			determinationEvent.addReference(reference);
592
		}
593

    
594
        getOccurrenceService().saveOrUpdate(derivedUnitBase);
595
		refreshTransaction();
596

    
597

    
598
		if (config.isDoCreateIndividualsAssociations()) {
599
			// logger.info("isDoCreateIndividualsAssociations");
600

    
601
			// TaxonDescription taxonDescription = null;
602
			if (config.isDoMatchToExistingDescription()) {
603
				logger.warn("The import option 'DoMatchToExistingDescription' is not yet implemented.");
604
			} else {
605
				// UUID taxonDescriptionUUID =
606
				// config.getTaxonToDescriptionMap().get(taxon.getUuid()); //
607
				// rather
608
				// logger.info("UUID taxondescription "+taxonDescriptionUUID);
609
				// if (taxonDescriptionUUID != null) {
610
				// try{
611
				// taxonDescription = (TaxonDescription)
612
				// getDescriptionService().load(taxonDescriptionUUID);
613
				// }catch(Exception
614
				// e){logger.warn("BLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
615
				// taxonDescription = TaxonDescription.NewInstance(taxon);
616
				// }
617
				// }
618
				// if (taxonDescription == null) {
619
				// taxonDescription = TaxonDescription.NewInstance(taxon);
620
				// config.getTaxonToDescriptionMap().put(taxon.getUuid(),taxonDescription.getUuid());
621
				//
622
				// // taxonDescriptionUUID = config.getTaxonToDescriptionMap()
623
				// .get(taxon.getUuid());
624
				// }
625

    
626
				/*
627
				 * Set<TaxonDescription> tds = taxon.getDescriptions();
628
				 * TaxonDescription td = null; if (tds.size() >0) { td=
629
				 * tds.iterator().next(); taxonDescription =
630
				 * CdmBase.deproxy(td,TaxonDescription.class); }
631
				 * 
632
				 * if (taxonDescription == null){ // taxonDescription =
633
				 * TaxonDescription.NewInstance(); //
634
				 * logger.info("taxondescr "+taxonDescription.getUuid()); //
635
				 * //taxonDescription.setTaxon(taxon);
636
				 * //taxon.addDescription(taxonDescription);
637
				 * //getTaxonService().merge(taxon);
638
				 * 
639
				 * /*}
640
				 */
641
				// taxonDescription.setTaxon(taxon);
642
				// }
643
			}
644

    
645
			makeIndividualsAssociation(taxon, determinationEvent);
646

    
647
		}
648
	}
649

    
650
	private void makeIndividualsAssociation(Taxon taxon, DeterminationEvent determinationEvent) {
651

    
652
		TaxonDescription taxonDescription = TaxonDescription.NewInstance();
653
		taxonDescription.setTitleCache(ref.getTitleCache(), true);
654

    
655
		getDescriptionService().saveOrUpdate(taxonDescription);
656

    
657
		refreshTransaction();
658

    
659
		try{taxon = (Taxon) getTaxonService().find(taxon.getUuid());
660
		}catch(Exception e){
661
			//logger.info("taxon uptodate");
662
			}
663

    
664
		taxonDescription = (TaxonDescription) getDescriptionService().find(taxonDescription.getUuid());
665
		taxon.addDescription(taxonDescription);
666

    
667
		IndividualsAssociation indAssociation = IndividualsAssociation.NewInstance();
668
		Feature feature = makeFeature(derivedUnitBase);
669
		indAssociation.setAssociatedSpecimenOrObservation(derivedUnitBase);
670
		indAssociation.setFeature(feature);
671

    
672
		for (Reference<?> citation : determinationEvent.getReferences()) {
673
			indAssociation.addSource(DescriptionElementSource.NewInstance(null,
674
					null, citation, null));
675
		}
676

    
677
		taxonDescription.addElement(indAssociation);
678

    
679
		getDescriptionService().saveOrUpdate(taxonDescription);
680

    
681
		getTaxonService().saveOrUpdate(taxon);
682
	}
683

    
684
	private Feature makeFeature(SpecimenOrObservationBase unit) {
685
		if (unit.isInstanceOf(DerivedUnit.class)) {
686
			return Feature.INDIVIDUALS_ASSOCIATION();
687
		} else if (unit.isInstanceOf(FieldObservation.class)
688
				|| unit.isInstanceOf(Observation.class)) {
689
			return Feature.OBSERVATION();
690
		} else if (unit.isInstanceOf(Fossil.class)
691
				|| unit.isInstanceOf(LivingBeing.class)
692
				|| unit.isInstanceOf(Specimen.class)) {
693
			return Feature.SPECIMEN();
694
		}
695
		logger.warn("No feature defined for derived unit class: "
696
				+ unit.getClass().getSimpleName());
697
		return null;
698
	}
699

    
700
	private void refreshTransaction(){
701
		commitTransaction(tx);
702
		tx = startTransaction();
703
		ref = getReferenceService().find(ref.getUuid());
704
		classification = getClassificationService().find(classification.getUuid());
705
		try{
706
			derivedUnitBase = (DerivedUnitBase) getOccurrenceService().find(derivedUnitBase.getUuid());
707
		}catch(Exception e){
708
			//logger.warn("derivedunit up to date or not created yet");
709
			}
710
	}
711

    
712
	/**
713
	 * getParentTaxon : get the taxonomic hierarchy for the current Taxon
714
	 * 
715
	 * @param taxon
716
	 * @param taxonName
717
	 * @param originalName
718
	 * @param config
719
	 * @return a map with the parenttaxon and the parenttaxonname
720
	 */
721
	private HashMap<Taxon, NonViralName<?>> getParentTaxon(Taxon taxon,
722
			NonViralName<?> taxonName, NonViralName<?> originalName,
723
			Abcd206ImportConfigurator config) {
724

    
725
		Taxon parenttaxon = null;
726
		NonViralName<?> parentName = null;
727
		List<TaxonBase> c = null;
728

    
729
		List<String> highername = new ArrayList<String>();
730
		Rank higherrank = null;
731
		Rank taxonrank = taxonName.getRank();
732

    
733
		// logger.info("getParentTaxon childname " + taxonName.getFullTitleCache()
734
		//		+ ", rank " + taxonrank + ", originalname "
735
		//		+ originalName.getFullTitleCache());
736

    
737
		HashMap<Taxon, NonViralName<?>> map = new HashMap<Taxon, NonViralName<?>>();
738

    
739

    
740
		refreshTransaction();
741

    
742
		taxon = (Taxon) getTaxonService().find(taxon.getUuid());
743

    
744
		if (taxonrank.isGenus()) {
745
			// to change and add test DoReusetaxa
746
			for (TaxonNode p : classification.getAllNodes()) {
747
				// logger.info("p UUID "+p.getUuid().toString());
748
				if (classification.getTopmostNode(p.getTaxon()) == null) {
749
					// logger.info("taxon1 "+p.getTaxon().getTitleCache());
750
					// logger.info("taxon2 "+taxon.getTitleCache());
751
					if (taxon.getTitleCache().contains(p.getTaxon().getTitleCache().split("sec. " + ref)[0])) {
752
						this.addParentChild(p.getTaxon(), taxon);
753

    
754
						refreshTransaction();
755
						taxon = (Taxon) getTaxonService().find(taxon.getUuid());
756

    
757
						break;
758
					}
759
				}// else
760
				// logger.info("getTopMostNode "+classification.getTopmostNode(p.getTaxon()));
761
			}
762
			// add the genus to the root of the classification
763
			TaxonNode p = this.addChildTaxon(taxon);
764
			this.addChildNode(p);
765

    
766
			refreshTransaction();
767

    
768
			taxon = (Taxon) getTaxonService().find(taxon.getUuid());
769

    
770
			return map;
771
		}
772

    
773
		if (taxonrank.isInfraGeneric()) {
774
			// logger.info("isInfrageneric");
775
			highername.add(originalName.getGenusOrUninomial());
776
			higherrank = Rank.GENUS();
777
		}
778

    
779
		if (taxonrank.isSpecies()) {
780
			// logger.info("isSpecies");
781
			if (originalName.getGenusOrUninomial() != null) {
782
				highername.add(originalName.getGenusOrUninomial());
783
				higherrank = Rank.GENUS();
784
			} else {
785
				highername.add(originalName.getFullTitleCache().trim()
786
						.split(" ")[0]);
787
				higherrank = Rank.GENUS();
788
			}
789
			if (originalName.getInfraGenericEpithet() != null) {
790
				highername.add(originalName.getInfraGenericEpithet());
791
				higherrank = Rank.INFRAGENUS();
792
			}
793
		}
794

    
795
		if (taxonrank.isInfraSpecific()) {
796
			// logger.info("isInfraSpecies");
797
			if (originalName.getGenusOrUninomial() != null)
798
				highername.add(originalName.getGenusOrUninomial());
799
			if (originalName.getInfraGenericEpithet() != null) {
800
				highername.add(originalName.getInfraGenericEpithet());
801
			}
802
			if (originalName.getSpecificEpithet() != null)
803
				highername.add(originalName.getSpecificEpithet());
804
			higherrank = Rank.SPECIES();
805
		}
806

    
807
		String highernamestr = StringUtils.join(highername.iterator(), " ")
808
				.split("sec. " + ref.getTitleCache())[0].trim();
809
		// logger.info("higherNamest :: " + highernamestr);
810
		if (config.isDoReUseTaxon() && highername != null
811
				&& highername.size() > 0 && highernamestr != "") {
812
			boolean parentFound = false;
813
			try {
814
				c = getTaxonService().searchTaxaByName(highernamestr, ref);
815

    
816
				for (TaxonBase b : c) {
817
					parenttaxon = (Taxon) b;
818
					Iterator it = parenttaxon.getTaxonNodes().iterator();
819
					// logger.warn("ICI2");
820
					while (it.hasNext()) {
821
						TaxonNode tmpNode = (TaxonNode) it.next();
822
						Taxon tmp = tmpNode.getTaxon();
823
						if (tmp.getTitleCache().split(
824
								"sec. " + ref.getTitleCache())[0].trim()
825
								.equalsIgnoreCase(highernamestr)) {
826
							parenttaxon = tmp;
827
							parentName = (NonViralName<?>) b.getName();
828
							parentFound = true;
829
						}
830
					}
831
//					if (!parentFound)
832
//						logger.info("parent pas trouvé");
833
//					else
834
//						logger.info("parent trouvé "
835
//								+ parenttaxon.getTitleCache());
836

    
837
				}
838
			} catch (Exception e) {
839
				logger.info("Problem while trying to reuse existing taxon" + e);
840
				parenttaxon = null;
841
			}
842
			if (!parentFound)
843
				parenttaxon = null;
844
		}
845

    
846
		if ((parenttaxon == null && highername != null && highername.size() > 0 && highernamestr != "")
847
				|| !config.isDoReUseTaxon()) {
848
			// logger.info("ICI BIS");
849
			parentName = NonViralName.NewInstance(null);
850
			parentName.setFullTitleCache(highernamestr);
851
			parentName.setNameCache(highernamestr);
852
			parentName.setRank(higherrank);
853
			if (higherrank == Rank.GENUS())
854
				parentName.setGenusOrUninomial(highernamestr.split(" ")[0]);
855

    
856
			getNameService().save(parentName);
857
			parenttaxon = Taxon.NewInstance(parentName, ref);
858
			getTaxonService().save(parenttaxon);
859

    
860
		}
861

    
862
		map.put(parenttaxon, parentName);
863
		return map;
864
		// return parenttaxon;
865
	}
866

    
867
	/**
868
	 * add the ParenTaxon to the current Classification, link it with the
869
	 * "child" taxon
870
	 * 
871
	 * @param child
872
	 * @param childName
873
	 * @param config
874
	 * @return the current child that was set as inputparameter (needed??)
875
	 */
876
	private Taxon addParentTaxon(Taxon child, NonViralName<?> childName,
877
			Abcd206ImportConfigurator config) {
878

    
879
		refreshTransaction();
880

    
881
		NonViralName<?> originalName = childName;
882
		HashMap<Taxon, Taxon> map = new HashMap<Taxon, Taxon>();
883
		HashMap<Taxon, NonViralName<?>> maptn = new HashMap<Taxon, NonViralName<?>>();
884

    
885
		HashMap<Taxon, NonViralName<?>> tmpmaptn = getParentTaxon(child,
886
				childName, originalName, config);
887

    
888
		Taxon tmpparent = (Taxon) getTaxonService().find(
889
				tmpmaptn.keySet().iterator().next().getUuid());
890
		child = (Taxon) getTaxonService().find(child.getUuid());
891
		NonViralName<?> parentname = tmpmaptn.get(tmpparent);
892

    
893
		map.put(tmpparent, child);
894
		maptn.put(child, childName);
895
		maptn.put(tmpparent, parentname);
896

    
897
		while (!tmpparent.getTitleCache().split("sec. " + ref.getTitleCache())[0]
898
				.trim().equalsIgnoreCase(
899
						child.getTitleCache().trim()
900
						.split("sec. " + ref.getTitleCache())[0])
901
						&& childName != null && tmpmaptn.keySet().size() > 0) {
902
			// logger.info("tmpparent.getTitleCache()  "
903
			//		+ tmpparent.getTitleCache());
904
			// logger.info("child.getTitleCache() " + child.getTitleCache());
905
			child = (Taxon) getTaxonService().find(tmpparent.getUuid());
906
			childName = maptn.get(child);
907
			// if (childName == null) {
908
			// logger.warn("OUPS " + tmpparent.getTitleCache());
909
			// }
910
			if (childName != null) {
911
				tmpmaptn = getParentTaxon(child, childName, originalName,
912
						config);
913
				try {
914
					if (tmpmaptn.keySet().size() > 0) {
915
						tmpparent = (Taxon) getTaxonService().find(
916
								tmpmaptn.keySet().iterator().next().getUuid());
917
						parentname = tmpmaptn.get(tmpparent);
918

    
919
						map.put(tmpparent, child);
920
						maptn.put(tmpparent, parentname);
921

    
922
						for (Taxon elt : map.keySet()) {
923
							NonViralName<?> t = maptn.get(elt);
924
							if (parentname.getRank() == Rank.GENUS())
925
								t.setGenusOrUninomial(parentname
926
										.getTitleCache());
927
							if (parentname.getRank() == Rank.SPECIES())
928
								t.setSpecificEpithet(parentname.getTitleCache());
929
							maptn.remove(elt);
930
							maptn.put(elt, t);
931
						}
932

    
933
					}
934

    
935
				} catch (Exception e) {
936
					logger.warn("ohooooooooooooooooooooooooooooooooooooooo "
937
							+ e);
938
				}
939
			}
940

    
941
		}
942

    
943
		// last child == higher rank found
944
		tmpparent = child;
945

    
946
		refreshTransaction();
947

    
948
		tmpparent = (Taxon) getTaxonService().find(tmpparent.getUuid());
949

    
950
		for (TaxonNode p : classification.getAllNodes()) {
951
			// logger.warn("ICI3");
952
			// logger.warn("ptmpparent UUID "+p.getUuid().toString());
953
			if (classification.getTopmostNode(p.getTaxon()) == null) {
954
				if (tmpparent.getTitleCache().contains(p.getTaxon().getTitleCache().split("sec. " + ref)[0])) {
955
					tmpparent = (Taxon) getTaxonService().find(p.getTaxon().getUuid());
956
					this.addParentChild(tmpparent, null);
957
					map.put(tmpparent, child);
958
					break;
959
				}
960
			}
961
		}
962

    
963
		ArrayList<Taxon> taxondone = new ArrayList<Taxon>();
964
		taxondone.add(tmpparent);
965

    
966
		refreshTransaction();
967

    
968
		TaxonNode childNode =null;
969
		while (taxondone.size() < map.size() + 1) {
970
			boolean exists = false;
971
			boolean childadded = false;
972
			tmpparent = (Taxon) getTaxonService().find(tmpparent.getUuid());
973
			child = (Taxon) getTaxonService().find(map.get(tmpparent).getUuid());
974

    
975

    
976
			if(child.getTaxonNodes().size()==0){
977
				childNode = this.addChildTaxon(child);
978
				this.addChildNode(childNode);
979
				childadded = true;
980
			}
981

    
982
			if (childadded)
983
				refreshTransaction();
984
			//			
985
			tmpparent = (Taxon) getTaxonService().find(tmpparent.getUuid());
986
			child = (Taxon) getTaxonService().find(map.get(tmpparent).getUuid());
987

    
988
			Set<TaxonNode> childnodes = classification.getChildNodes();
989

    
990
			List<TaxonNode> myList = new CopyOnWriteArrayList<TaxonNode>();
991
			for (TaxonNode n :childnodes){
992
				myList.add(n);
993
			}
994
			Iterator it = myList.iterator();
995
			while (it.hasNext()){
996
				TaxonNode tn2 = getTaxonNodeService().find(((TaxonNode) it.next()).getUuid());
997
				Taxon t2 = (Taxon) getTaxonService().find(tn2.getTaxon().getUuid());
998

    
999
				if (t2.getUuid().equals(tmpparent.getUuid())){
1000
					if (tmpparent.getTaxonNodes().size()==0){
1001
						//						logger.warn("A");
1002
						this.addParentChild(t2,getTaxonNodeService().find(childNode.getUuid()).getTaxon());
1003
					}
1004
					else{
1005
						//						logger.warn("B");
1006
						TaxonNode tn = getTaxonNodeService().find(child.getTaxonNodes().iterator().next().getUuid());
1007
						TaxonNode node = this.addChildNode(tn);
1008
//						logger.warn("LAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"+tn.getTaxon());
1009
						this.addParentChild(t2,node.getTaxon());
1010

    
1011
					}
1012
					exists=true;
1013
				}
1014
			}
1015
			refreshTransaction();
1016

    
1017
			try {
1018
				if (tmpparent != child && !exists) {
1019
					this.addParentChild(tmpparent, child);
1020
				}
1021
				tmpparent = child;
1022
				taxondone.add(child);
1023
			} catch (Exception e) {
1024
				logger.warn("PB :" + e);
1025
				logger.warn("tmpparent " + tmpparent);
1026
				logger.warn("child " + child);
1027
				System.exit(0);
1028
			}
1029
		}
1030

    
1031
		refreshTransaction();
1032
		return child;
1033
	}
1034

    
1035
	private TaxonNode addChildNode(TaxonNode childNode){
1036
		TaxonNode re =null;
1037
		boolean exists=false;
1038
		if (abcdstate.getConfig().isDoReUseTaxon()){
1039
			Taxon taxon = childNode.getTaxon();
1040
			Set<TaxonNode> allNodes = classification.getAllNodes();
1041
			Taxon tmp;
1042
			if (allNodes.size()>0)
1043
				for (TaxonNode tn:allNodes){
1044
					tmp = tn.getTaxon();
1045
					if (tmp.equals(taxon)){
1046
						re= tn;
1047
						exists=true;
1048
						break;
1049
					}
1050
				}
1051
		}
1052
		if(!abcdstate.getConfig().isDoReUseTaxon() || !exists){
1053
			refreshTransaction();
1054
			childNode = getTaxonNodeService().find(childNode.getUuid());
1055
			re= classification.addChildNode(childNode, ref, "", null);
1056
		}
1057
		return re;
1058
	}
1059

    
1060
	private void addParentChild(Taxon parent, Taxon child){
1061
		//logger.info("ADDPARENTCHILD");
1062
		boolean exists = false;
1063
		Taxon taxonFromHiber = null;
1064
		if (abcdstate.getConfig().isDoReUseTaxon()){
1065
			Set<TaxonNode> allNodes = classification.getAllNodes();	
1066
			Taxon tmp;
1067
			if (allNodes.size()>0)
1068
				for (TaxonNode tn:allNodes){
1069
					tmp = tn.getTaxon();
1070
					if (tmp.equals(parent)){
1071
						taxonFromHiber = tmp;
1072
					}
1073
				}
1074
			if (taxonFromHiber != null){
1075
				Set<TaxonNode> children = taxonFromHiber.getTaxonNodes();
1076
				if (children.size()>0)
1077
					for (TaxonNode cn:children){
1078
						Taxon tmpt = cn.getTaxon();
1079
						if (tmpt.equals(child))
1080
							exists=true;
1081
					}
1082
			}
1083
		}
1084
		if (!abcdstate.getConfig().isDoReUseTaxon() || !exists){
1085
			refreshTransaction();
1086
			parent = (Taxon) getTaxonService().find(parent.getUuid());
1087
			child = (Taxon) getTaxonService().find(child.getUuid());
1088
			classification.addParentChild(parent,child, ref, null);
1089
		}
1090
	}
1091

    
1092
	private TaxonNode addChildTaxon(Taxon child){
1093
		TaxonNode re =null;
1094
		boolean exists=false;
1095
		if (abcdstate.getConfig().isDoReUseTaxon()){
1096
			Set<TaxonNode> allNodes = classification.getAllNodes();	
1097
			Taxon tmp;
1098
			if (allNodes.size()>0)
1099
				for (TaxonNode tn:allNodes){
1100
					tmp = tn.getTaxon();
1101
					if (tmp.equals(child)){
1102
						re= tn;
1103
						exists=true;
1104
						break;
1105
					}
1106
				}
1107
		}
1108
		if(!abcdstate.getConfig().isDoReUseTaxon() || !exists){
1109
			refreshTransaction();
1110
			child = (Taxon) getTaxonService().find(child.getUuid());
1111
			re= classification.addChildTaxon(child, ref, "", null);
1112
		}
1113
		return re;
1114
	}
1115

    
1116
	/**
1117
	 * getTaxon : search for an existing taxon in the database, for the same
1118
	 * reference
1119
	 * 
1120
	 * @param config
1121
	 * @param scientificName
1122
	 * @param taxonName
1123
	 * @return
1124
	 */
1125
	private Taxon getTaxon(Abcd206ImportConfigurator config,
1126
			String scientificName, NonViralName taxonName) {
1127
		Taxon taxon = null;
1128
		List<TaxonBase> c = null;
1129

    
1130
		if (config.isDoMatchTaxa()) {
1131
			taxon = getTaxonService().findBestMatchingTaxon(scientificName);
1132
		}
1133

    
1134
		if (taxon == null && config.isDoReUseTaxon()) {
1135
			try {
1136
				c = getTaxonService().searchTaxaByName(scientificName, ref);
1137
				for (TaxonBase b : c) {
1138
					taxon = (Taxon) b;
1139
				}
1140
			} catch (Exception e) {
1141
				logger.info("does not work here either " + e);
1142
				taxon = null;
1143
			}
1144
		} else {
1145
			//logger.info("Matching to existing Taxon : " + taxon.getTitleCache());
1146
		}
1147

    
1148
		if (!config.isDoReUseTaxon() && taxon == null) {
1149
			getNameService().saveOrUpdate(taxonName);
1150
			taxon = Taxon.NewInstance(taxonName, ref);
1151
			getTaxonService().save(taxon);
1152
		}
1153
		if (taxon == null) {
1154
			getNameService().saveOrUpdate(taxonName);
1155
			taxon = Taxon.NewInstance(taxonName, ref);
1156
			getTaxonService().save(taxon);
1157

    
1158
		}
1159
//		logger.info("getTaxonService : "
1160
//				+ getTaxonService().find(taxon.getUuid()));
1161
		return (Taxon) getTaxonService().find(taxon.getUuid());
1162
		// return taxonFromUUID()
1163
	}
1164

    
1165
	/**
1166
	 * HandleIdentifications : get the scientific names present in the ABCD
1167
	 * document and store link them with the observation/specimen data
1168
	 * 
1169
	 * @param config
1170
	 */
1171
	private void handleIdentifications(Abcd206ImportConfigurator config,
1172
			DerivedUnitFacade derivedUnitFacade) {
1173

    
1174
		// commitTransaction(tx);
1175
		// tx =startTransaction();
1176

    
1177
		String fullScientificNameString;
1178
		Taxon taxon = null;
1179
		NonViralName<?> taxonName = null;
1180
		Rank.GENUS();
1181
		Rank.FAMILY();
1182

    
1183
		new HashMap<String, Taxon>();
1184
		HashMap<Integer, Taxon> preferredtaxontoinsert = new HashMap<Integer, Taxon>();
1185
		HashMap<Integer, NonViralName<?>> preferredtaxonnametoinsert = new HashMap<Integer, NonViralName<?>>();
1186
		HashMap<Integer, Taxon> taxontoinsert = new HashMap<Integer, Taxon>();
1187
		HashMap<Integer, NonViralName<?>> taxonnametoinsert = new HashMap<Integer, NonViralName<?>>();
1188

    
1189
		String scientificName = "";
1190
		boolean preferredFlag = false;
1191
		boolean onepreferred = false;
1192

    
1193
		if (dataHolder.nomenclatureCode == "")
1194
			dataHolder.nomenclatureCode = config.getNomenclaturalCode()
1195
			.toString();
1196

    
1197
		for (int i = 0; i < dataHolder.identificationList.size(); i++) {
1198

    
1199
			fullScientificNameString = dataHolder.identificationList.get(i);
1200
			fullScientificNameString = fullScientificNameString.replaceAll(
1201
					" et ", " & ");
1202

    
1203
			if (fullScientificNameString.indexOf("_preferred_") != -1) {
1204
				scientificName = fullScientificNameString.split("_preferred_")[0];
1205
				String pTmp = fullScientificNameString.split("_preferred_")[1]
1206
						.split("_code_")[0];
1207
				if (pTmp.equals("1")
1208
						|| pTmp.toLowerCase().indexOf("true") != -1) {
1209
					preferredFlag = true;
1210
					onepreferred = true;
1211
				} else {
1212
					preferredFlag = false;
1213
				}
1214
			} else {
1215
				scientificName = fullScientificNameString;
1216
			}
1217

    
1218
			// logger.info("fullscientificname " + fullScientificNameString
1219
			// + ", *" + dataHolder.nomenclatureCode + "*");
1220

    
1221
			if (fullScientificNameString.indexOf("_code_") != -1) {
1222
				if (fullScientificNameString.indexOf(':') != -1) {
1223
					dataHolder.nomenclatureCode = fullScientificNameString
1224
							.split("_code_")[1].split(":")[1];
1225
				} else
1226
					dataHolder.nomenclatureCode = fullScientificNameString
1227
					.split("_code_")[1];
1228
			}
1229

    
1230
			if (config.isDoAutomaticParsing()
1231
					|| dataHolder.atomisedIdentificationList == null
1232
					|| dataHolder.atomisedIdentificationList.size() == 0) {
1233
				taxonName = parseScientificName(scientificName);
1234
				if (taxonName == null)
1235
					taxonName = setTaxonNameByType(
1236
							dataHolder.atomisedIdentificationList.get(i),
1237
							scientificName);
1238
			} else {
1239
				if (dataHolder.atomisedIdentificationList != null
1240
						|| dataHolder.atomisedIdentificationList.size() > 0) {
1241
					taxonName = setTaxonNameByType(
1242
							dataHolder.atomisedIdentificationList.get(i),
1243
							scientificName);
1244
				}
1245
			}
1246

    
1247
			getNameService().saveOrUpdate(taxonName);
1248

    
1249
			taxon = getTaxon(config, scientificName, taxonName);
1250

    
1251
			if (preferredFlag) {
1252
				preferredtaxonnametoinsert.put(i, taxonName);
1253
				preferredtaxontoinsert.put(i, taxon);
1254
			} else {
1255
				taxonnametoinsert.put(i, taxonName);
1256
				taxontoinsert.put(i, taxon);
1257
			}
1258
		}
1259

    
1260
		Iterator entries = preferredtaxontoinsert.keySet().iterator();
1261
		while (entries.hasNext()) {
1262

    
1263
			int a = (Integer) entries.next();
1264
//			logger.info("\n PREFERRED num." + a + " \n");
1265
			taxonName = preferredtaxonnametoinsert.get(a);
1266
			taxon = preferredtaxontoinsert.get(a);
1267

    
1268

    
1269
			taxon = addParentTaxon(taxon, taxonName, config);
1270
			refreshTransaction();
1271

    
1272
			taxon = (Taxon) getTaxonService().find(taxon.getUuid());
1273

    
1274
			linkDeterminationEvent(taxon, true, config,
1275
					derivedUnitFacade);
1276
		}
1277

    
1278
		if (onepreferred) {
1279
			entries = taxontoinsert.keySet().iterator();
1280

    
1281
			while (entries.hasNext()) {
1282
				int a = (Integer) entries.next();
1283
//				logger.info("\n ADD non preferred " + a + " \n");
1284
				// taxonName = taxonnametoinsert.get(a);
1285
				taxon = taxontoinsert.get(a);
1286
				// do not do addParentTaxon as the name is not the
1287
				// preferred/accepted one
1288
				// should not be displayed in the tree
1289
				// taxon = addParentTaxon(taxon, taxonName, config, true);
1290

    
1291
				// do linkdetermination as it should be linked to the specimen,
1292
				// though
1293
				refreshTransaction();
1294
				taxon = (Taxon) getTaxonService().find(taxon.getUuid());
1295

    
1296
				linkDeterminationEvent(taxon, false, config, 
1297
						derivedUnitFacade);
1298

    
1299
			}
1300

    
1301
		}
1302

    
1303
		else {// no preferred name, have to add everything to the classification
1304
			// logger.info("no preferred taxa");
1305
			entries = taxontoinsert.keySet().iterator();
1306

    
1307
			while (entries.hasNext()) {
1308
				int a = (Integer) entries.next();
1309
				// logger.info("\n NORMAL num." + a + " \n");
1310
				taxonName = taxonnametoinsert.get(a);
1311
				taxon = taxontoinsert.get(a);
1312

    
1313

    
1314
				taxon = addParentTaxon(taxon, taxonName, config);
1315
				taxon = (Taxon) getTaxonService().find(taxon.getUuid());
1316

    
1317
				refreshTransaction();
1318
				taxon = (Taxon) getTaxonService().find(taxon.getUuid());
1319

    
1320
				if (taxontoinsert.keySet().size() == 1)
1321
					linkDeterminationEvent(taxon, true, config,
1322
							derivedUnitFacade);
1323
				else
1324
					linkDeterminationEvent(taxon, false, config,
1325
							derivedUnitFacade);
1326

    
1327
			}
1328

    
1329
		}
1330

    
1331
	}
1332

    
1333
	private NonViralName<?> parseScientificName(String scientificName) {
1334
		NonViralNameParserImpl nvnpi = NonViralNameParserImpl.NewInstance();
1335
		NonViralName<?> taxonName = null;
1336
		boolean problem = false;
1337

    
1338
		// logger.info("parseScientificName "
1339
		//		+ dataHolder.nomenclatureCode.toString());
1340

    
1341
		if (dataHolder.nomenclatureCode.toString().equals("Zoological")
1342
				|| dataHolder.nomenclatureCode.toString().contains("ICZN")) {
1343
			taxonName = (ZoologicalName) nvnpi.parseFullName(scientificName,
1344
					NomenclaturalCode.ICZN, null);
1345
			if (taxonName.hasProblem()) {
1346
				problem = true;
1347
			}
1348
		}
1349
		if (dataHolder.nomenclatureCode.toString().equals("Botanical")
1350
				|| dataHolder.nomenclatureCode.toString().contains("ICBN")) {
1351
			taxonName = (BotanicalName) nvnpi.parseFullName(scientificName,
1352
					NomenclaturalCode.ICBN, null);
1353
			if (taxonName.hasProblem()) {
1354
				problem = true;
1355
			}
1356
		}
1357
		if (dataHolder.nomenclatureCode.toString().equals("Bacterial")
1358
				|| dataHolder.nomenclatureCode.toString().contains("ICBN")) {
1359
			taxonName = (BacterialName) nvnpi.parseFullName(scientificName,
1360
					NomenclaturalCode.ICNB, null);
1361
			if (taxonName.hasProblem()) {
1362
				problem = true;
1363
			}
1364
		}
1365
		if (dataHolder.nomenclatureCode.toString().equals("Cultivar")
1366
				|| dataHolder.nomenclatureCode.toString().contains("ICNCP")) {
1367
			taxonName = (CultivarPlantName) nvnpi.parseFullName(scientificName,
1368
					NomenclaturalCode.ICNCP, null);
1369
			if (taxonName.hasProblem()) {
1370
				problem = true;
1371
			}
1372
		}
1373
		if (problem) {
1374
			// logger.info("Parsing with problem in parseScientificName "
1375
			//		+ scientificName);
1376
			return null;
1377
		}
1378
		return taxonName;
1379

    
1380
	}
1381

    
1382
	private NonViralName<?> setTaxonNameByType(
1383
			HashMap<String, String> atomisedMap, String fullName) {
1384
		boolean problem = false;
1385
		// logger.info("settaxonnamebytype "
1386
		//		+ dataHolder.nomenclatureCode.toString());
1387

    
1388
		if (dataHolder.nomenclatureCode.equals("Zoological")) {
1389
			NonViralName<ZoologicalName> taxonName = ZoologicalName
1390
					.NewInstance(null);
1391
			taxonName.setFullTitleCache(fullName, true);
1392
			taxonName.setGenusOrUninomial(getFromMap(atomisedMap, "Genus"));
1393
			taxonName
1394
			.setInfraGenericEpithet(getFromMap(atomisedMap, "SubGenus"));
1395
			taxonName.setSpecificEpithet(getFromMap(atomisedMap,
1396
					"SpeciesEpithet"));
1397
			taxonName.setInfraSpecificEpithet(getFromMap(atomisedMap,
1398
					"SubspeciesEpithet"));
1399

    
1400
			if (taxonName.getGenusOrUninomial() != null)
1401
				taxonName.setRank(Rank.GENUS());
1402

    
1403
			if (taxonName.getInfraGenericEpithet() != null)
1404
				taxonName.setRank(Rank.SUBGENUS());
1405

    
1406
			if (taxonName.getSpecificEpithet() != null)
1407
				taxonName.setRank(Rank.SPECIES());
1408

    
1409
			if (taxonName.getInfraSpecificEpithet() != null)
1410
				taxonName.setRank(Rank.SUBSPECIES());
1411

    
1412
			Team team = null;
1413
			if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1414
				team = Team.NewInstance();
1415
				team.setTitleCache(
1416
						getFromMap(atomisedMap, "AuthorTeamParenthesis"), true);
1417
			} else {
1418
				if (getFromMap(atomisedMap, "AuthorTeamAndYear") != null) {
1419
					team = Team.NewInstance();
1420
					team.setTitleCache(
1421
							getFromMap(atomisedMap, "AuthorTeamAndYear"), true);
1422
				}
1423
			}
1424
			if (team != null) {
1425
				taxonName.setBasionymAuthorTeam(team);
1426
			} else {
1427
				if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1428
					taxonName.setAuthorshipCache(getFromMap(atomisedMap,
1429
							"AuthorTeamParenthesis"));
1430
				} else if (getFromMap(atomisedMap, "AuthorTeamAndYear") != null) {
1431
					taxonName.setAuthorshipCache(getFromMap(atomisedMap,
1432
							"AuthorTeamAndYear"));
1433
				}
1434
			}
1435
			if (getFromMap(atomisedMap, "CombinationAuthorTeamAndYear") != null) {
1436
				team = Team.NewInstance();
1437
				team.setTitleCache(
1438
						getFromMap(atomisedMap, "CombinationAuthorTeamAndYear"),
1439
						true);
1440
				taxonName.setCombinationAuthorTeam(team);
1441
			}
1442
			if (taxonName.hasProblem()) {
1443
				logger.info("pb ICZN");
1444
				problem = true;
1445
			} else {
1446
				return taxonName;
1447
			}
1448
		}
1449
		if (dataHolder.nomenclatureCode.equals("Botanical")) {
1450
			NonViralName<BotanicalName> taxonName = BotanicalName
1451
					.NewInstance(null);
1452
			taxonName.setFullTitleCache(fullName, true);
1453
			taxonName.setGenusOrUninomial(getFromMap(atomisedMap, "Genus"));
1454
			taxonName.setInfraGenericEpithet(getFromMap(atomisedMap,
1455
					"FirstEpithet"));
1456
			taxonName.setInfraSpecificEpithet(getFromMap(atomisedMap,
1457
					"InfraSpeEpithet"));
1458
			try {
1459
				taxonName.setRank(Rank.getRankByName(getFromMap(atomisedMap,
1460
						"Rank")));
1461
			} catch (Exception e) {
1462
				if (taxonName.getGenusOrUninomial() != null)
1463
					taxonName.setRank(Rank.GENUS());
1464

    
1465
				if (taxonName.getInfraGenericEpithet() != null)
1466
					taxonName.setRank(Rank.SUBGENUS());
1467

    
1468
				if (taxonName.getSpecificEpithet() != null)
1469
					taxonName.setRank(Rank.SPECIES());
1470

    
1471
				if (taxonName.getInfraSpecificEpithet() != null)
1472
					taxonName.setRank(Rank.SUBSPECIES());
1473
			}
1474
			Team team = null;
1475
			if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1476
				team = Team.NewInstance();
1477
				team.setTitleCache(
1478
						getFromMap(atomisedMap, "AuthorTeamParenthesis"), true);
1479
				if (team != null) {
1480
					taxonName.setBasionymAuthorTeam(team);
1481
				}
1482
			}
1483
			if (getFromMap(atomisedMap, "AuthorTeam") != null) {
1484
				team = Team.NewInstance();
1485
				team.setTitleCache(getFromMap(atomisedMap, "AuthorTeam"), true);
1486
				if (team != null) {
1487
					taxonName.setCombinationAuthorTeam(team);
1488
				}
1489
			}
1490
			if (team == null) {
1491
				if (getFromMap(atomisedMap, "AuthorTeamParenthesis") != null) {
1492
					taxonName.setAuthorshipCache(getFromMap(atomisedMap,
1493
							"AuthorTeamParenthesis"));
1494
				} else if (getFromMap(atomisedMap, "AuthorTeam") != null) {
1495
					taxonName.setAuthorshipCache(getFromMap(atomisedMap,
1496
							"AuthorTeam"));
1497
				}
1498
			}
1499
			if (getFromMap(atomisedMap, "CombinationAuthorTeamAndYear") != null) {
1500
				team = Team.NewInstance();
1501
				team.setTitleCache(
1502
						getFromMap(atomisedMap, "CombinationAuthorTeamAndYear"),
1503
						true);
1504
				taxonName.setCombinationAuthorTeam(team);
1505
			}
1506
			if (taxonName.hasProblem()) {
1507
				logger.info("pb ICBN");
1508
				problem = true;
1509
			} else {
1510
				return taxonName;
1511
			}
1512
		}
1513
		if (dataHolder.nomenclatureCode.equals("Bacterial")) {
1514
			NonViralName<BacterialName> taxonName = BacterialName
1515
					.NewInstance(null);
1516
			taxonName.setFullTitleCache(fullName, true);
1517
			taxonName.setGenusOrUninomial(getFromMap(atomisedMap, "Genus"));
1518
			taxonName
1519
			.setInfraGenericEpithet(getFromMap(atomisedMap, "SubGenus"));
1520
			taxonName.setSpecificEpithet(getFromMap(atomisedMap, "Species"));
1521
			taxonName.setInfraSpecificEpithet(getFromMap(atomisedMap,
1522
					"SubspeciesEpithet"));
1523

    
1524
			if (taxonName.getGenusOrUninomial() != null)
1525
				taxonName.setRank(Rank.GENUS());
1526

    
1527
			if (taxonName.getInfraGenericEpithet() != null)
1528
				taxonName.setRank(Rank.SUBGENUS());
1529

    
1530
			if (taxonName.getSpecificEpithet() != null)
1531
				taxonName.setRank(Rank.SPECIES());
1532

    
1533
			if (taxonName.getInfraSpecificEpithet() != null)
1534
				taxonName.setRank(Rank.SUBSPECIES());
1535

    
1536
			if (getFromMap(atomisedMap, "AuthorTeamAndYear") != null) {
1537
				Team team = Team.NewInstance();
1538
				team.setTitleCache(
1539
						getFromMap(atomisedMap, "AuthorTeamAndYear"), true);
1540
				taxonName.setCombinationAuthorTeam(team);
1541
			}
1542
			if (getFromMap(atomisedMap, "ParentheticalAuthorTeamAndYear") != null) {
1543
				Team team = Team.NewInstance();
1544
				team.setTitleCache(
1545
						getFromMap(atomisedMap,
1546
								"ParentheticalAuthorTeamAndYear"), true);
1547
				taxonName.setBasionymAuthorTeam(team);
1548
			}
1549
			if (taxonName.hasProblem()) {
1550
				logger.info("pb ICNB");
1551
				problem = true;
1552
			} else {
1553
				return taxonName;
1554
			}
1555
		}
1556
		if (dataHolder.nomenclatureCode.equals("Cultivar")) {
1557
			CultivarPlantName taxonName = CultivarPlantName.NewInstance(null);
1558

    
1559
			if (taxonName.hasProblem()) {
1560
				logger.info("pb ICNCP");
1561
				problem = true;
1562
			} else {
1563
				return taxonName;
1564
			}
1565
			return taxonName;
1566
		}
1567

    
1568
		if (problem) {
1569
			logger.info("Problem im setTaxonNameByType ");
1570
			NonViralName<?> taxonName = NonViralName.NewInstance(null);
1571
			taxonName.setFullTitleCache(fullName, true);
1572
			return taxonName;
1573
		}
1574
		NonViralName<?> tn = NonViralName.NewInstance(null);
1575
		return tn;
1576
	}
1577

    
1578
	private String getFromMap(HashMap<String, String> atomisedMap, String key) {
1579
		String value = null;
1580
		if (atomisedMap.containsKey(key)) {
1581
			value = atomisedMap.get(key);
1582
		}
1583

    
1584
		try {
1585
			if (value != null && key.matches(".*Year.*")) {
1586
				value = value.trim();
1587
				if (value.matches("[a-z A-Z ]*[0-9]{4}$")) {
1588
					String tmp = value.split("[0-9]{4}$")[0];
1589
					int year = Integer.parseInt(value.split(tmp)[1]);
1590
					if (year >= 1752) {
1591
						value = tmp;
1592
					} else {
1593
						value = null;
1594
					}
1595
				} else {
1596
					value = null;
1597
				}
1598
			}
1599
		} catch (Exception e) {
1600
			value = null;
1601
		}
1602

    
1603
		return value;
1604
	}
1605

    
1606
	private void compareABCDtoCDM(URI urlFileName, ArrayList<String> knownElts) {
1607
		try {
1608
			DocumentBuilderFactory factory = DocumentBuilderFactory
1609
					.newInstance();
1610
			DocumentBuilder constructeur = factory.newDocumentBuilder();
1611
			URL url = urlFileName.toURL();
1612
			Object o = url.getContent();
1613
			InputStream is = (InputStream) o;
1614
			Document document = constructeur.parse(is);
1615
			Element root = document.getDocumentElement();
1616
			abcdFileGetter.traverse(root);
1617
		} catch (ParserConfigurationException e) {
1618
			e.printStackTrace();
1619
		} catch (SAXException e) {
1620
			e.printStackTrace();
1621
		} catch (IOException e) {
1622
			e.printStackTrace();
1623
		}
1624
		Set<String> elts = dataHolder.allABCDelements.keySet();
1625
		Iterator<String> it = elts.iterator();
1626
		String elt;
1627
		while (it.hasNext()) {
1628
			elt = it.next();
1629
			if (knownElts.indexOf(elt) == -1) {
1630
				// logger.info("Unmerged ABCD element: " + elt + " - "+
1631
				// dataHolder.allABCDelements.get(elt));
1632
			}
1633
		}
1634
	}
1635

    
1636
	@Override
1637
	protected boolean isIgnore(Abcd206ImportState state) {
1638
		// return ! config.isDoNameFacts();
1639
		return false;
1640
	}
1641

    
1642
}
(2-2/5)