Project

General

Profile

Download (20.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.excel.taxa;
11

    
12
import java.net.MalformedURLException;
13
import java.net.URI;
14
import java.net.URISyntaxException;
15
import java.util.Arrays;
16
import java.util.HashMap;
17
import java.util.HashSet;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21
import java.util.UUID;
22

    
23
import org.apache.commons.lang.StringUtils;
24
import org.apache.log4j.Logger;
25
import org.springframework.stereotype.Component;
26

    
27
import eu.etaxonomy.cdm.common.CdmUtils;
28
import eu.etaxonomy.cdm.io.excel.common.ExcelRowBase.SourceDataHolder;
29
import eu.etaxonomy.cdm.model.agent.Team;
30
import eu.etaxonomy.cdm.model.common.CdmBase;
31
import eu.etaxonomy.cdm.model.common.DescriptionElementSource;
32
import eu.etaxonomy.cdm.model.common.Language;
33
import eu.etaxonomy.cdm.model.common.TimePeriod;
34
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
35
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
36
import eu.etaxonomy.cdm.model.description.Distribution;
37
import eu.etaxonomy.cdm.model.description.Feature;
38
import eu.etaxonomy.cdm.model.description.PresenceTerm;
39
import eu.etaxonomy.cdm.model.description.TaxonDescription;
40
import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
41
import eu.etaxonomy.cdm.model.description.TextData;
42
import eu.etaxonomy.cdm.model.location.NamedArea;
43
import eu.etaxonomy.cdm.model.location.TdwgArea;
44
import eu.etaxonomy.cdm.model.media.Media;
45
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
46
import eu.etaxonomy.cdm.model.name.NonViralName;
47
import eu.etaxonomy.cdm.model.name.Rank;
48
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
49
import eu.etaxonomy.cdm.model.reference.Reference;
50
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
51
import eu.etaxonomy.cdm.model.taxon.Classification;
52
import eu.etaxonomy.cdm.model.taxon.Synonym;
53
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
54
import eu.etaxonomy.cdm.model.taxon.Taxon;
55
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
56
import eu.etaxonomy.cdm.strategy.exceptions.StringNotParsableException;
57
import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
58
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
59

    
60
/**
61
 * @author a.babadshanjan
62
 * @created 08.01.2009
63
 */
64

    
65
@Component
66
public class NormalExplicitImport extends TaxonExcelImporterBase {
67
	private static final Logger logger = Logger.getLogger(NormalExplicitImport.class);
68
	
69
	public static Set<String> validMarkers = new HashSet<String>(Arrays.asList(new String[]{"", "valid", "accepted", "a", "v", "t"}));
70
	public static Set<String> synonymMarkers = new HashSet<String>(Arrays.asList(new String[]{"", "invalid", "synonym", "s", "i"}));
71
	
72
	
73
	/* (non-Javadoc)
74
	 * @see eu.etaxonomy.cdm.io.excel.common.ExcelTaxonOrSpecimenImportBase#analyzeSingleValue(eu.etaxonomy.cdm.io.excel.common.ExcelTaxonOrSpecimenImportBase.KeyValue, eu.etaxonomy.cdm.io.excel.common.ExcelImportState)
75
	 */
76
	@Override
77
	protected boolean analyzeSingleValue(KeyValue keyValue, TaxonExcelImportState state) {
78
		boolean success = true;
79
		
80
		NormalExplicitRow normalExplicitRow = state.getCurrentRow();
81
		String key = keyValue.key;
82
		String value = keyValue.value;
83
		Integer index = keyValue.index;
84
		if (key.equalsIgnoreCase(ID_COLUMN)) {
85
			int ivalue = floatString2IntValue(value);
86
			normalExplicitRow.setId(ivalue);
87
			
88
		} else if(key.equalsIgnoreCase(PARENT_ID_COLUMN)) {
89
			int ivalue = floatString2IntValue(value);
90
			normalExplicitRow.setParentId(ivalue);
91
			
92
		} else if(key.equalsIgnoreCase(RANK_COLUMN)) {
93
			normalExplicitRow.setRank(value);
94
			
95
		} else if(key.equalsIgnoreCase(SCIENTIFIC_NAME_COLUMN)) {
96
			normalExplicitRow.setScientificName(value);
97
			
98
		} else if(key.equalsIgnoreCase(AUTHOR_COLUMN)) {
99
			normalExplicitRow.setAuthor(value);
100
			
101
		} else if(key.equalsIgnoreCase(NAME_STATUS_COLUMN)) {
102
			normalExplicitRow.setNameStatus(value);
103
			
104
		} else if(key.equalsIgnoreCase(VERNACULAR_NAME_COLUMN)) {
105
			normalExplicitRow.setCommonName(value);
106
			
107
		} else if(key.equalsIgnoreCase(LANGUAGE_COLUMN)) {
108
			normalExplicitRow.setLanguage(value);
109
		
110
		} else if(key.equalsIgnoreCase(TDWG_COLUMN)) {
111
			//TODO replace still necessary?
112
			value = value.replace(".0", "");
113
			normalExplicitRow.putDistribution(index, value);
114
		
115
		} else if(key.equalsIgnoreCase(PROTOLOGUE_COLUMN)) {
116
			normalExplicitRow.putProtologue(index, value);
117
			
118
		} else if(key.equalsIgnoreCase(IMAGE_COLUMN)) {
119
			normalExplicitRow.putImage(index, value);
120
			
121
		} else {
122
			if (analyzeFeatures(state, keyValue)){
123
				//ok
124
			}else{
125
				String message = "Unexpected column header " + key;
126
				fireWarningEvent(message, state, 10);
127
				success = false;
128
				logger.error(message);
129
			}
130
		}
131
		return success;
132
	}
133

    
134

    
135
	/** 
136
	 *  Stores taxa records in DB
137
	 */
138
	@Override
139
    protected boolean firstPass(TaxonExcelImportState state) {
140
		boolean success = true;
141
		Rank rank = null;
142
		NormalExplicitRow taxonDataHolder = state.getCurrentRow();
143
		
144
		String rankStr = taxonDataHolder.getRank();
145
		String taxonNameStr = taxonDataHolder.getScientificName();
146
		String authorStr = taxonDataHolder.getAuthor();
147
		String nameStatus = taxonDataHolder.getNameStatus();
148
		Integer id = taxonDataHolder.getId();
149
		UUID cdmUuid = taxonDataHolder.getCdmUuid();
150
		
151
		TaxonBase taxonBase = null;
152
		if (cdmUuid != null){
153
			taxonBase = getTaxonService().find(cdmUuid);
154
		}else{
155
			if (CdmUtils.isNotEmpty(taxonNameStr)) {
156

    
157
				// Rank
158
				try {
159
					rank = Rank.getRankByNameOrAbbreviation(rankStr);
160
				} catch (UnknownCdmTypeException ex) {
161
					try {
162
						rank = Rank.getRankByEnglishName(rankStr, state.getConfig().getNomenclaturalCode(), false);
163
					} catch (UnknownCdmTypeException e) {
164
						success = false;
165
						logger.error(rankStr + " is not a valid rank.");
166
					}
167
				}
168
				
169
	            //taxon
170
				taxonBase = createTaxon(state, rank, taxonNameStr, authorStr, nameStatus);
171
			}else{
172
				return true;
173
			}
174
		}
175
		if (taxonBase == null){
176
			String message = "Taxon could not be created. Record will not be handled";
177
			fireWarningEvent(message, "Record: " + state.getCurrentLine(), 6);
178
			logger.warn(message);
179
			return false;
180
		}
181
		
182
		//protologue
183
		for (String protologue : taxonDataHolder.getProtologues()){
184
			TextData textData = TextData.NewInstance(Feature.PROTOLOGUE());
185
			this.getNameDescription(taxonBase.getName()).addElement(textData);
186
			URI uri;
187
			try {
188
				uri = new URI(protologue);
189
				textData.addMedia(Media.NewInstance(uri, null, null, null));
190
			} catch (URISyntaxException e) {
191
				String warning = "URISyntaxException when trying to convert to URI: " + protologue;
192
				logger.error(warning);
193
			}	
194
		}
195

    
196
		//media
197
		for (String imageUrl : taxonDataHolder.getImages()){
198
			//TODO
199
			Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
200
			TaxonDescription td = taxon.getImageGallery(true);
201
			DescriptionElementBase mediaHolder;
202
			if (td.getElements().size() != 0){
203
				mediaHolder = td.getElements().iterator().next();
204
			}else{
205
				mediaHolder = TextData.NewInstance(Feature.IMAGE());
206
				td.addElement(mediaHolder);
207
			}
208
			try {
209
				Media media = getImageMedia(imageUrl, true);
210
				mediaHolder.addMedia(media);
211
			} catch (MalformedURLException e) {
212
				logger.warn("Can't add media: " + e.getMessage());
213
			}
214
		}
215

    
216
		//tdwg label
217
		for (String tdwg : taxonDataHolder.getDistributions()){
218
			//TODO
219
			Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
220
			TaxonDescription td = this.getTaxonDescription(taxon, false, true);
221
			NamedArea area = TdwgArea.getAreaByTdwgAbbreviation(tdwg);
222
			if (area == null){
223
				area = TdwgArea.getAreaByTdwgLabel(tdwg);
224
			}
225
			if (area != null){
226
				Distribution distribution = Distribution.NewInstance(area, PresenceTerm.PRESENT());
227
				td.addElement(distribution);
228
			}else{
229
				String message = "TDWG area could not be recognized: " + tdwg;
230
				logger.warn(message);
231
			}
232
			
233
		}
234
		
235

    
236
		
237
		state.putTaxon(id, taxonBase);
238
		getTaxonService().save(taxonBase);
239

    
240
		return success;
241
    }
242

    
243

    
244

    
245
	/** 
246
	 *  Stores parent-child, synonym and common name relationships
247
	 */
248
	@Override
249
    protected boolean secondPass(TaxonExcelImportState state) {
250
//		System.out.println(state.getCurrentLine());
251
		boolean success = true;
252
		try {
253
			NormalExplicitRow taxonDataHolder = state.getCurrentRow();
254
			String taxonNameStr = taxonDataHolder.getScientificName();
255
			String nameStatus = taxonDataHolder.getNameStatus();
256
			String commonNameStr = taxonDataHolder.getCommonName();
257
			Integer parentId = taxonDataHolder.getParentId();
258
			Integer childId = taxonDataHolder.getId();
259
			UUID cdmUuid = taxonDataHolder.getCdmUuid();
260
			Taxon acceptedTaxon;
261
			TaxonNameBase nameUsedInSource;
262
			
263
			if (cdmUuid != null){
264
				TaxonBase taxonBase = getTaxonService().find(cdmUuid);
265
				acceptedTaxon = getAcceptedTaxon(taxonBase);
266
				nameUsedInSource = taxonBase.getName();
267
			}else{
268
				//TODO error handling for class cast
269
				Taxon parentTaxon = CdmBase.deproxy(state.getTaxonBase(parentId), Taxon.class);
270
				if (CdmUtils.isNotEmpty(taxonNameStr)) {
271
					TaxonBase taxonBase = state.getTaxonBase(childId);
272
					nameUsedInSource = taxonBase.getName();
273
					nameStatus = CdmUtils.Nz(nameStatus).trim().toLowerCase();
274
					if (validMarkers.contains(nameStatus)){
275
						Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
276
						acceptedTaxon = taxon;
277
						// Add the parent relationship
278
						if (state.getCurrentRow().getParentId() != 0) {
279
							if (parentTaxon != null) {
280
								//Taxon taxon = (Taxon)state.getTaxonBase(childId);
281
								
282
								Reference citation = state.getConfig().getSourceReference();
283
								String microCitation = null;
284
								Taxon childTaxon = taxon;
285
								success &= makeParent(state, parentTaxon, childTaxon, citation, microCitation);
286
								getTaxonService().saveOrUpdate(parentTaxon);
287
							} else {
288
								String message = "Taxonomic parent not found for " + taxonNameStr;
289
								logger.warn(message);
290
								fireWarningEvent(message, state, 6);
291
								success = false;
292
							}
293
						}else{
294
							//do nothing (parent == 0) no parent exists
295
						}
296
					}else if (synonymMarkers.contains(nameStatus)){
297
						//add synonym relationship
298
						acceptedTaxon = parentTaxon;
299
						try {
300
							Synonym synonym = CdmBase.deproxy(taxonBase,Synonym.class);
301
							if (acceptedTaxon == null){
302
								String message = "Accepted/valid taxon could not be found. Please check referential integrity.";
303
								fireWarningEvent(message, state, 8);
304
							}else{
305
								acceptedTaxon.addSynonym(synonym, SynonymRelationshipType.SYNONYM_OF());
306
								getTaxonService().saveOrUpdate(acceptedTaxon);
307
							}
308
						} catch (Exception e) {
309
							String message = "Unhandled exception (%s) occurred during synonym import/update";
310
							message = String.format(message, e.getMessage());
311
							fireWarningEvent(message, state, 10); 
312
							success = false;
313
						}
314
					}else{
315
						acceptedTaxon = null;
316
						String message = "Unhandled name status (%s)";
317
						message = String.format(message, nameStatus);
318
						fireWarningEvent(message, state, 8);
319
					}
320
				}else{//taxonNameStr is empty
321
					//vernacular name case
322
					acceptedTaxon = parentTaxon;
323
					nameUsedInSource = null;
324
				}
325
			}
326
 
327
			if (acceptedTaxon == null && (CdmUtils.isNotEmpty(commonNameStr) ||taxonDataHolder.getFeatures().size() > 0 )){
328
				String message = "Accepted taxon could not be found. Can't add additional data (common names, descriptive data, ...) to taxon";
329
				fireWarningEvent(message, state, 6);
330
			}else{	
331
				if (CdmUtils.isNotEmpty(commonNameStr)){			// add common name to taxon
332
					handleCommonName(state, taxonNameStr, commonNameStr, acceptedTaxon);
333
				}
334
				
335
				handleFeatures(state, taxonDataHolder, acceptedTaxon, nameUsedInSource);
336
			}
337
		} catch (Exception e) {
338
			e.printStackTrace();
339
		}
340
		return success;
341
	}
342

    
343

    
344
	/**
345
	 * @param state
346
	 * @param taxonDataHolder
347
	 * @param acceptedTaxon
348
	 */
349
	private void handleFeatures(TaxonExcelImportState state, NormalExplicitRow taxonDataHolder, Taxon acceptedTaxon, TaxonNameBase nameUsedInSource) {
350
		//feature
351
		for (UUID featureUuid : taxonDataHolder.getFeatures()){
352
			Feature feature = getFeature(state, featureUuid);
353
			List<String> textList = taxonDataHolder.getFeatureTexts(featureUuid);
354
			List<String> languageList = taxonDataHolder.getFeatureLanguages(featureUuid);
355
			
356
			for (int i = 0; i < textList.size(); i++){
357
				String featureText = textList.get(i);
358
				String featureLanguage = languageList.get(i);
359
				Language language = getFeatureLanguage(featureLanguage, state);
360
				//TODO
361
				TaxonDescription td = this.getTaxonDescription(acceptedTaxon, false, true);
362
				TextData textData = TextData.NewInstance(feature);
363
				textData.putText(language, featureText);
364
				td.addElement(textData);
365
				
366
				SourceDataHolder sourceDataHolder = taxonDataHolder.getFeatureTextReferences(featureUuid, i);
367
				List<Map<SourceType, String>> sourceList = sourceDataHolder.getSources();
368
				for (Map<SourceType, String> sourceMap : sourceList){
369
				
370
					DescriptionElementSource source = DescriptionElementSource.NewInstance();
371
					//ref
372
					Reference<?> ref = ReferenceFactory.newGeneric();
373
					boolean refExists = false; //in case none of the ref fields exists, the ref should not be added
374
					for (SourceType type : sourceMap.keySet()){
375
						String value = sourceMap.get(type);
376
						if (type.equals(SourceType.Author)){
377
							Team team = Team.NewInstance();
378
							team.setTitleCache(value, true);
379
							ref.setAuthorTeam(team);
380
						}else if (type.equals(SourceType.Title)) {
381
							ref.setTitle(value);
382
						}else if (type.equals(SourceType.Year)) {
383
							ref.setDatePublished(TimePeriod.parseString(value));
384
						}
385
						refExists = true;
386
					}
387
					if (refExists){
388
						source.setCitation(ref);
389
						source.setNameUsedInSource(nameUsedInSource);
390
					}
391
					textData.addSource(source);
392
				}				
393
			}
394
		}
395
	}
396

    
397

    
398
	private Map<String, UUID> languageMapping = new HashMap<String, UUID>();
399

    
400
	private Language getFeatureLanguage(String featureLanguage, TaxonExcelImportState state) {
401
		if (StringUtils.isBlank(featureLanguage)){
402
			return null;
403
		}
404
		UUID languageUuid = languageMapping.get(featureLanguage);
405
		if (languageUuid == null){
406
			Language result = getTermService().getLanguageByIso(featureLanguage);
407
			languageUuid = result.getUuid();
408
			languageMapping.put(featureLanguage, languageUuid);
409
		}
410
		Language result = getLanguage(state, languageUuid, null, null, null);
411
		return result;
412
	}
413

    
414

    
415
	/**
416
	 * @param state
417
	 * @param taxonNameStr
418
	 * @param commonNameStr
419
	 * @param parentId
420
	 */
421
	private void handleCommonName(TaxonExcelImportState state,
422
			String taxonNameStr, String commonNameStr, Taxon acceptedTaxon) {
423
		Language language = getTermService().getLanguageByIso(state.getCurrentRow().getLanguage());
424
		if (language == null && CdmUtils.isNotEmpty(state.getCurrentRow().getLanguage())  ){
425
			String error ="Language is null but shouldn't"; 
426
			logger.error(error);
427
			throw new IllegalArgumentException(error);
428
		}
429
		CommonTaxonName commonTaxonName = CommonTaxonName.NewInstance(commonNameStr, language);
430
		try {
431
			TaxonDescription taxonDescription = getTaxonDescription(acceptedTaxon, false, true);
432
			taxonDescription.addElement(commonTaxonName);
433
			logger.info("Common name " + commonNameStr + " added to " + acceptedTaxon.getTitleCache());
434
		} catch (ClassCastException ex) {
435
			logger.error(taxonNameStr + " is not a taxon instance.");
436
		}
437
	}
438

    
439

    
440
	/**
441
	 * @param state
442
	 * @param rank
443
	 * @param taxonNameStr
444
	 * @param authorStr
445
	 * @param nameStatus
446
	 * @return
447
	 */
448
	private TaxonBase createTaxon(TaxonExcelImportState state, Rank rank,
449
			String taxonNameStr, String authorStr, String nameStatus) {
450
		// Create the taxon name object depending on the setting of the nomenclatural code 
451
		// in the configurator (botanical code, zoological code, etc.) 
452
		if (StringUtils.isBlank(taxonNameStr)){
453
			return null;
454
		}
455
		NomenclaturalCode nc = getConfigurator().getNomenclaturalCode();
456
		
457
		TaxonBase taxonBase = null;
458
		
459
		String titleCache = CdmUtils.concat(" ", taxonNameStr, authorStr);
460
		if (! synonymMarkers.contains(nameStatus)  && state.getConfig().isDoMatchTaxa()){
461
			titleCache = CdmUtils.concat(" ", taxonNameStr, authorStr);
462
			taxonBase = getTaxonService().findBestMatchingTaxon(titleCache);
463
		}else{
464
			taxonBase = getTaxonService().findBestMatchingSynonym(titleCache);
465
			if (taxonBase != null){
466
				logger.info("Matching taxon/synonym found for " + titleCache);
467
			}
468
		}
469
		if (taxonBase != null){
470
			logger.info("Matching taxon/synonym found for " + titleCache);
471
		}else {
472
			taxonBase = createTaxon(state, rank, taxonNameStr, authorStr, nameStatus, nc);
473
		}
474
		return taxonBase;
475
	}
476

    
477

    
478
	
479

    
480
	/**
481
	 * @param state
482
	 * @param rank
483
	 * @param taxonNameStr
484
	 * @param authorStr
485
	 * @param nameStatus
486
	 * @param nc
487
	 * @return
488
	 */
489
	private TaxonBase createTaxon(TaxonExcelImportState state, Rank rank, String taxonNameStr, 
490
			String authorStr, String nameStatus, NomenclaturalCode nc) {
491
		TaxonBase taxonBase;
492
		NonViralName taxonNameBase = null;
493
		if (nc == NomenclaturalCode.ICVCN){
494
			logger.warn("ICVCN not yet supported");
495
			
496
		}else{
497
			taxonNameBase =(NonViralName) nc.getNewTaxonNameInstance(rank);
498
			//NonViralName nonViralName = (NonViralName)taxonNameBase;
499
			NonViralNameParserImpl parser = NonViralNameParserImpl.NewInstance();
500
			taxonNameBase = parser.parseFullName(taxonNameStr, nc, rank);
501
			
502
			taxonNameBase.setNameCache(taxonNameStr);
503
			
504
			// Create the author
505
			if (CdmUtils.isNotEmpty(authorStr)) {
506
				try {
507
					parser.parseAuthors(taxonNameBase, authorStr);
508
				} catch (StringNotParsableException e) {
509
					taxonNameBase.setAuthorshipCache(authorStr);
510
 				}
511
			}
512
		}
513

    
514
		//Create the taxon
515
		Reference sec = state.getConfig().getSourceReference();
516
		// Create the status
517
		nameStatus = CdmUtils.Nz(nameStatus).trim().toLowerCase();
518
		if (validMarkers.contains(nameStatus)){
519
			taxonBase = Taxon.NewInstance(taxonNameBase, sec);
520
		}else if (synonymMarkers.contains(nameStatus)){
521
			taxonBase = Synonym.NewInstance(taxonNameBase, sec);
522
		}else {
523
			Taxon taxon = Taxon.NewInstance(taxonNameBase, sec);
524
			taxon.setTaxonStatusUnknown(true);
525
			taxonBase = taxon;
526
		}
527
		return taxonBase;
528
	}
529
	
530
	/**
531
	 * @param taxon
532
	 * @return
533
	 */
534
	//TODO implementation must be improved when matching of taxon names with existing names is implemented
535
	//=> the assumption that the only description is the description added by this import
536
	//is wrong then
537
	private TaxonNameDescription getNameDescription(TaxonNameBase name) {
538
		Set<TaxonNameDescription> descriptions = name.getDescriptions();
539
		if (descriptions.size()>1){
540
			throw new IllegalStateException("Implementation does not yet support names with multiple descriptions");
541
		}else if (descriptions.size()==1){
542
			return descriptions.iterator().next();
543
		}else{
544
			return TaxonNameDescription.NewInstance(name);
545
		}
546
	}
547

    
548
	private boolean makeParent(TaxonExcelImportState state, Taxon parentTaxon, Taxon childTaxon, Reference citation, String microCitation){
549
		boolean success = true;
550
		Reference sec = state.getConfig().getSourceReference();
551
		
552
//		Reference sec = parentTaxon.getSec();
553
		Classification tree = state.getTree(sec);
554
		if (tree == null){
555
			tree = makeTree(state, sec);
556
		}
557
		if (sec.equals(childTaxon.getSec())){
558
			success &=  (null !=  tree.addParentChild(parentTaxon, childTaxon, citation, microCitation));
559
		}else{
560
			logger.warn("No relationship added for child " + childTaxon.getTitleCache());
561
		}
562
		return success;
563
	}
564
	
565

    
566
	/* (non-Javadoc)
567
	 * @see eu.etaxonomy.cdm.io.excel.common.ExcelTaxonOrSpecimenImportBase#createDataHolderRow()
568
	 */
569
	@Override
570
	protected NormalExplicitRow createDataHolderRow() {
571
		return new NormalExplicitRow();
572
	}
573

    
574
	
575
	
576
	/* (non-Javadoc)
577
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IoStateBase)
578
	 */
579
	@Override
580
	protected boolean doCheck(TaxonExcelImportState state) {
581
		logger.warn("DoCheck not yet implemented for NormalExplicitImport");
582
		return true;
583
	}
584
	
585
	/* (non-Javadoc)
586
	 * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IoStateBase)
587
	 */
588
	@Override
589
	protected boolean isIgnore(TaxonExcelImportState state) {
590
		return false;
591
	}
592
	
593

    
594
	
595
}
(1-1/5)