Project

General

Profile

Download (16.6 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.api.service;
11

    
12
import java.util.ArrayList;
13
import java.util.Collection;
14
import java.util.Collections;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Map;
18
import java.util.Set;
19
import java.util.UUID;
20

    
21
import org.apache.log4j.Logger;
22
import org.springframework.beans.factory.annotation.Autowired;
23
import org.springframework.beans.factory.annotation.Qualifier;
24
import org.springframework.stereotype.Service;
25
import org.springframework.transaction.TransactionStatus;
26
import org.springframework.transaction.annotation.Transactional;
27

    
28
import eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator;
29
import eu.etaxonomy.cdm.api.service.pager.Pager;
30
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
31
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
32
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
33
import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
34
import eu.etaxonomy.cdm.model.common.RelationshipBase;
35
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
36
import eu.etaxonomy.cdm.model.description.DescriptionBase;
37
import eu.etaxonomy.cdm.model.description.TaxonDescription;
38
import eu.etaxonomy.cdm.model.name.Rank;
39
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
40
import eu.etaxonomy.cdm.model.reference.ReferenceBase;
41
import eu.etaxonomy.cdm.model.taxon.Synonym;
42
import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
43
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
44
import eu.etaxonomy.cdm.model.taxon.Taxon;
45
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
46
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
47
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
48
import eu.etaxonomy.cdm.persistence.dao.common.IOrderedTermVocabularyDao;
49
import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;
50
import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
51
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
52
import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;
53
import eu.etaxonomy.cdm.persistence.query.SelectMode;
54

    
55

    
56
@Service
57
@Transactional(readOnly = true)
58
public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDao> implements ITaxonService {
59
	private static final Logger logger = Logger.getLogger(TaxonServiceImpl.class);
60

    
61
	@Autowired
62
	private ITaxonNameDao nameDao;
63
//	@Autowired
64
//	@Qualifier("nonViralNameDaoHibernateImpl")
65
//	private INonViralNameDao nonViralNameDao;
66
	@Autowired
67
	private IOrderedTermVocabularyDao orderedVocabularyDao;
68
	@Autowired
69
	private IDescriptionDao descriptionDao;
70
	
71
	/**
72
	 * Constructor
73
	 */
74
	public TaxonServiceImpl(){
75
		if (logger.isDebugEnabled()) { logger.debug("Load TaxonService Bean"); }
76
	}
77
	
78
	public TaxonBase getTaxonByUuid(UUID uuid) {
79
		return super.getCdmObjectByUuid(uuid); 
80
	}
81

    
82
	@Transactional(readOnly = false)
83
	public UUID saveTaxon(TaxonBase taxon) {
84
		return super.saveCdmObject(taxon);
85
	}
86

    
87
	//@Transactional(readOnly = false)
88
	public UUID saveTaxon(TaxonBase taxon, TransactionStatus txStatus) {
89
		
90
		//return super.saveCdmObject(taxon, txStatus);
91
		return super.saveCdmObject(taxon);
92
	}
93
	
94
	
95
	@Transactional(readOnly = false)
96
	public Map<UUID, ? extends TaxonBase> saveTaxonAll(Collection<? extends TaxonBase> taxonCollection){
97
		return saveCdmObjectAll(taxonCollection);
98
	}
99

    
100
	@Transactional(readOnly = false)
101
	public UUID removeTaxon(TaxonBase taxon) {
102
		return super.removeCdmObject(taxon);
103
	}
104

    
105
	public List<TaxonBase> searchTaxaByName(String name, ReferenceBase sec) {
106
		return dao.getTaxaByName(name, sec);
107
	}
108

    
109
	public List<TaxonBase> getAllTaxonBases(int limit, int start){
110
		return dao.list(limit, start);
111
	}
112

    
113
	public List<Taxon> getAllTaxa(int limit, int start){
114
		return dao.getAllTaxa(limit, start);
115
	}
116
	
117
	public List<Synonym> getAllSynonyms(int limit, int start) {
118
		return dao.getAllSynonyms(limit, start);
119
	}
120
	
121
	/* (non-Javadoc)
122
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase)
123
	 */
124
	public List<Taxon> getRootTaxa(ReferenceBase sec){
125
		return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true);
126
	}
127

    
128
	/* (non-Javadoc)
129
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean)
130
	 */
131
	public List<Taxon> getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, boolean onlyWithChildren) {
132
		if (cdmFetch == null){
133
			cdmFetch = CdmFetch.NO_FETCH();
134
		}
135
		return dao.getRootTaxa(sec, cdmFetch, onlyWithChildren, false);
136
	}
137

    
138
	
