Project

General

Profile

Download (19.5 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
package eu.etaxonomy.cdm.io.cyprus;
10

    
11
import java.util.Arrays;
12
import java.util.HashSet;
13
import java.util.List;
14
import java.util.Map;
15
import java.util.Set;
16
import java.util.UUID;
17

    
18
import org.apache.commons.lang.StringUtils;
19
import org.apache.log4j.Logger;
20
import org.springframework.stereotype.Component;
21

    
22
import eu.etaxonomy.cdm.common.CdmUtils;
23
import eu.etaxonomy.cdm.io.common.TdwgAreaProvider;
24
import eu.etaxonomy.cdm.io.common.mapping.IInputTransformer;
25
import eu.etaxonomy.cdm.io.common.mapping.UndefinedTransformerMethodException;
26
import eu.etaxonomy.cdm.io.excel.common.ExcelImportBase;
27
import eu.etaxonomy.cdm.io.excel.common.ExcelRowBase;
28
import eu.etaxonomy.cdm.model.common.Language;
29
import eu.etaxonomy.cdm.model.description.Distribution;
30
import eu.etaxonomy.cdm.model.description.Feature;
31
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
32
import eu.etaxonomy.cdm.model.description.TaxonDescription;
33
import eu.etaxonomy.cdm.model.description.TextData;
34
import eu.etaxonomy.cdm.model.location.NamedArea;
35
import eu.etaxonomy.cdm.model.name.INonViralName;
36
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
37
import eu.etaxonomy.cdm.model.name.Rank;
38
import eu.etaxonomy.cdm.model.reference.Reference;
39
import eu.etaxonomy.cdm.model.taxon.Classification;
40
import eu.etaxonomy.cdm.model.taxon.Synonym;
41
import eu.etaxonomy.cdm.model.taxon.SynonymType;
42
import eu.etaxonomy.cdm.model.taxon.Taxon;
43
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
44
import eu.etaxonomy.cdm.strategy.parser.INonViralNameParser;
45
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
46

    
47
/**
48
 * @author a.babadshanjan
49
 * @since 08.01.2009
50
 */
51
@Component
52
public class CyprusExcelImport
53
        extends ExcelImportBase<CyprusImportState, CyprusImportConfigurator, ExcelRowBase> {
54

    
55
    private static final long serialVersionUID = 4449832452730987788L;
56

    
57
    private static final Logger logger = Logger.getLogger(CyprusExcelImport.class);
58

    
59
	public static Set<String> validMarkers = new HashSet<>(Arrays.asList(new String[]{"", "valid", "accepted", "a", "v", "t"}));
60
	public static Set<String> synonymMarkers = new HashSet<>(Arrays.asList(new String[]{"", "invalid", "synonym", "s", "i"}));
61

    
62

    
63
	@Override
64
	protected boolean isIgnore(CyprusImportState state) {
65
		return ! state.getConfig().isDoTaxa();
66
	}
67

    
68
	@Override
69
	protected boolean doCheck(CyprusImportState state) {
70
		logger.warn("DoCheck not yet implemented for CyprusExcelImport");
71
		return true;
72
	}
73

    
74
//	protected static final String ID_COLUMN = "Id";
75
	protected static final String SPECIES_COLUMN = "species";
76
	protected static final String SUBSPECIES_COLUMN = "subspecies";
77
	protected static final String GENUS_COLUMN = "genus";
78
	protected static final String FAMILY_COLUMN = "family";
79
	protected static final String DIVISION_COLUMN = "division";
80
	protected static final String HOMOTYPIC_SYNONYM_COLUMN = "homotypic synonyms";
81
	protected static final String HETEROTYPIC_SYNONYMS_COLUMN = "heterotypic synonyms";
82
	protected static final String ENDEMISM_COLUMN = "endemism";
83

    
84
	protected static final String STATUS_COLUMN = "status";
85
	protected static final String RED_DATA_BOOK_CATEGORY_COLUMN = "red data book category";
86
	protected static final String SYSTEMATICS_COLUMN = "systematics";
87

    
88
	// TODO: This enum is for future use (perhaps).
89
	protected enum Columns {
90
//		Id("Id"),
91
		Species("species"),
92
		Subspecies("subspecies"),
93
		Genus("genus"),
94
		Family("family"),
95
		Division("division"),
96
		HomotypicSynonyms("homotypic synonyms"),
97
		HeterotypicSynonyms("heterotypic synonyms"),
98
		Status("status"),
99
		Endemism("endemism");
100

    
101
		private final String head;
102
		private String value;
103

    
104
		private Columns(String head) {
105
			this.head = head;
106
		}
107

    
108
		public String head() {
109
			return this.head;
110
		}
111

    
112
		public String value() {
113
			return this.value;
114
		}
115
	}
116

    
117
	@Override
118
    protected void analyzeRecord(Map<String, String> record, CyprusImportState state) {
119

    
120
		Set<String> keys = record.keySet();
121

    
122
    	CyprusRow cyprusRow = new CyprusRow();
123
    	state.setCyprusRow(cyprusRow);
124

    
125
    	for (String originalKey: keys) {
126
    		String indexedKey = CdmUtils.removeDuplicateWhitespace(originalKey.trim()).toString();
127
    		String[] split = indexedKey.split("_");
128
    		String key = split[0];
129
    		if (split.length > 1){
130
    			String indexString = split[1];
131
    			try {
132
					Integer.valueOf(indexString);
133
				} catch (NumberFormatException e) {
134
					String message = "Index must be integer";
135
					logger.error(message);
136
					continue;
137
				}
138
    		}
139

    
140
    		String value = record.get(indexedKey);
141
    		if (! StringUtils.isBlank(value)) {
142
    			if (logger.isDebugEnabled()) { logger.debug(key + ": " + value); }
143
        		value = CdmUtils.removeDuplicateWhitespace(value.trim()).toString();
144
    		}else{
145
    			continue;
146
    		}
147

    
148
    		if (key.equalsIgnoreCase(SPECIES_COLUMN)) {
149
//    			int ivalue = floatString2IntValue(value);
150
    			cyprusRow.setSpecies(value);
151

    
152
			} else if(key.equalsIgnoreCase(SUBSPECIES_COLUMN)) {
153
				cyprusRow.setSubspecies(value);
154

    
155
			} else if(key.equalsIgnoreCase(HOMOTYPIC_SYNONYM_COLUMN)) {
156
				cyprusRow.setHomotypicSynonyms(value);
157

    
158
			} else if(key.equalsIgnoreCase(HETEROTYPIC_SYNONYMS_COLUMN)) {
159
				cyprusRow.setHeterotypicSynonyms(value);
160

    
161
			} else if(key.equalsIgnoreCase(ENDEMISM_COLUMN)) {
162
				cyprusRow.setEndemism(value);
163

    
164
			} else if(key.equalsIgnoreCase(STATUS_COLUMN)) {
165
				cyprusRow.setStatus(value);
166

    
167
			} else if(key.equalsIgnoreCase(RED_DATA_BOOK_CATEGORY_COLUMN)) {
168
				cyprusRow.setRedDataBookCategory(value);
169

    
170
			} else if(key.equalsIgnoreCase(SYSTEMATICS_COLUMN)) {
171
				cyprusRow.setSystematics(value);
172

    
173
			} else if(key.equalsIgnoreCase(GENUS_COLUMN)) {
174
				cyprusRow.setGenus(value);
175

    
176
			} else if(key.equalsIgnoreCase(FAMILY_COLUMN)) {
177
				cyprusRow.setFamily(value);
178

    
179
			} else if(key.equalsIgnoreCase(DIVISION_COLUMN)) {
180
				cyprusRow.setDivision(value);
181

    
182
			} else {
183
				state.setUnsuccessfull();
184
				logger.error("Unexpected column header " + key);
185
			}
186
    	}
187
    	return;
188
    }
189

    
190
	private static INonViralNameParser<INonViralName> nameParser = NonViralNameParserImpl.NewInstance();
191
	private static NomenclaturalCode nc = NomenclaturalCode.ICNAFP;
192
	private Feature redBookCategory;
193
	private Feature endemism;
194
	private PresenceAbsenceTerm indigenous;
195
	private PresenceAbsenceTerm indigenousDoubtful;
196
	private PresenceAbsenceTerm cultivatedDoubtful;
197

    
198
	private PresenceAbsenceTerm casual;
199
	private PresenceAbsenceTerm casualDoubtful;
200
	private PresenceAbsenceTerm nonInvasive;
201
	private PresenceAbsenceTerm nonInvasiveDoubtful;
202
	private PresenceAbsenceTerm invasive;
203
	private PresenceAbsenceTerm invasiveDoubtful;
204
	private PresenceAbsenceTerm questionable;
205
	private PresenceAbsenceTerm questionableDoubtful;
206

    
207
	private boolean termsCreated = false;
208

    
209
	private boolean makeTerms(CyprusImportState state) {
210
		if (termsCreated == false){
211
			IInputTransformer transformer = state.getTransformer();
212

    
213
			try {
214
				//feature
215
				UUID redBookUuid = transformer.getFeatureUuid("Red book");
216
				redBookCategory = this.getFeature(state, redBookUuid, "Red book category", "Red data book category", "Red book", null);
217
				getTermService().save(redBookCategory);
218

    
219
				UUID endemismUuid = transformer.getFeatureUuid("Endemism");
220
				endemism = this.getFeature(state, endemismUuid, "Endemism", "Endemism", "Endemism", null);
221
				getTermService().save(endemism);
222

    
223
				//status
224
				UUID indigenousUuid = transformer.getPresenceTermUuid("IN");
225
				indigenous = this.getPresenceTerm(state, indigenousUuid, "indigenous", "Indigenous", "IN", false);
226
				getTermService().save(indigenous);
227
				UUID indigenousDoubtfulUuid = transformer.getPresenceTermUuid("IN?");
228
				indigenousDoubtful = this.getPresenceTerm(state, indigenousDoubtfulUuid, "indigenous?", "Indigenous?", "IN?", false);
229
				getTermService().save(indigenousDoubtful);
230

    
231
				UUID cultivatedDoubtfulUuid = transformer.getPresenceTermUuid("CU?");
232
				cultivatedDoubtful = this.getPresenceTerm(state, cultivatedDoubtfulUuid, "cultivated?", "Cultivated?", "CU?", false);
233
				getTermService().save(cultivatedDoubtful);
234

    
235
				UUID casualUuid = transformer.getPresenceTermUuid("CA");
236
				casual = this.getPresenceTerm(state, casualUuid, "casual", "Casual", "CA", false);
237
				getTermService().save(casual);
238
				UUID casualDoubtfulUuid = transformer.getPresenceTermUuid("CA?");
239
				casualDoubtful = this.getPresenceTerm(state, casualDoubtfulUuid, "casual?", "Casual?", "CA?", false);
240
				getTermService().save(casualDoubtful);
241

    
242
				UUID nonInvasiveUuid = transformer.getPresenceTermUuid("NN");
243
				nonInvasive = this.getPresenceTerm(state, nonInvasiveUuid, "naturalized  non-invasive", "Naturalized  non-invasive", "NN", false);
244
				getTermService().save(nonInvasive);
245
				UUID nonInvasiveDoubtfulUuid = transformer.getPresenceTermUuid("NN?");
246
				nonInvasiveDoubtful = this.getPresenceTerm(state, nonInvasiveDoubtfulUuid, "naturalized  non-invasive?", "Naturalized  non-invasive?", "NN?", false);
247
				getTermService().save(nonInvasiveDoubtful);
248

    
249
				UUID invasiveUuid = transformer.getPresenceTermUuid("NA");
250
				invasive = this.getPresenceTerm(state, invasiveUuid, "naturalized  invasive", "Naturalized  invasive", "NA", false);
251
				getTermService().save(invasive);
252
				UUID invasiveDoubtfulUuid = transformer.getPresenceTermUuid("NA?");
253
				invasiveDoubtful = this.getPresenceTerm(state, invasiveDoubtfulUuid, "naturalized  invasive?", "Naturalized  invasive?", "NA?", false);
254
				getTermService().save(invasiveDoubtful);
255

    
256
				UUID questionableUuid = transformer.getPresenceTermUuid("Q");
257
				questionable = this.getPresenceTerm(state, questionableUuid, "questionable", "Questionable", "Q", false);
258
				getTermService().save(questionable);
259
				UUID questionableDoubtfulUuid = transformer.getPresenceTermUuid("Q?");
260
				questionableDoubtful = this.getPresenceTerm(state, questionableDoubtfulUuid, "questionable?", "Questionable?", "Q?", false);
261
				getTermService().save(questionableDoubtful);
262

    
263
				termsCreated = true;
264

    
265
				return true;
266
			} catch (UndefinedTransformerMethodException e) {
267
				e.printStackTrace();
268
				return false;
269
			}
270
		}
271
		return true;
272

    
273
	}
274

    
275
	/**
276
	 *  Stores taxa records in DB
277
	 */
278
	@Override
279
    protected void firstPass(CyprusImportState state) {
280

    
281
		makeTerms(state);
282
		CyprusRow taxonLight = state.getCyprusRow();
283
		Reference citation = null;
284
		String microCitation = null;
285

    
286
		//species name
287
		String speciesStr = taxonLight.getSpecies();
288
		String subSpeciesStr = taxonLight.getSubspecies();
289
		String homotypicSynonymsString = taxonLight.getHomotypicSynonyms();
290
		List<String> homotypicSynonymList = Arrays.asList(homotypicSynonymsString.split(";"));
291
		String heterotypicSynonymsString = taxonLight.getHeterotypicSynonyms();
292
		List<String> heterotypicSynonymList = Arrays.asList(heterotypicSynonymsString.split(";"));
293

    
294
		String systematicsString = taxonLight.getSystematics();
295
		String endemismString = taxonLight.getEndemism();
296
		String statusString = taxonLight.getStatus();
297
		String redBookCategory = taxonLight.getRedDataBookCategory();
298

    
299
		if (StringUtils.isNotBlank(speciesStr)) {
300
			boolean speciesIsExisting = false;
301
			Taxon mainTaxon = null;
302
			//species
303
			Taxon speciesTaxon = (Taxon)createTaxon(state, Rank.SPECIES(), speciesStr, Taxon.class, nc);
304
			mainTaxon = speciesTaxon;
305

    
306
			//subspecies
307
			if (StringUtils.isNotBlank(subSpeciesStr)){
308
				Taxon existingSpecies = state.getHigherTaxon(speciesStr);
309
				if (existingSpecies != null){
310
					speciesIsExisting = true;
311
					speciesTaxon = existingSpecies;
312
				}
313

    
314
				Taxon subSpeciesTaxon = (Taxon)createTaxon(state, Rank.SUBSPECIES(), subSpeciesStr, Taxon.class, nc);
315

    
316
				if (subSpeciesTaxon != null){
317
					makeParent(state, speciesTaxon, subSpeciesTaxon, citation, microCitation);
318
				}
319
				mainTaxon = subSpeciesTaxon;
320
				state.putHigherTaxon(speciesStr, speciesTaxon);
321
			}
322

    
323
			if (! speciesIsExisting){
324
				makeHigherTaxa(state, taxonLight, speciesTaxon, citation, microCitation);
325
			}
326
			makeHomotypicSynonyms(state, homotypicSynonymList, mainTaxon);
327
			makeHeterotypicSynonyms(state, heterotypicSynonymList, mainTaxon);
328
			makeSystematics(systematicsString, mainTaxon);
329
			makeEndemism(endemismString, mainTaxon);
330
			makeStatus(statusString, mainTaxon);
331
			makeRedBookCategory(redBookCategory, mainTaxon);
332

    
333
//			state.putHigherTaxon(higherName, uuid);//(speciesStr, mainTaxon);
334
			getTaxonService().save(mainTaxon);
335
		}
336
		return;
337
    }
338

    
339
	private void makeHigherTaxa(CyprusImportState state, CyprusRow taxonLight, Taxon speciesTaxon, Reference citation, String microCitation) {
340
		String divisionStr = taxonLight.getDivision();
341
		String genusStr = taxonLight.getGenus();
342
		String familyStr = taxonLight.getFamily();
343

    
344
		Taxon division = getTaxon(state, divisionStr, Rank.DIVISION(), null, citation, microCitation);
345
		Taxon family = getTaxon(state, familyStr, Rank.FAMILY(), division, citation, microCitation);
346
		Taxon genus = getTaxon(state, genusStr, Rank.GENUS(), family, citation, microCitation);
347
		makeParent(state, genus, speciesTaxon, citation, microCitation)	;
348
	}
349

    
350

    
351
	private Taxon getTaxon(CyprusImportState state, String taxonNameStr, Rank rank, Taxon parent, Reference citation, String microCitation) {
352
		Taxon result;
353
		if (state.containsHigherTaxon(taxonNameStr)){
354
			result = state.getHigherTaxon(taxonNameStr);
355
		}else{
356
			result = (Taxon)createTaxon(state, rank, taxonNameStr, Taxon.class, nc);
357
			state.putHigherTaxon(taxonNameStr, result);
358
			if (parent == null){
359
				makeParent(state, null,result, citation, microCitation);
360
			}else{
361
				makeParent(state, parent, result, citation, microCitation);
362
			}
363

    
364
		}
365
		return result;
366
	}
367

    
368

    
369
	private void makeHomotypicSynonyms(CyprusImportState state,
370
			List<String> homotypicSynonymList, Taxon mainTaxon) {
371
		for (String homotypicSynonym: homotypicSynonymList){
372
			if (StringUtils.isNotBlank(homotypicSynonym)){
373
				Synonym synonym = (Synonym)createTaxon(state, null, homotypicSynonym, Synonym.class, nc);
374
				mainTaxon.addHomotypicSynonym(synonym);
375
			}
376
		}
377
	}
378

    
379

    
380
	private void makeHeterotypicSynonyms(CyprusImportState state, List<String> heterotypicSynonymList, Taxon mainTaxon) {
381
		for (String heterotypicSynonym: heterotypicSynonymList){
382
			if (StringUtils.isNotBlank(heterotypicSynonym)){
383
				Synonym synonym = (Synonym)createTaxon(state, null, heterotypicSynonym, Synonym.class, nc);
384
				mainTaxon.addSynonym(synonym, SynonymType.HETEROTYPIC_SYNONYM_OF());
385
			}
386
		}
387
	}
388

    
389

    
390
	private void makeSystematics(String systematicsString, Taxon mainTaxon) {
391
		//Systematics
392
		if (StringUtils.isNotBlank(systematicsString)){
393
			TaxonDescription td = this.getTaxonDescription(mainTaxon, false, true);
394
			TextData textData = TextData.NewInstance(Feature.SYSTEMATICS());
395
			textData.putText(Language.UNDETERMINED(), systematicsString);
396
			td.addElement(textData);
397
		}
398
	}
399

    
400

    
401
	private void makeEndemism(String endemismString, Taxon mainTaxon) {
402
		//endemism
403
		if (StringUtils.isNotBlank(endemismString)){
404
			//OLD - not wanted as marker
405
//			boolean flag;
406
//			if (endemismString.trim().equalsIgnoreCase("not endemic") || endemismString.trim().equalsIgnoreCase("ne?")){
407
//				flag = false;
408
//			}else if (endemismString.trim().equalsIgnoreCase("endemic")){
409
//				flag = true;
410
//			}else{
411
//				throw new RuntimeException(endemismString + " is not a valid value for endemism");
412
//			}
413
//			Marker marker = Marker.NewInstance(MarkerType.ENDEMIC(), flag);
414
//			mainTaxon.addMarker(marker);
415
			//text data
416
			TaxonDescription td = this.getTaxonDescription(mainTaxon, false, true);
417
			TextData textData = TextData.NewInstance(endemism);
418
			textData.putText(Language.ENGLISH(), endemismString);
419
			td.addElement(textData);
420
		}
421
	}
422

    
423
	private void makeStatus(String statusString, Taxon mainTaxon) {
424
		//status
425
		if (StringUtils.isNotBlank(statusString)){
426
			PresenceAbsenceTerm status = null;
427
			if (statusString.contains("Indigenous?")){
428
				status = indigenousDoubtful;
429
			}else if (statusString.contains("Indigenous")){
430
				status = indigenous;
431
			}else if (statusString.contains("Casual?") || statusString.contains("Causal?")){
432
				status = casualDoubtful;
433
			}else if (statusString.contains("Casual")){
434
				status = casual;
435
			}else if (statusString.contains("Cultivated?")){
436
				status = cultivatedDoubtful;
437
			}else if (statusString.contains("Cultivated")){
438
				status = PresenceAbsenceTerm.CULTIVATED();
439
			}else if (statusString.contains("non-invasive?")){
440
				status = nonInvasiveDoubtful;
441
			}else if (statusString.contains("non-invasive")){
442
				status = nonInvasive;
443
			}else if (statusString.contains("invasive?")){
444
				status = invasiveDoubtful;
445
			}else if (statusString.contains("invasive")){
446
				status = invasive;
447
			}else if (statusString.contains("Questionable?")){
448
				status = questionableDoubtful;
449
			}else if (statusString.contains("Questionable")){
450
				status = questionable;
451
			}else if (statusString.startsWith("F")){
452
				status = null;
453
			}else if (statusString.equals("##")){
454
				status = null;
455
			}else{
456
				logger.warn("Unknown status: " + statusString);
457
				status = null;
458
			}
459
			TaxonDescription td = this.getTaxonDescription(mainTaxon, false, true);
460
			NamedArea area = TdwgAreaProvider.getAreaByTdwgAbbreviation("CYP");
461
			Distribution distribution = Distribution.NewInstance(area, status);
462
			td.addElement(distribution);
463

    
464
			//text data
465
			TextData textData = TextData.NewInstance(Feature.STATUS());
466
			textData.putText(Language.ENGLISH(), statusString);
467
			td.addElement(textData);
468
		}
469
	}
470

    
471
	private void makeRedBookCategory(String redBookCategory, Taxon mainTaxon) {
472
		//red data book category
473
		if (StringUtils.isNotBlank(redBookCategory)){
474
			TaxonDescription td = this.getTaxonDescription(mainTaxon, false, true);
475
			TextData textData = TextData.NewInstance(this.redBookCategory);
476
			textData.putText(Language.ENGLISH(), redBookCategory);
477
			td.addElement(textData);
478
		}
479
	}
480

    
481
	/**
482
	 *  Stores parent-child, synonym and common name relationships
483
	 */
484
	@Override
485
    protected void secondPass(CyprusImportState state) {
486
//		CyprusRow cyprusRow = state.getCyprusRow();
487
		return;
488
	}
489

    
490
	private TaxonBase<?> createTaxon(CyprusImportState state, Rank rank, String taxonNameStr,
491
			Class<?> statusClass, NomenclaturalCode nc) {
492
		TaxonBase<?> taxonBase;
493
		INonViralName taxonNameBase = null;
494
		if (nc == NomenclaturalCode.ICVCN){
495
			logger.warn("ICVCN not yet supported");
496

    
497
		}else{
498
			taxonNameBase = nc.getNewTaxonNameInstance(rank);
499
			INonViralNameParser<INonViralName> parser = nameParser;//NonViralNameParserImpl.NewInstance();
500
			taxonNameBase = parser.parseFullName(taxonNameStr, nc, rank);
501

    
502
			//taxonNameBase.setNameCache(taxonNameStr);
503
		}
504

    
505
		//Create the taxon
506
		Reference sec = state.getConfig().getSourceReference();
507
		// Create the status
508
		if (statusClass.equals(Taxon.class)){
509
			taxonBase = Taxon.NewInstance(taxonNameBase, sec);
510
		}else if (statusClass.equals(Synonym.class)){
511
			taxonBase = Synonym.NewInstance(taxonNameBase, sec);
512
		}else {
513
			Taxon taxon = Taxon.NewInstance(taxonNameBase, sec);
514
			taxon.setTaxonStatusUnknown(true);
515
			taxonBase = taxon;
516
		}
517
		return taxonBase;
518
	}
519

    
520
	private boolean makeParent(CyprusImportState state, Taxon parentTaxon, Taxon childTaxon, Reference citation, String microCitation){
521
		boolean success = true;
522
		Reference sec = state.getConfig().getSourceReference();
523

    
524
//		Reference sec = parentTaxon.getSec();
525
		Classification tree = state.getTree(sec);
526
		if (tree == null){
527
			tree = makeTree(state, sec);
528
			tree.setTitleCache(state.getConfig().getSourceReferenceTitle(), true);
529
		}
530
		if (sec.equals(childTaxon.getSec())){
531
			success &=  (null !=  tree.addParentChild(parentTaxon, childTaxon, citation, microCitation));
532
		}else{
533
			logger.warn("No relationship added for child " + childTaxon.getTitleCache());
534
		}
535
		return success;
536
	}
537
}
(3-3/7)