Project

General

Profile

Download (22.9 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy 
5
* http://www.e-taxonomy.eu
6
* 
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10

    
11
package eu.etaxonomy.cdm.api.service;
12

    
13
import java.util.ArrayList;
14
import java.util.Comparator;
15
import java.util.HashSet;
16
import java.util.List;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import org.apache.log4j.Logger;
21
import org.springframework.beans.factory.annotation.Autowired;
22
import org.springframework.stereotype.Service;
23
import org.springframework.transaction.annotation.Transactional;
24

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

    
59

    
60
@Service
61
@Transactional(readOnly = true)
62
public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDao> implements ITaxonService{
63
	private static final Logger logger = Logger.getLogger(TaxonServiceImpl.class);
64

    
65
	@Autowired
66
	private ITaxonNameDao nameDao;
67
	
68

    
69
	@Autowired
70
	private IOrderedTermVocabularyDao orderedVocabularyDao;
71
	@Autowired
72
	private IDescriptionDao descriptionDao;
73
	@Autowired
74
	private BeanInitializer defaultBeanInitializer;
75
	
76
	private Comparator<? super TaxonNode> taxonNodeComparator;
77
	@Autowired
78
	public void setTaxonNodeComparator(ITaxonNodeComparator<? super TaxonNode> taxonNodeComparator){
79
		this.taxonNodeComparator = (Comparator<? super TaxonNode>) taxonNodeComparator;
80
	}
81
	
82
	/**
83
	 * Constructor
84
	 */
85
	public TaxonServiceImpl(){
86
		if (logger.isDebugEnabled()) { logger.debug("Load TaxonService Bean"); }
87
	}
88

    
89
	/**
90
	 * FIXME Candidate for harmonization
91
	 * rename searchByName ? 
92
	 */
93
	public List<TaxonBase> searchTaxaByName(String name, ReferenceBase sec) {
94
		return dao.getTaxaByName(name, sec);
95
	}
96
	
97
	/**
98
	 * FIXME Candidate for harmonization
99
	 * list(Synonym.class, ...)
100
	 *  (non-Javadoc)
101
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllSynonyms(int, int)
102
	 */
103
	public List<Synonym> getAllSynonyms(int limit, int start) {
104
		return dao.getAllSynonyms(limit, start);
105
	}
106
	
107
	/**
108
	 * FIXME Candidate for harmonization
109
	 * list(Taxon.class, ...)
110
	 *  (non-Javadoc)
111
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllTaxa(int, int)
112
	 */
113
	public List<Taxon> getAllTaxa(int limit, int start) {
114
		return dao.getAllTaxa(limit, start);
115
	}
116

    
117

    
118
	/**
119
	 * FIXME Candidate for harmonization
120
	 * merge with getRootTaxa(ReferenceBase sec, ..., ...)
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
	/**
129
	 * FIXME Candidate for harmonization
130
	 * merge with getRootTaxa(ReferenceBase sec, ..., ...)
131
	 *  (non-Javadoc)
132
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean)
133
	 */
134
	public List<Taxon> getRootTaxa(ReferenceBase sec, CdmFetch cdmFetch, boolean onlyWithChildren) {
135
		if (cdmFetch == null){
136
			cdmFetch = CdmFetch.NO_FETCH();
137
		}
138
		return dao.getRootTaxa(sec, cdmFetch, onlyWithChildren, false);
139
	}
140
	
141
	/**
142
 	 * FIXME Candidate for harmonization
143
	 * merge with getRootTaxa(ReferenceBase sec, ..., ...)
144
	 *  (non-Javadoc)
145
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean, boolean)
146
	 */
147
	public List<Taxon> getRootTaxa(ReferenceBase sec, boolean onlyWithChildren,
148
			boolean withMisapplications) {
149
		return dao.getRootTaxa(sec, null, onlyWithChildren, withMisapplications);
150
	}
151

    
152
	/* (non-Javadoc)
153
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.ReferenceBase, boolean, boolean)
154
	 */
155
	public List<Taxon> getRootTaxa(Rank rank, ReferenceBase sec, boolean onlyWithChildren,
156
			boolean withMisapplications, List<String> propertyPaths) {
157
		return dao.getRootTaxa(rank, sec, null, onlyWithChildren, withMisapplications, propertyPaths);
158
	}
159

    
160
	public List<RelationshipBase> getAllRelationships(int limit, int start){
161
		return dao.getAllRelationships(limit, start);
162
	}
163
	
164
	/**
165
	 * FIXME Candidate for harmonization
166
	 * is this the same as termService.getVocabulary(VocabularyEnum.TaxonRelationshipType) ? 
167
	 */
168
	@Deprecated
169
	public OrderedTermVocabulary<TaxonRelationshipType> getTaxonRelationshipTypeVocabulary() {
170
		
171
		String taxonRelTypeVocabularyId = "15db0cf7-7afc-4a86-a7d4-221c73b0c9ac";
172
		UUID uuid = UUID.fromString(taxonRelTypeVocabularyId);
173
		OrderedTermVocabulary<TaxonRelationshipType> taxonRelTypeVocabulary = 
174
			(OrderedTermVocabulary)orderedVocabularyDao.findByUuid(uuid);
175
		return taxonRelTypeVocabulary;
176
	}
177

    
178
	/* (non-Javadoc)
179
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#makeTaxonSynonym(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.Taxon)
180
	 */
181
	@Transactional(readOnly = false)
182
	public Synonym makeTaxonSynonym(Taxon oldTaxon, Taxon newAcceptedTaxon, SynonymRelationshipType synonymRelationshipType, ReferenceBase citation, String citationMicroReference) {
183
		if (oldTaxon == null || newAcceptedTaxon == null || oldTaxon.getName() == null){
184
			throw new IllegalArgumentException();
185
		}
186
		
187
		// Move oldTaxon to newTaxon
188
		TaxonNameBase<?,?> synonymName = oldTaxon.getName();
189
		if (synonymRelationshipType == null){
190
			if (synonymName.isHomotypic(newAcceptedTaxon.getName())){
191
				synonymRelationshipType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
192
			}else{
193
				//TODO synonymType 
194
				synonymRelationshipType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
195
			}
196
		}
197
		SynonymRelationship synRel = newAcceptedTaxon.addSynonymName(synonymName, synonymRelationshipType, citation, citationMicroReference);
198
		
199
		//Move Synonym Relations to new Taxon
200
		for(SynonymRelationship synRelation : oldTaxon.getSynonymRelations()){
201
			newAcceptedTaxon.addSynonym(synRelation.getSynonym(), synRelation.getType(), 
202
					synRelation.getCitation(), synRelation.getCitationMicroReference());
203
		}
204

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

    
268
	/*
269
	 * (non-Javadoc)
270
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#swapSynonymWithAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym)
271
	 */
272
	@Transactional(readOnly = false)
273
	public void swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, SynonymRelationshipType synonymRelationshipType){
274
		
275
		// create a new synonym with the old acceptedName
276
		TaxonNameBase oldAcceptedTaxonName = acceptedTaxon.getName();
277
		
278
		// remove synonym from oldAcceptedTaxon
279
		acceptedTaxon.removeSynonym(synonym);
280
		
281
		// make synonym name the accepted taxons name
282
		TaxonNameBase newAcceptedTaxonName = synonym.getName();
283
		acceptedTaxon.setName(newAcceptedTaxonName);
284
		
285
		// add the new synonym to the acceptedTaxon
286
		if(synonymRelationshipType == null){
287
			synonymRelationshipType = SynonymRelationshipType.SYNONYM_OF();
288
		}
289
		
290
		acceptedTaxon.addSynonymName(oldAcceptedTaxonName, synonymRelationshipType);
291
	}
292
	
293
	/*
294
	 * (non-Javadoc)
295
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#makeSynonymAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.Taxon)
296
	 */
297
	public Taxon makeSynonymAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon){
298
		
299
		Taxon newAcceptedTaxon = Taxon.NewInstance(synonym.getName(), acceptedTaxon.getSec());
300
		
301
		acceptedTaxon.removeSynonym(synonym);
302
		
303
		return newAcceptedTaxon;
304
	}
305

    
306
	public void generateTitleCache() {
307
		generateTitleCache(true);
308
	}
309
	//TODO
310
	public void generateTitleCache(boolean forceProtected) {
311
		logger.warn("generateTitleCache not yet fully implemented!");
312
	}
313

    
314
	@Autowired
315
	protected void setDao(ITaxonDao dao) {
316
		this.dao = dao;
317
	}
318

    
319
	public Pager<TaxonBase> findTaxaByName(Class<? extends TaxonBase> clazz, String uninomial,	String infragenericEpithet, String specificEpithet,	String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) {
320
        Integer numberOfResults = dao.countTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank);
321
		
322
		List<TaxonBase> results = new ArrayList<TaxonBase>();
323
		if(numberOfResults > 0) { // no point checking again
324
			results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber); 
325
		}