139
	/* (non-Javadoc)
140
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean, boolean)
141
	 */
142
	public List<Taxon> getRootTaxa(ReferenceBase sec, boolean onlyWithChildren,
143
			boolean withMisapplications) {
144
		return dao.getRootTaxa(sec, null, onlyWithChildren, withMisapplications);
145
	}
146

    
147
	/* (non-Javadoc)
148
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean, boolean)
149
	 */
150
	public List<Taxon> getRootTaxa(Rank rank, ReferenceBase sec, boolean onlyWithChildren,
151
			boolean withMisapplications) {
152
		return dao.getRootTaxa(rank, sec, null, onlyWithChildren, withMisapplications);
153
	}
154

    
155
	public List<RelationshipBase> getAllRelationships(int limit, int start){
156
		return dao.getAllRelationships(limit, start);
157
	}
158
	
159
	public OrderedTermVocabulary<TaxonRelationshipType> getTaxonRelationshipTypeVocabulary() {
160
		
161
		String taxonRelTypeVocabularyId = "15db0cf7-7afc-4a86-a7d4-221c73b0c9ac";
162
		UUID uuid = UUID.fromString(taxonRelTypeVocabularyId);
163
		OrderedTermVocabulary<TaxonRelationshipType> taxonRelTypeVocabulary = 
164
			(OrderedTermVocabulary)orderedVocabularyDao.findByUuid(uuid);
165
		return taxonRelTypeVocabulary;
166
	}
167

    
168
	/* (non-Javadoc)
169
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#makeTaxonSynonym(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.Taxon)
170
	 */
171
	@Transactional(readOnly = false)
172
	public Synonym makeTaxonSynonym(Taxon oldTaxon, Taxon newAcceptedTaxon, SynonymRelationshipType synonymType, ReferenceBase citation, String citationMicroReference) {
173
		if (oldTaxon == null || newAcceptedTaxon == null || oldTaxon.getName() == null){
174
			return null;
175
		}
176
		
177
		// Move oldTaxon to newTaxon
178
		TaxonNameBase<?,?> synonymName = oldTaxon.getName();
179
		if (synonymType == null){
180
			if (synonymName.isHomotypic(newAcceptedTaxon.getName())){
181
				synonymType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
182
			}else{
183
				//TODO synonymType 
184
				synonymType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
185
			}
186
		}
187
		SynonymRelationship synRel = newAcceptedTaxon.addSynonymName(synonymName, synonymType, citation, citationMicroReference);
188
		
189
		//Move Synonym Relations to new Taxon
190
		for(SynonymRelationship synRelation : oldTaxon.getSynonymRelations()){
191
			newAcceptedTaxon.addSynonym(synRelation.getSynonym(), synRelation.getType(), 
192
					synRelation.getCitation(), synRelation.getCitationMicroReference());
193
		}
194

    
195
		//Move Taxon RelationShips to new Taxon
196
		Set<TaxonRelationship> removableTaxonRels = new HashSet<TaxonRelationship>();
197
		for(TaxonRelationship taxonRelation : oldTaxon.getTaxonRelations()){
198
			//CHILDREN
199
			if (taxonRelation.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())){
200
				if (taxonRelation.getFromTaxon() == oldTaxon){
201
					removableTaxonRels.add(taxonRelation);
202
//					oldTaxon.removeTaxonRelation(taxonRelation);
203
				}else if(taxonRelation.getToTaxon() == oldTaxon){
204
					newAcceptedTaxon.addTaxonomicChild(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());
205
					removableTaxonRels.add(taxonRelation);
206
//					oldTaxon.removeTaxonRelation(taxonRelation);
207
				}else{
208
					logger.warn("Taxon is not part of its own Taxonrelationship");
209
				}
210
			}
211
			//MISAPPLIED NAMES
212
			if (taxonRelation.getType().equals(TaxonRelationshipType.MISAPPLIED_NAME_FOR())){
213
				if (taxonRelation.getFromTaxon() == oldTaxon){
214
					newAcceptedTaxon.addMisappliedName(taxonRelation.getToTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());
215
					removableTaxonRels.add(taxonRelation);
216
//					oldTaxon.removeTaxonRelation(taxonRelation);
217
				}else if(taxonRelation.getToTaxon() == oldTaxon){
218
					newAcceptedTaxon.addMisappliedName(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());
219
					removableTaxonRels.add(taxonRelation);
220
//					oldTaxon.removeTaxonRelation(taxonRelation);
221
				}else{
222
					logger.warn("Taxon is not part of its own Taxonrelationship");
223
				}
224
			}
225
			//Concept Relationships
226
			//FIXME implement
227
//			if (taxonRelation.getType().equals(TaxonRelationshipType.MISAPPLIEDNAMEFOR())){
228
//				if (taxonRelation.getFromTaxon() == oldTaxon){
229
//					newAcceptedTaxon.addMisappliedName(taxonRelation.getToTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());
230
//			        removableTaxonRels.add(taxonRelation);
231
//				}else if(taxonRelation.getToTaxon() == oldTaxon){
232
//					newAcceptedTaxon.addMisappliedName(taxonRelation.getFromTaxon(), taxonRelation.getCitation(), taxonRelation.getCitationMicroReference());
233
//	                removableTaxonRels.add(taxonRelation);
234
//				}else{
235
//					logger.warn("Taxon is not part of its own Taxonrelationship");
236
//				}
237
//			}
238
		}