326
		
327
		return new DefaultPagerImpl<TaxonBase>(pageNumber, numberOfResults, pageSize, results);
328
	}
329

    
330
	public List<TaxonRelationship> listToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
331
		Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedTo);
332
		
333
		List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
334
		if(numberOfResults > 0) { // no point checking again
335
			results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo); 
336
		}
337
		return results;
338
	}
339
	
340
	public Pager<TaxonRelationship> pageToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
341
        Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedTo);
342
		
343
		List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
344
		if(numberOfResults > 0) { // no point checking again
345
			results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo); 
346
		}
347
		return new DefaultPagerImpl<TaxonRelationship>(pageNumber, numberOfResults, pageSize, results);
348
	}
349
	
350
	public List<TaxonRelationship> listFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
351
		Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedFrom);
352
		
353
		List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
354
		if(numberOfResults > 0) { // no point checking again
355
			results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom); 
356
		}
357
		return results;
358
	}
359
	
360
	public Pager<TaxonRelationship> pageFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
361
        Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedFrom);
362
		
363
		List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
364
		if(numberOfResults > 0) { // no point checking again
365
			results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom); 
366
		}
367
		return new DefaultPagerImpl<TaxonRelationship>(pageNumber, numberOfResults, pageSize, results);
368
	}
369

    
370
	public Pager<SynonymRelationship> getSynonyms(Taxon taxon,	SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
371
        Integer numberOfResults = dao.countSynonyms(taxon, type);
372
		
373
		List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();
374
		if(numberOfResults > 0) { // no point checking again
375
			results = dao.getSynonyms(taxon, type, pageSize, pageNumber, orderHints, propertyPaths); 
376
		}
377
		
378
		return new DefaultPagerImpl<SynonymRelationship>(pageNumber, numberOfResults, pageSize, results);
379
	}
380
	
381
	public Pager<SynonymRelationship> getSynonyms(Synonym synonym,	SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
382
        Integer numberOfResults = dao.countSynonyms(synonym, type);
383
		
384
		List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();
385
		if(numberOfResults > 0) { // no point checking again
386
			results = dao.getSynonyms(synonym, type, pageSize, pageNumber, orderHints, propertyPaths); 
387
		}
388
		
389
		return new DefaultPagerImpl<SynonymRelationship>(pageNumber, numberOfResults, pageSize, results);
390
	}
391
	
392
	public List<Synonym> getHomotypicSynonymsByHomotypicGroup(Taxon taxon, List<String> propertyPaths){
393
		Taxon t = (Taxon)dao.load(taxon.getUuid(), propertyPaths);
394
		return t.getHomotypicSynonymsByHomotypicGroup();
395
	}
396
	
397
	public List<List<Synonym>> getHeterotypicSynonymyGroups(Taxon taxon, List<String> propertyPaths){
398
		Taxon t = (Taxon)dao.load(taxon.getUuid(), propertyPaths);
399
		List<HomotypicalGroup> hsgl = t.getHeterotypicSynonymyGroups();
400
		List<List<Synonym>> heterotypicSynonymyGroups = new ArrayList<List<Synonym>>(hsgl.size());
401
		for(HomotypicalGroup hsg : hsgl){
402
			heterotypicSynonymyGroups.add(hsg.getSynonymsInGroup(t.getSec()));
403
		}
404
		return heterotypicSynonymyGroups;
405
	}
406

    
407
	public Pager<TaxonBase> search(Class<? extends TaxonBase> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
408
        Integer numberOfResults = dao.count(clazz,queryString);
409
		
410
		List<TaxonBase> results = new ArrayList<TaxonBase>();
411
		if(numberOfResults > 0) { // no point checking again
412
			results = dao.search(clazz,queryString, pageSize, pageNumber, orderHints, propertyPaths); 
413
		}
414
		
415
		return new DefaultPagerImpl<TaxonBase>(pageNumber, numberOfResults, pageSize, results);
416
	}
417

    
418
	