239
		
240
		for(TaxonRelationship taxonRel : removableTaxonRels) {
241
			oldTaxon.removeTaxonRelation(taxonRel);
242
		}
243
		
244
		//Move Descriptions to new Taxon
245
		for(TaxonDescription taxDescription : oldTaxon.getDescriptions()){
246
			newAcceptedTaxon.addDescription(taxDescription);
247
		}
248
		//delete old Taxon
249
		this.dao.saveOrUpdate(newAcceptedTaxon);
250
//		FIXME implement
251
//		this.dao.delete(oldTaxon);
252
		
253
		//return
254
//		this.dao.flush();
255
		return synRel.getSynonym();
256
	}
257

    
258

    
259
	public void generateTitleCache() {
260
		generateTitleCache(true);
261
	}
262
	//TODO
263
	public void generateTitleCache(boolean forceProtected) {
264
		logger.warn("generateTitleCache not yet fully implemented!");
265
//		for (TaxonBase tb : taxonDao.getAllTaxa(null,null)){
266
//			logger.warn("Old taxon title: " + tb.getTitleCache());
267
//			if (forceProtected || !tb.isProtectedTitleCache() ){
268
//				tb.setTitleCache(tb.generateTitle(), false);
269
//				taxonDao.update(tb);
270
//				logger.warn("New title: " + tb.getTitleCache());
271
//			}
272
//		}
273
		
274
	}
275

    
276
	@Autowired
277
	protected void setDao(ITaxonDao dao) {
278
		this.dao = dao;
279
	}
280

    
281
	public Pager<TaxonBase> findTaxaByName(Boolean accepted, String uninomial,	String infragenericEpithet, String specificEpithet,	String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) {
282
        Integer numberOfResults = dao.countTaxaByName(accepted, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank);
283
		
284
		List<TaxonBase> results = new ArrayList<TaxonBase>();
285
		if(numberOfResults > 0) { // no point checking again
286
			results = dao.findTaxaByName(accepted, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber); 
287
		}
288
		
289
		return new DefaultPagerImpl<TaxonBase>(pageNumber, numberOfResults, pageSize, results);
290
	}
291

    
292
	public Pager<TaxonRelationship> getRelatedTaxa(Taxon taxon,	TaxonRelationshipType type, Integer pageSize, Integer pageNumber) {
293
        Integer numberOfResults = dao.countRelatedTaxa(taxon, type);
294
		
295
		List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
296
		if(numberOfResults > 0) { // no point checking again
297
			results = dao.getRelatedTaxa(taxon, type, pageSize, pageNumber); 
298
		}
299
		
300
		return new DefaultPagerImpl<TaxonRelationship>(pageNumber, numberOfResults, pageSize, results);
301
	}
302

    
303
	public Pager<SynonymRelationship> getSynonyms(Taxon taxon,	SynonymRelationshipType type, Integer pageSize, Integer pageNumber) {
304
        Integer numberOfResults = dao.countSynonyms(taxon, type);
305
		
306
		List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();
307
		if(numberOfResults > 0) { // no point checking again
308
			results = dao.getSynonyms(taxon, type, pageSize, pageNumber); 
309
		}
310
		
311
		return new DefaultPagerImpl<SynonymRelationship>(pageNumber, numberOfResults, pageSize, results);
312
	}
313

    
314
	public Pager<TaxonBase> searchTaxa(String queryString, Boolean accepted, Integer pageSize, Integer pageNumber) {
315
        Integer numberOfResults = dao.countTaxa(queryString, accepted);
316
		
317
		List<TaxonBase> results = new ArrayList<TaxonBase>();
318
		if(numberOfResults > 0) { // no point checking again
319
			results = dao.searchTaxa(queryString, accepted, pageSize, pageNumber); 
320
		}
321
		
322
		return new DefaultPagerImpl<TaxonBase>(pageNumber, numberOfResults, pageSize, results);
323
	}