419
	public Pager<IdentifiableEntity> findTaxaAndNames(ITaxonServiceConfigurator configurator) {
420
		
421
		List<IdentifiableEntity> results = new ArrayList<IdentifiableEntity>();
422
		int numberOfResults = 0; // overall number of results (as opposed to number of results per page)
423
		List<TaxonBase> taxa = null; 
424

    
425
		// Taxa and synonyms
426
		long numberTaxaResults = 0L;
427
		
428
		Class<? extends TaxonBase> clazz = null;
429
		if (configurator.isDoTaxa() && configurator.isDoSynonyms()) {
430
			clazz = TaxonBase.class;
431
		} else if(configurator.isDoTaxa()) {
432
			clazz = Taxon.class;
433
		} else if (configurator.isDoSynonyms()) {
434
			clazz = Synonym.class;
435
		}
436
		
437
		if(clazz != null){
438
			numberTaxaResults = 
439
				dao.countTaxaByName(clazz, 
440
					configurator.getSearchString(), configurator.getTaxonomicTree(), configurator.getMatchMode(),
441
					configurator.getNamedAreas());
442
			if(numberTaxaResults > configurator.getPageSize() * configurator.getPageNumber()){ // no point checking again if less results
443
				taxa = dao.getTaxaByName(clazz, 
444
					configurator.getSearchString(), configurator.getTaxonomicTree(), configurator.getMatchMode(),
445
					configurator.getNamedAreas(), configurator.getPageSize(), 
446
					configurator.getPageNumber(), configurator.getTaxonPropertyPath());
447
			}
448
		}
449

    
450
		if (logger.isDebugEnabled()) { logger.debug(numberTaxaResults + " matching taxa counted"); }
451
		
452
		if(taxa != null){
453
			results.addAll(taxa);
454
		}
455
		
456
		numberOfResults += numberTaxaResults;
457
		
458
		// Names without taxa 
459
		
460
		if (configurator.isDoNamesWithoutTaxa()) {
461
            int numberNameResults = 0;
462
            //FIXME implement search by area
463
			List<? extends TaxonNameBase<?,?>> names = 
464
				nameDao.findByName(configurator.getSearchString(), configurator.getMatchMode(), 
465
						configurator.getPageSize(), configurator.getPageNumber(), null, null);
466
			if (logger.isDebugEnabled()) { logger.debug(names.size() + " matching name(s) found"); }
467
			if (names.size() > 0) {
468
				for (TaxonNameBase<?,?> taxonName : names) {
469
					if (taxonName.getTaxonBases().size() == 0) {
470
						results.add(taxonName);
471
						numberNameResults++;
472
					}
473
				}
474
				if (logger.isDebugEnabled()) { logger.debug(numberNameResults + " matching name(s) without taxa found"); }
475
				numberOfResults += numberNameResults;
476
			}
477
		}
478
		
479
		// Taxa from common names
480
		// FIXME the matching common names also must be returned
481
		// FIXME implement search by area
482
		if (configurator.isDoTaxaByCommonNames()) {
483
			int numberCommonNameResults = 0;
484
			List<CommonTaxonName> commonTaxonNames = 
485
				descriptionDao.searchDescriptionByCommonName(configurator.getSearchString(), 
486
						configurator.getMatchMode(), configurator.getPageSize(), configurator.getPageNumber());
487
			if (logger.isDebugEnabled()) { logger.debug(commonTaxonNames.size() + " matching common name(s) found"); }
488
			if (commonTaxonNames.size() > 0) {
489
				for (CommonTaxonName commonTaxonName : commonTaxonNames) {
490
					DescriptionBase description = commonTaxonName.getInDescription();
491
					description = HibernateProxyHelper.deproxy(description, DescriptionBase.class);
492
					if (description instanceof TaxonDescription) {
493
						TaxonDescription taxonDescription = HibernateProxyHelper.deproxy(description, TaxonDescription.class);
494
						Taxon taxon = taxonDescription.getTaxon();
495
						taxon = HibernateProxyHelper.deproxy(taxon, Taxon.class);
496
						if (!results.contains(taxon) && !taxon.isMisappliedName()) {
497
							defaultBeanInitializer.initialize(taxon, configurator.getTaxonPropertyPath());
498
							results.add(taxon);
499
							numberCommonNameResults++;
500
						}
501
					} else {
502
						logger.warn("Description of " + commonTaxonName.getName() + " is not an instance of TaxonDescription");
503
					}
504
				}
505
				numberOfResults += numberCommonNameResults;
506
			} 
507
		}
508
		
509
		//FIXME does not work any more after model change
510
		logger.warn("Sort does currently not work on identifiable entities due to model changes (duplicated implementation of the Comparable interface).");
511
		//Collections.sort(results);
512
		return new DefaultPagerImpl<IdentifiableEntity>
513
			(configurator.getPageNumber(), numberOfResults, configurator.getPageSize(), results);
514
	}
515
	
516
	public List<UuidAndTitleCache<TaxonBase>> getTaxonUuidAndTitleCache(){
517
		return dao.getUuidAndTitleCache();
518
	}
519

    
520
	public List<MediaRepresentation> getAllMedia(Taxon taxon, int size, int height, int widthOrDuration, String[] mimeTypes){
521
		List<MediaRepresentation> medRep = new ArrayList<MediaRepresentation>();
522
		taxon = (Taxon)dao.load(taxon.getUuid());
523
		Set<TaxonDescription> descriptions = taxon.getDescriptions();
524
		for (TaxonDescription taxDesc: descriptions){
525
			Set<DescriptionElementBase> elements = taxDesc.getElements();
526
			for (DescriptionElementBase descElem: elements){
527
				for(Media media : descElem.getMedia()){
528
									
529
					//find the best matching representation
530
					medRep.add(media.findBestMatchingRepresentation(size, height, widthOrDuration, mimeTypes));
531
					
532
				}
533
			}
534
		}
535
		return medRep;
536
	}
537
}
(43-43/48)