324

    
325
	
326
	public Pager<IdentifiableEntity> findTaxaAndNames(ITaxonServiceConfigurator configurator) {
327
		
328
		List<IdentifiableEntity> results = new ArrayList<IdentifiableEntity>();
329
		int numberOfResults = 0;
330
		List<TaxonBase> taxa = null; 
331
		int taxaCount = 0;
332
		int numberTaxaResults = 0;
333
		boolean isMisappliedName = false;
334
		
335
		// Taxa and synonyms
336
		
337
		if (configurator.isDoTaxa() && configurator.isDoSynonyms()) {
338
			taxa = dao.getTaxaByName(configurator.getSearchString(), configurator.getMatchMode(),
339
						SelectMode.ALL, configurator.getPageSize(), configurator.getPageNumber());
340
			numberTaxaResults = dao.countTaxaByName(configurator.getSearchString(), configurator.getMatchMode(), true);
341
			
342
		} else if(configurator.isDoTaxa()) {
343
			taxa = dao.getTaxaByName(configurator.getSearchString(), configurator.getMatchMode(),
344
						true, configurator.getPageSize(), configurator.getPageNumber());
345
			numberTaxaResults = dao.countTaxaByName(configurator.getSearchString(), configurator.getMatchMode(), true);
346
			
347
		} else if (configurator.isDoSynonyms()) {
348
			taxa = dao.getTaxaByName(configurator.getSearchString(), configurator.getMatchMode(),
349
					false, configurator.getPageSize(), configurator.getPageNumber());
350
			numberTaxaResults = dao.countTaxaByName(configurator.getSearchString(), configurator.getMatchMode(), false);
351
		}
352

    
353
		if (logger.isDebugEnabled()) { logger.debug(numberTaxaResults + " matching taxa counted"); }
354
		
355
		results.addAll(taxa);
356
		
357
		numberOfResults += numberTaxaResults;
358
		
359
		// Names without taxa 
360
		
361
		if (configurator.isDoNamesWithoutTaxa()) {
362
            int numberNameResults = 0;
363
			List<? extends TaxonNameBase<?,?>> names = 
364
				nameDao.findByName(configurator.getSearchString(), configurator.getMatchMode(), 
365
						configurator.getPageSize(), configurator.getPageNumber(), null);
366
			if (logger.isDebugEnabled()) { logger.debug(names.size() + " matching name(s) found"); }
367
			if (names.size() > 0) {
368
				for (TaxonNameBase<?,?> taxonName : names) {
369
					if (taxonName.getTaxonBases().size() == 0) {
370
						results.add(taxonName);
371
						numberNameResults++;
372
					}
373
				}
374
				if (logger.isDebugEnabled()) { logger.debug(numberNameResults + " matching name(s) without taxa found"); }
375
				numberOfResults += numberNameResults;
376
			}
377
		}
378
		
379
		// Taxa from common names
380
		
381
		if (configurator.isDoTaxaByCommonNames()) {
382
			int numberCommonNameResults = 0;
383
			List<CommonTaxonName> commonTaxonNames = 
384
				descriptionDao.searchDescriptionByCommonName(configurator.getSearchString(), 
385
						configurator.getMatchMode(), configurator.getPageSize(), configurator.getPageNumber());
386
			if (logger.isDebugEnabled()) { logger.debug(commonTaxonNames.size() + " matching common name(s) found"); }
387
			if (commonTaxonNames.size() > 0) {
388
				for (CommonTaxonName commonTaxonName : commonTaxonNames) {
389
					DescriptionBase description = commonTaxonName.getInDescription();
390
					description = HibernateProxyHelper.deproxy(description, DescriptionBase.class);
391
					if (description instanceof TaxonDescription) {
392
						TaxonDescription taxonDescription = HibernateProxyHelper.deproxy(description, TaxonDescription.class);
393
						Taxon taxon = taxonDescription.getTaxon();
394
						taxon = HibernateProxyHelper.deproxy(taxon, Taxon.class);
395
						if (!results.contains(taxon) && !taxon.isMisappliedName()) {
396
							results.add(taxon);
397
							numberCommonNameResults++;
398
						}
399
					} else {
400
						logger.warn("Description of " + commonTaxonName.getName() + " is not an instance of TaxonDescription");
401
					}
402
				}
403
				numberOfResults += numberCommonNameResults;
404
			} 
405
		}
406
		
407
		Collections.sort(results);
408
		return new DefaultPagerImpl<IdentifiableEntity>
409
			(configurator.getPageNumber(), numberOfResults, configurator.getPageSize(), results);
410
	}
411
	
412
}
(26-26/28)