Project

General

Profile

« Previous | Next » 

Revision 76f89a6f

Added by Andreas Kohlbecker over 12 years ago

removing unused private class TaxonAndNameComparator

View differences:

cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/TaxonServiceImpl.java
1 1
// $Id$
2 2
/**
3 3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy 
4
* European Distributed Institute of Taxonomy
5 5
* http://www.e-taxonomy.eu
6
* 
6
*
7 7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8 8
* See LICENSE.TXT at the top of this package for the full license terms.
9 9
*/
......
68 68
@Service
69 69
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
70 70
public class TaxonServiceImpl extends IdentifiableServiceBase<TaxonBase,ITaxonDao> implements ITaxonService{
71
	private static final Logger logger = Logger.getLogger(TaxonServiceImpl.class);
72

  
73
	@Autowired
74
	private ITaxonNameDao nameDao;
75
	
76
	@Autowired
77
	private IOrderedTermVocabularyDao orderedVocabularyDao;
78
	
79
	/**
80
	 * Constructor
81
	 */
82
	public TaxonServiceImpl(){
83
		if (logger.isDebugEnabled()) { logger.debug("Load TaxonService Bean"); }
84
	}
85

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

  
114
	/**
115
	 * FIXME Candidate for harmonization
116
	 * merge with getRootTaxa(Reference sec, ..., ...)
117
	 *  (non-Javadoc)
118
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, boolean)
119
	 */
120
	public List<Taxon> getRootTaxa(Reference sec, CdmFetch cdmFetch, boolean onlyWithChildren) {
121
		if (cdmFetch == null){
122
			cdmFetch = CdmFetch.NO_FETCH();
123
		}
124
		return dao.getRootTaxa(sec, cdmFetch, onlyWithChildren, false);
125
	}
126

  
127

  
128
	/* (non-Javadoc)
129
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.Reference, boolean, boolean)
130
	 */
131
	public List<Taxon> getRootTaxa(Rank rank, Reference sec, boolean onlyWithChildren,boolean withMisapplications, List<String> propertyPaths) {
132
		return dao.getRootTaxa(rank, sec, null, onlyWithChildren, withMisapplications, propertyPaths);
133
	}
134

  
135
	/* (non-Javadoc)
136
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllRelationships(int, int)
137
	 */
138
	public List<RelationshipBase> getAllRelationships(int limit, int start){
139
		return dao.getAllRelationships(limit, start);
140
	}
141
	
142
	/**
143
	 * FIXME Candidate for harmonization
144
	 * is this the same as termService.getVocabulary(VocabularyEnum.TaxonRelationshipType) ? 
145
	 */
146
	@Deprecated
147
	public OrderedTermVocabulary<TaxonRelationshipType> getTaxonRelationshipTypeVocabulary() {
148
		
149
		String taxonRelTypeVocabularyId = "15db0cf7-7afc-4a86-a7d4-221c73b0c9ac";
150
		UUID uuid = UUID.fromString(taxonRelTypeVocabularyId);
151
		OrderedTermVocabulary<TaxonRelationshipType> taxonRelTypeVocabulary = 
152
			(OrderedTermVocabulary)orderedVocabularyDao.findByUuid(uuid);
153
		return taxonRelTypeVocabulary;
154
	}
155

  
156
	
157

  
158
	/*
159
	 * (non-Javadoc)
160
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#swapSynonymWithAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym)
161
	 */
162
	@Transactional(readOnly = false)
163
	public void swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon){
164
		
165
		TaxonNameBase synonymName = synonym.getName();
166
		synonymName.removeTaxonBase(synonym);
167
		TaxonNameBase taxonName = acceptedTaxon.getName();
168
		taxonName.removeTaxonBase(acceptedTaxon);
169
		
170
		synonym.setName(taxonName);
171
		acceptedTaxon.setName(synonymName);
172
		
173
		// the accepted taxon needs a new uuid because the concept has changed
174
		// FIXME this leads to an error "HibernateException: immutable natural identifier of an instance of eu.etaxonomy.cdm.model.taxon.Taxon was altered"
175
		//acceptedTaxon.setUuid(UUID.randomUUID());
176
	}
177
		
178
	
179
	/* (non-Javadoc)
180
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#changeSynonymToAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.Taxon)
181
	 */
182
	//TODO correct delete handling still needs to be implemented / checked
183
	@Override
184
	@Transactional(readOnly = false)
185
	public Taxon changeSynonymToAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean deleteSynonym, boolean copyCitationInfo, Reference citation, String microCitation) throws IllegalArgumentException{
186
		
187
		TaxonNameBase acceptedName = acceptedTaxon.getName();
188
		TaxonNameBase synonymName = synonym.getName();
189
		HomotypicalGroup synonymHomotypicGroup = synonymName.getHomotypicalGroup();
190
		if (acceptedName.getHomotypicalGroup().equals(synonymHomotypicGroup)){
191
			String message = "The accepted taxon and the synonym are part of the same homotypical group and therefore can not be both accepted.";
192
			throw new IllegalArgumentException(message);
193
		}
194
		
195
		Taxon newAcceptedTaxon = Taxon.NewInstance(synonymName, acceptedTaxon.getSec());
196
		
197
		SynonymRelationshipType relType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
198
		List<Synonym> heteroSynonyms = synonymHomotypicGroup.getSynonymsInGroup(acceptedTaxon.getSec());
199
		for (Synonym heteroSynonym : heteroSynonyms){
200
			if (synonym.equals(heteroSynonym)){
201
				acceptedTaxon.removeSynonym(heteroSynonym, false);
202
			}else{
203
				heteroSynonym.replaceAcceptedTaxon(newAcceptedTaxon, relType, copyCitationInfo, citation, microCitation);
204
			}
205
		}
206
		
207
		//synonym.getName().removeTaxonBase(synonym);
208
		//TODO correct delete handling still needs to be implemented / checked
209
		if (deleteSynonym){
210
			try {
211
				this.dao.flush();
212
				this.delete(synonym);
213
				
214
			} catch (Exception e) {
215
				logger.info("Can't delete old synonym from database");
216
			}
217
		}
218
		
219
	
220
		return newAcceptedTaxon;
221
	}
222
	
223
	public Taxon changeSynonymToRelatedTaxon(Synonym synonym, Taxon toTaxon, TaxonRelationshipType taxonRelationshipType, Reference citation, String microcitation){
224
		
225
		// Get name from synonym
226
		TaxonNameBase<?, ?> synonymName = synonym.getName();
227
		
228
		// remove synonym from taxon
229
		toTaxon.removeSynonym(synonym);
230
		
231
		// Create a taxon with synonym name
232
		Taxon fromTaxon = Taxon.NewInstance(synonymName, null);
233
		
234
		// Add taxon relation 
235
		fromTaxon.addTaxonRelation(toTaxon, taxonRelationshipType, citation, microcitation);
236
				
237
		// since we are swapping names, we have to detach the name from the synonym completely. 
238
		// Otherwise the synonym will still be in the list of typified names.
239
		synonym.getName().removeTaxonBase(synonym);
240
		
241
		return fromTaxon;
242
	}
243
	
244
	/* (non-Javadoc)
245
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#changeHomotypicalGroupOfSynonym(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.name.HomotypicalGroup, eu.etaxonomy.cdm.model.taxon.Taxon, boolean, boolean)
246
	 */
247
	@Transactional(readOnly = false)
248
	@Override
249
	public void changeHomotypicalGroupOfSynonym(Synonym synonym, HomotypicalGroup newHomotypicalGroup, Taxon targetTaxon, 
250
						boolean removeFromOtherTaxa, boolean setBasionymRelationIfApplicable){
251
    	// Get synonym name
252
		TaxonNameBase synonymName = synonym.getName();
253
		HomotypicalGroup oldHomotypicalGroup = synonymName.getHomotypicalGroup();
254
		
255
		
256
		// Switch groups
257
		oldHomotypicalGroup.removeTypifiedName(synonymName);
258
		newHomotypicalGroup.addTypifiedName(synonymName);
259
		
260
		//remove existing basionym relationships
261
		synonymName.removeBasionyms();
262
				
263
		//add basionym relationship
264
		if (setBasionymRelationIfApplicable){
265
			Set<TaxonNameBase> basionyms = newHomotypicalGroup.getBasionyms();
266
			for (TaxonNameBase basionym : basionyms){
267
				synonymName.addBasionym(basionym);
268
			}
269
		}
270

  
271
		//set synonym relationship correctly
71
    private static final Logger logger = Logger.getLogger(TaxonServiceImpl.class);
72

  
73
    @Autowired
74
    private ITaxonNameDao nameDao;
75

  
76
    @Autowired
77
    private IOrderedTermVocabularyDao orderedVocabularyDao;
78

  
79
    /**
80
     * Constructor
81
     */
82
    public TaxonServiceImpl(){
83
        if (logger.isDebugEnabled()) { logger.debug("Load TaxonService Bean"); }
84
    }
85

  
86
    /**
87
     * FIXME Candidate for harmonization
88
     * rename searchByName ?
89
     */
90
    public List<TaxonBase> searchTaxaByName(String name, Reference sec) {
91
        return dao.getTaxaByName(name, sec);
92
    }
93

  
94
    /**
95
     * FIXME Candidate for harmonization
96
     * list(Synonym.class, ...)
97
     *  (non-Javadoc)
98
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllSynonyms(int, int)
99
     */
100
    public List<Synonym> getAllSynonyms(int limit, int start) {
101
        return dao.getAllSynonyms(limit, start);
102
    }
103

  
104
    /**
105
     * FIXME Candidate for harmonization
106
     * list(Taxon.class, ...)
107
     *  (non-Javadoc)
108
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllTaxa(int, int)
109
     */
110
    public List<Taxon> getAllTaxa(int limit, int start) {
111
        return dao.getAllTaxa(limit, start);
112
    }
113

  
114
    /**
115
     * FIXME Candidate for harmonization
116
     * merge with getRootTaxa(Reference sec, ..., ...)
117
     *  (non-Javadoc)
118
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, boolean)
119
     */
120
    public List<Taxon> getRootTaxa(Reference sec, CdmFetch cdmFetch, boolean onlyWithChildren) {
121
        if (cdmFetch == null){
122
            cdmFetch = CdmFetch.NO_FETCH();
123
        }
124
        return dao.getRootTaxa(sec, cdmFetch, onlyWithChildren, false);
125
    }
126

  
127

  
128
    /* (non-Javadoc)
129
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.Reference, boolean, boolean)
130
     */
131
    public List<Taxon> getRootTaxa(Rank rank, Reference sec, boolean onlyWithChildren,boolean withMisapplications, List<String> propertyPaths) {
132
        return dao.getRootTaxa(rank, sec, null, onlyWithChildren, withMisapplications, propertyPaths);
133
    }
134

  
135
    /* (non-Javadoc)
136
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllRelationships(int, int)
137
     */
138
    public List<RelationshipBase> getAllRelationships(int limit, int start){
139
        return dao.getAllRelationships(limit, start);
140
    }
141

  
142
    /**
143
     * FIXME Candidate for harmonization
144
     * is this the same as termService.getVocabulary(VocabularyEnum.TaxonRelationshipType) ?
145
     */
146
    @Deprecated
147
    public OrderedTermVocabulary<TaxonRelationshipType> getTaxonRelationshipTypeVocabulary() {
148

  
149
        String taxonRelTypeVocabularyId = "15db0cf7-7afc-4a86-a7d4-221c73b0c9ac";
150
        UUID uuid = UUID.fromString(taxonRelTypeVocabularyId);
151
        OrderedTermVocabulary<TaxonRelationshipType> taxonRelTypeVocabulary =
152
            (OrderedTermVocabulary)orderedVocabularyDao.findByUuid(uuid);
153
        return taxonRelTypeVocabulary;
154
    }
155

  
156

  
157

  
158
    /*
159
     * (non-Javadoc)
160
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#swapSynonymWithAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym)
161
     */
162
    @Transactional(readOnly = false)
163
    public void swapSynonymAndAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon){
164

  
165
        TaxonNameBase synonymName = synonym.getName();
166
        synonymName.removeTaxonBase(synonym);
167
        TaxonNameBase taxonName = acceptedTaxon.getName();
168
        taxonName.removeTaxonBase(acceptedTaxon);
169

  
170
        synonym.setName(taxonName);
171
        acceptedTaxon.setName(synonymName);
172

  
173
        // the accepted taxon needs a new uuid because the concept has changed
174
        // FIXME this leads to an error "HibernateException: immutable natural identifier of an instance of eu.etaxonomy.cdm.model.taxon.Taxon was altered"
175
        //acceptedTaxon.setUuid(UUID.randomUUID());
176
    }
177

  
178

  
179
    /* (non-Javadoc)
180
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#changeSynonymToAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.Taxon)
181
     */
182
    //TODO correct delete handling still needs to be implemented / checked
183
    @Override
184
    @Transactional(readOnly = false)
185
    public Taxon changeSynonymToAcceptedTaxon(Synonym synonym, Taxon acceptedTaxon, boolean deleteSynonym, boolean copyCitationInfo, Reference citation, String microCitation) throws IllegalArgumentException{
186

  
187
        TaxonNameBase acceptedName = acceptedTaxon.getName();
188
        TaxonNameBase synonymName = synonym.getName();
189
        HomotypicalGroup synonymHomotypicGroup = synonymName.getHomotypicalGroup();
190
        if (acceptedName.getHomotypicalGroup().equals(synonymHomotypicGroup)){
191
            String message = "The accepted taxon and the synonym are part of the same homotypical group and therefore can not be both accepted.";
192
            throw new IllegalArgumentException(message);
193
        }
194

  
195
        Taxon newAcceptedTaxon = Taxon.NewInstance(synonymName, acceptedTaxon.getSec());
196

  
197
        SynonymRelationshipType relType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
198
        List<Synonym> heteroSynonyms = synonymHomotypicGroup.getSynonymsInGroup(acceptedTaxon.getSec());
199
        for (Synonym heteroSynonym : heteroSynonyms){
200
            if (synonym.equals(heteroSynonym)){
201
                acceptedTaxon.removeSynonym(heteroSynonym, false);
202
            }else{
203
                heteroSynonym.replaceAcceptedTaxon(newAcceptedTaxon, relType, copyCitationInfo, citation, microCitation);
204
            }
205
        }
206

  
207
        //synonym.getName().removeTaxonBase(synonym);
208
        //TODO correct delete handling still needs to be implemented / checked
209
        if (deleteSynonym){
210
            try {
211
                this.dao.flush();
212
                this.delete(synonym);
213

  
214
            } catch (Exception e) {
215
                logger.info("Can't delete old synonym from database");
216
            }
217
        }
218

  
219

  
220
        return newAcceptedTaxon;
221
    }
222

  
223
    public Taxon changeSynonymToRelatedTaxon(Synonym synonym, Taxon toTaxon, TaxonRelationshipType taxonRelationshipType, Reference citation, String microcitation){
224

  
225
        // Get name from synonym
226
        TaxonNameBase<?, ?> synonymName = synonym.getName();
227

  
228
        // remove synonym from taxon
229
        toTaxon.removeSynonym(synonym);
230

  
231
        // Create a taxon with synonym name
232
        Taxon fromTaxon = Taxon.NewInstance(synonymName, null);
233

  
234
        // Add taxon relation
235
        fromTaxon.addTaxonRelation(toTaxon, taxonRelationshipType, citation, microcitation);
236

  
237
        // since we are swapping names, we have to detach the name from the synonym completely.
238
        // Otherwise the synonym will still be in the list of typified names.
239
        synonym.getName().removeTaxonBase(synonym);
240

  
241
        return fromTaxon;
242
    }
243

  
244
    /* (non-Javadoc)
245
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#changeHomotypicalGroupOfSynonym(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.name.HomotypicalGroup, eu.etaxonomy.cdm.model.taxon.Taxon, boolean, boolean)
246
     */
247
    @Transactional(readOnly = false)
248
    @Override
249
    public void changeHomotypicalGroupOfSynonym(Synonym synonym, HomotypicalGroup newHomotypicalGroup, Taxon targetTaxon,
250
                        boolean removeFromOtherTaxa, boolean setBasionymRelationIfApplicable){
251
        // Get synonym name
252
        TaxonNameBase synonymName = synonym.getName();
253
        HomotypicalGroup oldHomotypicalGroup = synonymName.getHomotypicalGroup();
254

  
255

  
256
        // Switch groups
257
        oldHomotypicalGroup.removeTypifiedName(synonymName);
258
        newHomotypicalGroup.addTypifiedName(synonymName);
259

  
260
        //remove existing basionym relationships
261
        synonymName.removeBasionyms();
262

  
263
        //add basionym relationship
264
        if (setBasionymRelationIfApplicable){
265
            Set<TaxonNameBase> basionyms = newHomotypicalGroup.getBasionyms();
266
            for (TaxonNameBase basionym : basionyms){
267
                synonymName.addBasionym(basionym);
268
            }
269
        }
270

  
271
        //set synonym relationship correctly
272 272
//		SynonymRelationship relToTaxon = null;
273
		boolean relToTargetTaxonExists = false;
274
		Set<SynonymRelationship> existingRelations = synonym.getSynonymRelations();
275
		for (SynonymRelationship rel : existingRelations){
276
			Taxon acceptedTaxon = rel.getAcceptedTaxon();
277
			boolean isTargetTaxon = acceptedTaxon != null && acceptedTaxon.equals(targetTaxon);
278
			HomotypicalGroup acceptedGroup = acceptedTaxon.getHomotypicGroup();
279
			boolean isHomotypicToTaxon = acceptedGroup.equals(newHomotypicalGroup);
280
			SynonymRelationshipType newRelationType = isHomotypicToTaxon? SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF() : SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
281
			rel.setType(newRelationType);
282
			//TODO handle citation and microCitation
283
			
284
			if (isTargetTaxon){
285
				relToTargetTaxonExists = true;
286
			}else{
287
				if (removeFromOtherTaxa){
288
					acceptedTaxon.removeSynonym(synonym, false);
289
				}else{
290
					//do nothing
291
				}
292
			}
293
		}
294
		if (targetTaxon != null &&  ! relToTargetTaxonExists ){
295
			Taxon acceptedTaxon = targetTaxon;
296
			HomotypicalGroup acceptedGroup = acceptedTaxon.getHomotypicGroup();
297
			boolean isHomotypicToTaxon = acceptedGroup.equals(newHomotypicalGroup);
298
			SynonymRelationshipType relType = isHomotypicToTaxon? SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF() : SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
299
			//TODO handle citation and microCitation
300
			Reference citation = null;
301
			String microCitation = null;
302
			acceptedTaxon.addSynonym(synonym, relType, citation, microCitation);
303
		}
304

  
305
	}
306
	
307

  
308
	/* (non-Javadoc)
309
	 * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)
310
	 */
311
	@Override
312
	public void updateTitleCache(Class<? extends TaxonBase> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<TaxonBase> cacheStrategy, IProgressMonitor monitor) {
313
		if (clazz == null){
314
			clazz = TaxonBase.class;
315
		}
316
		super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
317
	}
318

  
319
	@Autowired
320
	protected void setDao(ITaxonDao dao) {
321
		this.dao = dao;
322
	}
323

  
324
	/* (non-Javadoc)
325
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer)
326
	 */
327
	public Pager<TaxonBase> findTaxaByName(Class<? extends TaxonBase> clazz, String uninomial,	String infragenericEpithet, String specificEpithet,	String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) {
273
        boolean relToTargetTaxonExists = false;
274
        Set<SynonymRelationship> existingRelations = synonym.getSynonymRelations();
275
        for (SynonymRelationship rel : existingRelations){
276
            Taxon acceptedTaxon = rel.getAcceptedTaxon();
277
            boolean isTargetTaxon = acceptedTaxon != null && acceptedTaxon.equals(targetTaxon);
278
            HomotypicalGroup acceptedGroup = acceptedTaxon.getHomotypicGroup();
279
            boolean isHomotypicToTaxon = acceptedGroup.equals(newHomotypicalGroup);
280
            SynonymRelationshipType newRelationType = isHomotypicToTaxon? SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF() : SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
281
            rel.setType(newRelationType);
282
            //TODO handle citation and microCitation
283

  
284
            if (isTargetTaxon){
285
                relToTargetTaxonExists = true;
286
            }else{
287
                if (removeFromOtherTaxa){
288
                    acceptedTaxon.removeSynonym(synonym, false);
289
                }else{
290
                    //do nothing
291
                }
292
            }
293
        }
294
        if (targetTaxon != null &&  ! relToTargetTaxonExists ){
295
            Taxon acceptedTaxon = targetTaxon;
296
            HomotypicalGroup acceptedGroup = acceptedTaxon.getHomotypicGroup();
297
            boolean isHomotypicToTaxon = acceptedGroup.equals(newHomotypicalGroup);
298
            SynonymRelationshipType relType = isHomotypicToTaxon? SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF() : SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
299
            //TODO handle citation and microCitation
300
            Reference citation = null;
301
            String microCitation = null;
302
            acceptedTaxon.addSynonym(synonym, relType, citation, microCitation);
303
        }
304

  
305
    }
306

  
307

  
308
    /* (non-Javadoc)
309
     * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)
310
     */
311
    @Override
312
    public void updateTitleCache(Class<? extends TaxonBase> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<TaxonBase> cacheStrategy, IProgressMonitor monitor) {
313
        if (clazz == null){
314
            clazz = TaxonBase.class;
315
        }
316
        super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
317
    }
318

  
319
    @Autowired
320
    protected void setDao(ITaxonDao dao) {
321
        this.dao = dao;
322
    }
323

  
324
    /* (non-Javadoc)
325
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer)
326
     */
327
    public Pager<TaxonBase> findTaxaByName(Class<? extends TaxonBase> clazz, String uninomial,	String infragenericEpithet, String specificEpithet,	String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) {
328 328
        Integer numberOfResults = dao.countTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank);
329
		
330
		List<TaxonBase> results = new ArrayList<TaxonBase>();
331
		if(numberOfResults > 0) { // no point checking again
332
			results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber); 
333
		}
334
		
335
		return new DefaultPagerImpl<TaxonBase>(pageNumber, numberOfResults, pageSize, results);
336
	}
337

  
338
	/* (non-Javadoc)
339
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#listTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer)
340
	 */
341
	public List<TaxonBase> listTaxaByName(Class<? extends TaxonBase> clazz, String uninomial,	String infragenericEpithet, String specificEpithet,	String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) {
329

  
330
        List<TaxonBase> results = new ArrayList<TaxonBase>();
331
        if(numberOfResults > 0) { // no point checking again
332
            results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber);
333
        }
334

  
335
        return new DefaultPagerImpl<TaxonBase>(pageNumber, numberOfResults, pageSize, results);
336
    }
337

  
338
    /* (non-Javadoc)
339
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#listTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer)
340
     */
341
    public List<TaxonBase> listTaxaByName(Class<? extends TaxonBase> clazz, String uninomial,	String infragenericEpithet, String specificEpithet,	String infraspecificEpithet, Rank rank, Integer pageSize,Integer pageNumber) {
342 342
        Integer numberOfResults = dao.countTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank);
343
		
344
		List<TaxonBase> results = new ArrayList<TaxonBase>();
345
		if(numberOfResults > 0) { // no point checking again
346
			results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber); 
347
		}
348
		
349
		return results;
350
	}
351

  
352
	/* (non-Javadoc)
353
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#listToTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
354
	 */
355
	public List<TaxonRelationship> listToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
356
		Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedTo);
357
		
358
		List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
359
		if(numberOfResults > 0) { // no point checking again
360
			results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo); 
361
		}
362
		return results;
363
	}
364
	
365
	/* (non-Javadoc)
366
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#pageToTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
367
	 */
368
	public Pager<TaxonRelationship> pageToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
343

  
344
        List<TaxonBase> results = new ArrayList<TaxonBase>();
345
        if(numberOfResults > 0) { // no point checking again
346
            results = dao.findTaxaByName(clazz, uninomial, infragenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber);
347
        }
348

  
349
        return results;
350
    }
351

  
352
    /* (non-Javadoc)
353
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#listToTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
354
     */
355
    public List<TaxonRelationship> listToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
356
        Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedTo);
357

  
358
        List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
359
        if(numberOfResults > 0) { // no point checking again
360
            results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo);
361
        }
362
        return results;
363
    }
364

  
365
    /* (non-Javadoc)
366
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#pageToTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
367
     */
368
    public Pager<TaxonRelationship> pageToTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
369 369
        Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedTo);
370
		
371
		List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
372
		if(numberOfResults > 0) { // no point checking again
373
			results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo); 
374
		}
375
		return new DefaultPagerImpl<TaxonRelationship>(pageNumber, numberOfResults, pageSize, results);
376
	}
377
	
378
	/* (non-Javadoc)
379
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#listFromTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
380
	 */
381
	public List<TaxonRelationship> listFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
382
		Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedFrom);
383
		
384
		List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
385
		if(numberOfResults > 0) { // no point checking again
386
			results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom); 
387
		}
388
		return results;
389
	}
390
	
391
	/* (non-Javadoc)
392
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#pageFromTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
393
	 */
394
	public Pager<TaxonRelationship> pageFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
370

  
371
        List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
372
        if(numberOfResults > 0) { // no point checking again
373
            results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedTo);
374
        }
375
        return new DefaultPagerImpl<TaxonRelationship>(pageNumber, numberOfResults, pageSize, results);
376
    }
377

  
378
    /* (non-Javadoc)
379
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#listFromTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
380
     */
381
    public List<TaxonRelationship> listFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths){
395 382
        Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedFrom);
396
		
397
		List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
398
		if(numberOfResults > 0) { // no point checking again
399
			results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom); 
400
		}
401
		return new DefaultPagerImpl<TaxonRelationship>(pageNumber, numberOfResults, pageSize, results);
402
	}
403

  
404
	/* (non-Javadoc)
405
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
406
	 */
407
	public Pager<SynonymRelationship> getSynonyms(Taxon taxon,	SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
383

  
384
        List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
385
        if(numberOfResults > 0) { // no point checking again
386
            results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom);
387
        }
388
        return results;
389
    }
390

  
391
    /* (non-Javadoc)
392
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#pageFromTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
393
     */
394
    public Pager<TaxonRelationship> pageFromTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
395
        Integer numberOfResults = dao.countTaxonRelationships(taxon, type, TaxonRelationship.Direction.relatedFrom);
396

  
397
        List<TaxonRelationship> results = new ArrayList<TaxonRelationship>();
398
        if(numberOfResults > 0) { // no point checking again
399
            results = dao.getTaxonRelationships(taxon, type, pageSize, pageNumber, orderHints, propertyPaths, TaxonRelationship.Direction.relatedFrom);
400
        }
401
        return new DefaultPagerImpl<TaxonRelationship>(pageNumber, numberOfResults, pageSize, results);
402
    }
403

  
404
    /* (non-Javadoc)
405
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
406
     */
407
    public Pager<SynonymRelationship> getSynonyms(Taxon taxon,	SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
408 408
        Integer numberOfResults = dao.countSynonyms(taxon, type);
409
		
410
		List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();
411
		if(numberOfResults > 0) { // no point checking again
412
			results = dao.getSynonyms(taxon, type, pageSize, pageNumber, orderHints, propertyPaths); 
413
		}
414
		
415
		return new DefaultPagerImpl<SynonymRelationship>(pageNumber, numberOfResults, pageSize, results);
416
	}
417
	
418
	/* (non-Javadoc)
419
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
420
	 */
421
	public Pager<SynonymRelationship> getSynonyms(Synonym synonym,	SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
409

  
410
        List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();
411
        if(numberOfResults > 0) { // no point checking again
412
            results = dao.getSynonyms(taxon, type, pageSize, pageNumber, orderHints, propertyPaths);
413
        }
414

  
415
        return new DefaultPagerImpl<SynonymRelationship>(pageNumber, numberOfResults, pageSize, results);
416
    }
417

  
418
    /* (non-Javadoc)
419
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
420
     */
421
    public Pager<SynonymRelationship> getSynonyms(Synonym synonym,	SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
422 422
        Integer numberOfResults = dao.countSynonyms(synonym, type);
423
		
424
		List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();
425
		if(numberOfResults > 0) { // no point checking again
426
			results = dao.getSynonyms(synonym, type, pageSize, pageNumber, orderHints, propertyPaths); 
427
		}
428
		
429
		return new DefaultPagerImpl<SynonymRelationship>(pageNumber, numberOfResults, pageSize, results);
430
	}
431
	
432
	/* (non-Javadoc)
433
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getHomotypicSynonymsByHomotypicGroup(eu.etaxonomy.cdm.model.taxon.Taxon, java.util.List)
434
	 */
435
	public List<Synonym> getHomotypicSynonymsByHomotypicGroup(Taxon taxon, List<String> propertyPaths){
436
		Taxon t = (Taxon)dao.load(taxon.getUuid(), propertyPaths);
437
		return t.getHomotypicSynonymsByHomotypicGroup();
438
	}
439
	
440
	/* (non-Javadoc)
441
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getHeterotypicSynonymyGroups(eu.etaxonomy.cdm.model.taxon.Taxon, java.util.List)
442
	 */
443
	public List<List<Synonym>> getHeterotypicSynonymyGroups(Taxon taxon, List<String> propertyPaths){
444
		Taxon t = (Taxon)dao.load(taxon.getUuid(), propertyPaths);
445
		List<HomotypicalGroup> hsgl = t.getHeterotypicSynonymyGroups();
446
		List<List<Synonym>> heterotypicSynonymyGroups = new ArrayList<List<Synonym>>(hsgl.size());
447
		for(HomotypicalGroup hsg : hsgl){
448
			heterotypicSynonymyGroups.add(hsg.getSynonymsInGroup(t.getSec()));
449
		}
450
		return heterotypicSynonymyGroups;
451
	}
452
	
453
	public List<UuidAndTitleCache<TaxonBase>> findTaxaAndNamesForEditor(ITaxonServiceConfigurator configurator){
454
		
455
		List<UuidAndTitleCache<TaxonBase>> result = new ArrayList<UuidAndTitleCache<TaxonBase>>();
456
		Class<? extends TaxonBase> clazz = null;
457
		if ((configurator.isDoTaxa() && configurator.isDoSynonyms())) {
458
			clazz = TaxonBase.class;
459
			//propertyPath.addAll(configurator.getTaxonPropertyPath());
460
			//propertyPath.addAll(configurator.getSynonymPropertyPath());
461
		} else if(configurator.isDoTaxa()) {
462
			clazz = Taxon.class;
463
			//propertyPath = configurator.getTaxonPropertyPath();
464
		} else if (configurator.isDoSynonyms()) {
465
			clazz = Synonym.class;
466
			//propertyPath = configurator.getSynonymPropertyPath();
467
		}
468
		
469
		
470
		result = dao.getTaxaByNameForEditor(clazz, configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas());
471
		return result;
472
	}
473
	/* (non-Javadoc)
474
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaAndNames(eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator)
475
	 */
476
	public Pager<IdentifiableEntity> findTaxaAndNames(ITaxonServiceConfigurator configurator) {
477
		
478
		List<IdentifiableEntity> results = new ArrayList<IdentifiableEntity>();
479
		int numberOfResults = 0; // overall number of results (as opposed to number of results per page)
480
		List<TaxonBase> taxa = null; 
481

  
482
		// Taxa and synonyms
483
		long numberTaxaResults = 0L;
484
		
485
		Class<? extends TaxonBase> clazz = null;
486
		List<String> propertyPath = new ArrayList<String>();
487
		if(configurator.getTaxonPropertyPath() != null){
488
			propertyPath.addAll(configurator.getTaxonPropertyPath());
489
		}
490
		if ((configurator.isDoTaxa() && configurator.isDoSynonyms())) {
491
			clazz = TaxonBase.class;
492
			//propertyPath.addAll(configurator.getTaxonPropertyPath());
493
			//propertyPath.addAll(configurator.getSynonymPropertyPath());
494
		} else if(configurator.isDoTaxa()) {
495
			clazz = Taxon.class;
496
			//propertyPath = configurator.getTaxonPropertyPath();
497
		} else if (configurator.isDoSynonyms()) {
498
			clazz = Synonym.class;
499
			//propertyPath = configurator.getSynonymPropertyPath();
500
		}
501
		
502
		if(clazz != null){
503
			if(configurator.getPageSize() != null){ // no point counting if we need all anyway
504
				numberTaxaResults = 
505
					dao.countTaxaByName(clazz, 
506
						configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(),
507
						configurator.getNamedAreas());
508
			}
509
			
510
			if(configurator.getPageSize() == null || numberTaxaResults > configurator.getPageSize() * configurator.getPageNumber()){ // no point checking again if less results
511
				taxa = dao.getTaxaByName(clazz, 
512
					configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(),
513
					configurator.getNamedAreas(), configurator.getPageSize(), 
514
					configurator.getPageNumber(), propertyPath);
515
			}
516
		}
517

  
518
		if (logger.isDebugEnabled()) { logger.debug(numberTaxaResults + " matching taxa counted"); }
519
		
520
		if(taxa != null){
521
			results.addAll(taxa);
522
		}
523
		
524
		numberOfResults += numberTaxaResults;
525

  
526
		// Names without taxa 
527
		if (configurator.isDoNamesWithoutTaxa()) {
423

  
424
        List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();
425
        if(numberOfResults > 0) { // no point checking again
426
            results = dao.getSynonyms(synonym, type, pageSize, pageNumber, orderHints, propertyPaths);
427
        }
428

  
429
        return new DefaultPagerImpl<SynonymRelationship>(pageNumber, numberOfResults, pageSize, results);
430
    }
431

  
432
    /* (non-Javadoc)
433
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getHomotypicSynonymsByHomotypicGroup(eu.etaxonomy.cdm.model.taxon.Taxon, java.util.List)
434
     */
435
    public List<Synonym> getHomotypicSynonymsByHomotypicGroup(Taxon taxon, List<String> propertyPaths){
436
        Taxon t = (Taxon)dao.load(taxon.getUuid(), propertyPaths);
437
        return t.getHomotypicSynonymsByHomotypicGroup();
438
    }
439

  
440
    /* (non-Javadoc)
441
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getHeterotypicSynonymyGroups(eu.etaxonomy.cdm.model.taxon.Taxon, java.util.List)
442
     */
443
    public List<List<Synonym>> getHeterotypicSynonymyGroups(Taxon taxon, List<String> propertyPaths){
444
        Taxon t = (Taxon)dao.load(taxon.getUuid(), propertyPaths);
445
        List<HomotypicalGroup> hsgl = t.getHeterotypicSynonymyGroups();
446
        List<List<Synonym>> heterotypicSynonymyGroups = new ArrayList<List<Synonym>>(hsgl.size());
447
        for(HomotypicalGroup hsg : hsgl){
448
            heterotypicSynonymyGroups.add(hsg.getSynonymsInGroup(t.getSec()));
449
        }
450
        return heterotypicSynonymyGroups;
451
    }
452

  
453
    public List<UuidAndTitleCache<TaxonBase>> findTaxaAndNamesForEditor(ITaxonServiceConfigurator configurator){
454

  
455
        List<UuidAndTitleCache<TaxonBase>> result = new ArrayList<UuidAndTitleCache<TaxonBase>>();
456
        Class<? extends TaxonBase> clazz = null;
457
        if ((configurator.isDoTaxa() && configurator.isDoSynonyms())) {
458
            clazz = TaxonBase.class;
459
            //propertyPath.addAll(configurator.getTaxonPropertyPath());
460
            //propertyPath.addAll(configurator.getSynonymPropertyPath());
461
        } else if(configurator.isDoTaxa()) {
462
            clazz = Taxon.class;
463
            //propertyPath = configurator.getTaxonPropertyPath();
464
        } else if (configurator.isDoSynonyms()) {
465
            clazz = Synonym.class;
466
            //propertyPath = configurator.getSynonymPropertyPath();
467
        }
468

  
469

  
470
        result = dao.getTaxaByNameForEditor(clazz, configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas());
471
        return result;
472
    }
473
    /* (non-Javadoc)
474
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaAndNames(eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator)
475
     */
476
    public Pager<IdentifiableEntity> findTaxaAndNames(ITaxonServiceConfigurator configurator) {
477

  
478
        List<IdentifiableEntity> results = new ArrayList<IdentifiableEntity>();
479
        int numberOfResults = 0; // overall number of results (as opposed to number of results per page)
480
        List<TaxonBase> taxa = null;
481

  
482
        // Taxa and synonyms
483
        long numberTaxaResults = 0L;
484

  
485
        Class<? extends TaxonBase> clazz = null;
486
        List<String> propertyPath = new ArrayList<String>();
487
        if(configurator.getTaxonPropertyPath() != null){
488
            propertyPath.addAll(configurator.getTaxonPropertyPath());
489
        }
490
        if ((configurator.isDoTaxa() && configurator.isDoSynonyms())) {
491
            clazz = TaxonBase.class;
492
            //propertyPath.addAll(configurator.getTaxonPropertyPath());
493
            //propertyPath.addAll(configurator.getSynonymPropertyPath());
494
        } else if(configurator.isDoTaxa()) {
495
            clazz = Taxon.class;
496
            //propertyPath = configurator.getTaxonPropertyPath();
497
        } else if (configurator.isDoSynonyms()) {
498
            clazz = Synonym.class;
499
            //propertyPath = configurator.getSynonymPropertyPath();
500
        }
501

  
502
        if(clazz != null){
503
            if(configurator.getPageSize() != null){ // no point counting if we need all anyway
504
                numberTaxaResults =
505
                    dao.countTaxaByName(clazz,
506
                        configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(),
507
                        configurator.getNamedAreas());
508
            }
509

  
510
            if(configurator.getPageSize() == null || numberTaxaResults > configurator.getPageSize() * configurator.getPageNumber()){ // no point checking again if less results
511
                taxa = dao.getTaxaByName(clazz,
512
                    configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(),
513
                    configurator.getNamedAreas(), configurator.getPageSize(),
514
                    configurator.getPageNumber(), propertyPath);
515
            }
516
        }
517

  
518
        if (logger.isDebugEnabled()) { logger.debug(numberTaxaResults + " matching taxa counted"); }
519

  
520
        if(taxa != null){
521
            results.addAll(taxa);
522
        }
523

  
524
        numberOfResults += numberTaxaResults;
525

  
526
        // Names without taxa
527
        if (configurator.isDoNamesWithoutTaxa()) {
528 528
            int numberNameResults = 0;
529
           
530
			List<? extends TaxonNameBase<?,?>> names = 
531
				nameDao.findByName(configurator.getTitleSearchStringSqlized(), configurator.getMatchMode(), 
532
						configurator.getPageSize(), configurator.getPageNumber(), null, configurator.getTaxonNamePropertyPath());
533
			if (logger.isDebugEnabled()) { logger.debug(names.size() + " matching name(s) found"); }
534
			if (names.size() > 0) {
535
				for (TaxonNameBase<?,?> taxonName : names) {
536
					if (taxonName.getTaxonBases().size() == 0) {
537
						results.add(taxonName);
538
						numberNameResults++;
539
					}
540
				}
541
				if (logger.isDebugEnabled()) { logger.debug(numberNameResults + " matching name(s) without taxa found"); }
542
				numberOfResults += numberNameResults;
543
			}
544
		}
545
		
546
		// Taxa from common names
547
		
548
		if (configurator.isDoTaxaByCommonNames()) {
549
			taxa = null;
550
			numberTaxaResults = 0;
551
			if(configurator.getPageSize() != null){// no point counting if we need all anyway
552
				numberTaxaResults = dao.countTaxaByCommonName(configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas());
553
			}
554
			if(configurator.getPageSize() == null || numberTaxaResults > configurator.getPageSize() * configurator.getPageNumber()){
555
				taxa = dao.getTaxaByCommonName(configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas(), configurator.getPageSize(), configurator.getPageNumber(), configurator.getTaxonPropertyPath());
556
			}
557
			if(taxa != null){
558
				results.addAll(taxa);
559
			}
560
			numberOfResults += numberTaxaResults;
561
			 
562
		}
563
		
564
	   return new DefaultPagerImpl<IdentifiableEntity>
565
			(configurator.getPageNumber(), numberOfResults, configurator.getPageSize(), results);
566
	}
567
	
568
	public List<UuidAndTitleCache<TaxonBase>> getTaxonUuidAndTitleCache(){
569
		return dao.getUuidAndTitleCache();
570
	}
571

  
572
	/* (non-Javadoc)
573
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllMedia(eu.etaxonomy.cdm.model.taxon.Taxon, int, int, int, java.lang.String[])
574
	 */
575
	public List<MediaRepresentation> getAllMedia(Taxon taxon, int size, int height, int widthOrDuration, String[] mimeTypes){
576
		List<MediaRepresentation> medRep = new ArrayList<MediaRepresentation>();
577
		taxon = (Taxon)dao.load(taxon.getUuid());
578
		Set<TaxonDescription> descriptions = taxon.getDescriptions();
579
		for (TaxonDescription taxDesc: descriptions){
580
			Set<DescriptionElementBase> elements = taxDesc.getElements();
581
			for (DescriptionElementBase descElem: elements){
582
				for(Media media : descElem.getMedia()){
583
									
584
					//find the best matching representation
585
					medRep.add(MediaUtils.findBestMatchingRepresentation(media, null, size, height, widthOrDuration, mimeTypes));
586
					
587
				}
588
			}
589
		}
590
		return medRep;
591
	}
592

  
593
	/* (non-Javadoc)
594
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaByID(java.util.Set)
595
	 */
596
	public List<TaxonBase> findTaxaByID(Set<Integer> listOfIDs) {
597
		return this.dao.findById(listOfIDs);
598
	}
599

  
600
	/* (non-Javadoc)
601
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#countAllRelationships()
602
	 */
603
	public int countAllRelationships() {
604
		return this.dao.countAllRelationships();
605
	}
606

  
607
	/* (non-Javadoc)
608
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#createAllInferredSynonyms(eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.taxon.Taxon)
609
	 */
610
	public List<Synonym> createAllInferredSynonyms(Classification tree,
611
			Taxon taxon) {
612
		
613
		return this.dao.createAllInferredSynonyms(taxon, tree);
614
	}
615

  
616
	/* (non-Javadoc)
617
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#createInferredSynonyms(eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)
618
	 */
619
	public List<Synonym> createInferredSynonyms(Classification tree, Taxon taxon, SynonymRelationshipType type) {
620
		
621
		return this.dao.createInferredSynonyms(taxon, tree, type);
622
	}
623

  
624
	/* (non-Javadoc)
625
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findIdenticalTaxonNames(java.util.List)
626
	 */
627
	public List<TaxonNameBase> findIdenticalTaxonNames(List<String> propertyPath) {
628
		
629
		return this.dao.findIdenticalTaxonNames(propertyPath);
630
	}
631
	
632
	/* (non-Javadoc)
633
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findIdenticalTaxonNameIds(java.util.List)
634
	 */
635
	public List<TaxonNameBase> findIdenticalTaxonNameIds(List<String> propertyPath) {
636
		
637
		return this.dao.findIdenticalNamesNew(propertyPath);
638
	}
639
	
640
	/* (non-Javadoc)
641
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getPhylumName(eu.etaxonomy.cdm.model.name.TaxonNameBase)
642
	 */
643
	public String getPhylumName(TaxonNameBase name){
644
		return this.dao.getPhylumName(name);
645
	}
646
	
647
	private class TaxonAndNameComparator implements Comparator{
648

  
649
		public int compare(Object arg0, Object arg1) {
650
			IdentifiableEntity castArg0 = (IdentifiableEntity) arg0;
651
			IdentifiableEntity castArg1 = (IdentifiableEntity) arg1;
652
			return castArg0.compareTo(castArg1);
653
		}
654
		
655
	}
656

  
657
	/* (non-Javadoc)
658
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#deleteSynonymRelationships(eu.etaxonomy.cdm.model.taxon.Synonym)
659
	 */
660
	public long deleteSynonymRelationships(Synonym syn) {
661
		
662
		return dao.deleteSynonymRelationships(syn);
663
	}
664

  
665
	
666
	/* (non-Javadoc)
667
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#listSynonymRelationships(eu.etaxonomy.cdm.model.taxon.TaxonBase, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction)
668
	 */
669
	public List<SynonymRelationship> listSynonymRelationships(
670
			TaxonBase taxonBase, SynonymRelationshipType type, Integer pageSize, Integer pageNumber,
671
			List<OrderHint> orderHints, List<String> propertyPaths, Direction direction) {
672
		Integer numberOfResults = dao.countSynonymRelationships(taxonBase, type, direction);
673
		
674
		List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();
675
		if(numberOfResults > 0) { // no point checking again
676
			results = dao.getSynonymRelationships(taxonBase, type, pageSize, pageNumber, orderHints, propertyPaths, direction); 
677
		}
678
		return results;
679
	}
680

  
681
	/* (non-Javadoc)
682
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findBestMatchingTaxon(java.lang.String)
683
	 */
684
	@Override
685
	public Taxon findBestMatchingTaxon(String taxonName) {
686
		MatchingTaxonConfigurator config = MatchingTaxonConfigurator.NewInstance();
687
		config.setTaxonNameTitle(taxonName);
688
		return findBestMatchingTaxon(config);
689
	}
690
	
691
	
692
	
693
	@Override
694
	public Taxon findBestMatchingTaxon(MatchingTaxonConfigurator config) {
695
		
696
		Taxon bestCandidate = null;
697
		try{
698
			// 1. search for acceptet taxa
699
			List<TaxonBase> taxonList = dao.findByNameTitleCache(Taxon.class, config.getTaxonNameTitle(), null, MatchMode.EXACT, null, 0, null, null);
700
			boolean bestCandidateMatchesSecUuid = false;
701
			boolean bestCandidateIsInClassification = false;
702
			int countEqualCandidates = 0;
703
			for(TaxonBase taxonBaseCandidate : taxonList){
704
				if(taxonBaseCandidate instanceof Taxon){
705
					Taxon newCanditate = CdmBase.deproxy(taxonBaseCandidate, Taxon.class);
706
					boolean newCandidateMatchesSecUuid = isMatchesSecUuid(newCanditate, config);
707
					if (! newCandidateMatchesSecUuid && config.isOnlyMatchingSecUuid() ){
708
						continue;
709
					}else if(newCandidateMatchesSecUuid && ! bestCandidateMatchesSecUuid){
710
						bestCandidate = newCanditate;
711
						countEqualCandidates = 1;
712
						bestCandidateMatchesSecUuid = true;
713
						continue;
714
					}
715
					
716
					boolean newCandidateInClassification = isInClassification(newCanditate, config);
717
					if (! newCandidateInClassification && config.isOnlyMatchingClassificationUuid()){
718
						continue;
719
					}else if (newCandidateInClassification && ! bestCandidateIsInClassification){
720
						bestCandidate = newCanditate;
721
						countEqualCandidates = 1;
722
						bestCandidateIsInClassification = true;
723
						continue;
724
					}
725
					if (bestCandidate == null){
726
						bestCandidate = newCanditate;
727
						countEqualCandidates = 1;
728
						continue;
729
					}
730
					
731
				}else{  //not Taxon.class
732
					continue;
733
				}
734
				countEqualCandidates++;
735

  
736
			}
737
			if (bestCandidate != null){
738
				if(countEqualCandidates > 1){
739
					logger.info(countEqualCandidates + " equally matching TaxonBases found, using first accepted Taxon: " + bestCandidate.getTitleCache());
740
					return bestCandidate;
741
				} else {
742
					logger.info("using accepted Taxon: " + bestCandidate.getTitleCache());
743
					return bestCandidate;
744
				}
745
			}
746
			
747
			
748
			// 2. search for synonyms
749
			if (config.isIncludeSynonyms()){
750
				List<TaxonBase> synonymList = dao.findByNameTitleCache(Synonym.class, config.getTaxonNameTitle(), null, MatchMode.EXACT, null, 0, null, null);
751
				for(TaxonBase taxonBase : synonymList){
752
					if(taxonBase instanceof Synonym){
753
						Synonym synonym = CdmBase.deproxy(taxonBase, Synonym.class);
754
						Set<Taxon> acceptetdCandidates = synonym.getAcceptedTaxa();
755
						if(!acceptetdCandidates.isEmpty()){
756
							bestCandidate = acceptetdCandidates.iterator().next();
757
							if(acceptetdCandidates.size() == 1){
758
								logger.info(acceptetdCandidates.size() + " Accepted taxa found for synonym " + taxonBase.getTitleCache() + ", using first one: " + bestCandidate.getTitleCache());
759
								return bestCandidate;
760
							} else {
761
								logger.info("using accepted Taxon " +  bestCandidate.getTitleCache() + "for synonym " + taxonBase.getTitleCache());
762
								return bestCandidate;
763
							}
764
							//TODO extend method: search using treeUUID, using SecUUID, first find accepted then include synonyms until a matching taxon is found
765
						}
766
					}
767
				}
768
			}
769
			
770
		} catch (Exception e){
771
			logger.error(e);
772
		}
773
		
774
		return bestCandidate;
775
	}
776

  
777
	private boolean isInClassification(Taxon taxon, MatchingTaxonConfigurator config) {
778
		UUID configClassificationUuid = config.getClassificationUuid();
779
		if (configClassificationUuid == null){
780
			return false;
781
		}
782
		for (TaxonNode node : taxon.getTaxonNodes()){
783
			UUID classUuid = node.getClassification().getUuid();
784
			if (configClassificationUuid.equals(classUuid)){
785
				return true;
786
			}
787
		}
788
		return false;
789
	}
790

  
791
	private boolean isMatchesSecUuid(Taxon taxon, MatchingTaxonConfigurator config) {
792
		UUID configSecUuid = config.getSecUuid();
793
		if (configSecUuid == null){
794
			return false;
795
		}
796
		UUID taxonSecUuid = (taxon.getSec() == null)? null : taxon.getSec().getUuid();
797
		return configSecUuid.equals(taxonSecUuid);
798
	}
799

  
800
	/* (non-Javadoc)
801
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findBestMatchingSynonym(java.lang.String)
802
	 */
803
	@Override
804
	public Synonym findBestMatchingSynonym(String taxonName) {
805
		List<TaxonBase> synonymList = dao.findByNameTitleCache(Synonym.class, taxonName, null, MatchMode.EXACT, null, 0, null, null);
806
		if(! synonymList.isEmpty()){
807
			Synonym result = CdmBase.deproxy(synonymList.iterator().next(), Synonym.class);
808
			if(synonymList.size() == 1){
809
				logger.info(synonymList.size() + " Synonym found " + result.getTitleCache() );
810
				return result;
811
			} else {
812
				logger.info("Several matching synonyms found. Using first: " +  result.getTitleCache());
813
				return result;
814
			}
815
		}
816
		return null;
817
	}
818

  
819
	/* (non-Javadoc)
820
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#moveSynonymToAnotherTaxon(eu.etaxonomy.cdm.model.taxon.SynonymRelationship, eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.reference.Reference, java.lang.String)
821
	 */
822
	@Override
823
	public Taxon moveSynonymToAnotherTaxon(SynonymRelationship synonymRelation,
824
			Taxon toTaxon, SynonymRelationshipType synonymRelationshipType, Reference reference, String referenceDetail) {
825
		Taxon fromTaxon = synonymRelation.getAcceptedTaxon();
826

  
827
		toTaxon.addSynonym(synonymRelation.getSynonym(), synonymRelationshipType, reference, referenceDetail);
828
		
829
		fromTaxon.removeSynonymRelation(synonymRelation);
830
				
831
		return toTaxon;
832
	}
833

  
834
	/* (non-Javadoc)
835
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheTaxon()
836
	 */
837
	@Override
838
	public List<UuidAndTitleCache<TaxonBase>> getUuidAndTitleCacheTaxon() {
839
		return dao.getUuidAndTitleCacheTaxon();
840
	}
841

  
842
	/* (non-Javadoc)
843
	 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheSynonym()
844
	 */
845
	@Override
846
	public List<UuidAndTitleCache<TaxonBase>> getUuidAndTitleCacheSynonym() {
847
		return dao.getUuidAndTitleCacheSynonym();
848
	}
849
	
850
	
529

  
530
            List<? extends TaxonNameBase<?,?>> names =
531
                nameDao.findByName(configurator.getTitleSearchStringSqlized(), configurator.getMatchMode(),
532
                        configurator.getPageSize(), configurator.getPageNumber(), null, configurator.getTaxonNamePropertyPath());
533
            if (logger.isDebugEnabled()) { logger.debug(names.size() + " matching name(s) found"); }
534
            if (names.size() > 0) {
535
                for (TaxonNameBase<?,?> taxonName : names) {
536
                    if (taxonName.getTaxonBases().size() == 0) {
537
                        results.add(taxonName);
538
                        numberNameResults++;
539
                    }
540
                }
541
                if (logger.isDebugEnabled()) { logger.debug(numberNameResults + " matching name(s) without taxa found"); }
542
                numberOfResults += numberNameResults;
543
            }
544
        }
545

  
546
        // Taxa from common names
547

  
548
        if (configurator.isDoTaxaByCommonNames()) {
549
            taxa = null;
550
            numberTaxaResults = 0;
551
            if(configurator.getPageSize() != null){// no point counting if we need all anyway
552
                numberTaxaResults = dao.countTaxaByCommonName(configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas());
553
            }
554
            if(configurator.getPageSize() == null || numberTaxaResults > configurator.getPageSize() * configurator.getPageNumber()){
555
                taxa = dao.getTaxaByCommonName(configurator.getTitleSearchStringSqlized(), configurator.getClassification(), configurator.getMatchMode(), configurator.getNamedAreas(), configurator.getPageSize(), configurator.getPageNumber(), configurator.getTaxonPropertyPath());
556
            }
557
            if(taxa != null){
558
                results.addAll(taxa);
559
            }
560
            numberOfResults += numberTaxaResults;
561

  
562
        }
563

  
564
       return new DefaultPagerImpl<IdentifiableEntity>
565
            (configurator.getPageNumber(), numberOfResults, configurator.getPageSize(), results);
566
    }
567

  
568
    public List<UuidAndTitleCache<TaxonBase>> getTaxonUuidAndTitleCache(){
569
        return dao.getUuidAndTitleCache();
570
    }
571

  
572
    /* (non-Javadoc)
573
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllMedia(eu.etaxonomy.cdm.model.taxon.Taxon, int, int, int, java.lang.String[])
574
     */
575
    public List<MediaRepresentation> getAllMedia(Taxon taxon, int size, int height, int widthOrDuration, String[] mimeTypes){
576
        List<MediaRepresentation> medRep = new ArrayList<MediaRepresentation>();
577
        taxon = (Taxon)dao.load(taxon.getUuid());
578
        Set<TaxonDescription> descriptions = taxon.getDescriptions();
579
        for (TaxonDescription taxDesc: descriptions){
580
            Set<DescriptionElementBase> elements = taxDesc.getElements();
581
            for (DescriptionElementBase descElem: elements){
582
                for(Media media : descElem.getMedia()){
583

  
584
                    //find the best matching representation
585
                    medRep.add(MediaUtils.findBestMatchingRepresentation(media, null, size, height, widthOrDuration, mimeTypes));
586

  
587
                }
588
            }
589
        }
590
        return medRep;
591
    }
592

  
593
    /* (non-Javadoc)
594
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaByID(java.util.Set)
595
     */
596
    public List<TaxonBase> findTaxaByID(Set<Integer> listOfIDs) {
597
        return this.dao.findById(listOfIDs);
598
    }
599

  
600
    /* (non-Javadoc)
601
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#countAllRelationships()
602
     */
603
    public int countAllRelationships() {
604
        return this.dao.countAllRelationships();
605
    }
606

  
607
    /* (non-Javadoc)
608
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#createAllInferredSynonyms(eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.taxon.Taxon)
609
     */
610
    public List<Synonym> createAllInferredSynonyms(Classification tree,
611
            Taxon taxon) {
612

  
613
        return this.dao.createAllInferredSynonyms(taxon, tree);
614
    }
615

  
616
    /* (non-Javadoc)
617
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#createInferredSynonyms(eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)
618
     */
619
    public List<Synonym> createInferredSynonyms(Classification tree, Taxon taxon, SynonymRelationshipType type) {
620

  
621
        return this.dao.createInferredSynonyms(taxon, tree, type);
622
    }
623

  
624
    /* (non-Javadoc)
625
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#findIdenticalTaxonNames(java.util.List)
626
     */
627
    public List<TaxonNameBase> findIdenticalTaxonNames(List<String> propertyPath) {
628

  
629
        return this.dao.findIdenticalTaxonNames(propertyPath);
630
    }
631

  
632
    /* (non-Javadoc)
633
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#findIdenticalTaxonNameIds(java.util.List)
634
     */
635
    public List<TaxonNameBase> findIdenticalTaxonNameIds(List<String> propertyPath) {
636

  
637
        return this.dao.findIdenticalNamesNew(propertyPath);
638
    }
639

  
640
    /* (non-Javadoc)
641
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getPhylumName(eu.etaxonomy.cdm.model.name.TaxonNameBase)
642
     */
643
    public String getPhylumName(TaxonNameBase name){
644
        return this.dao.getPhylumName(name);
645
    }
646

  
647
    /* (non-Javadoc)
648
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#deleteSynonymRelationships(eu.etaxonomy.cdm.model.taxon.Synonym)
649
     */
650
    public long deleteSynonymRelationships(Synonym syn) {
651

  
652
        return dao.deleteSynonymRelationships(syn);
653
    }
654

  
655

  
656
    /* (non-Javadoc)
657
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#listSynonymRelationships(eu.etaxonomy.cdm.model.taxon.TaxonBase, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction)
658
     */
659
    public List<SynonymRelationship> listSynonymRelationships(
660
            TaxonBase taxonBase, SynonymRelationshipType type, Integer pageSize, Integer pageNumber,
661
            List<OrderHint> orderHints, List<String> propertyPaths, Direction direction) {
662
        Integer numberOfResults = dao.countSynonymRelationships(taxonBase, type, direction);
663

  
664
        List<SynonymRelationship> results = new ArrayList<SynonymRelationship>();
665
        if(numberOfResults > 0) { // no point checking again
666
            results = dao.getSynonymRelationships(taxonBase, type, pageSize, pageNumber, orderHints, propertyPaths, direction);
667
        }
668
        return results;
669
    }
670

  
671
    /* (non-Javadoc)
672
     * @see eu.etaxonomy.cdm.api.service.ITaxonService#findBestMatchingTaxon(java.lang.String)
673
     */
674
    @Override
675
    public Taxon findBestMatchingTaxon(String taxonName) {
676
        MatchingTaxonConfigurator config = MatchingTaxonConfigurator.NewInstance();
677
        config.setTaxonNameTitle(taxonName);
678
        return findBestMatchingTaxon(config);
679
    }
680

  
681

  
682

  
683
    @Override
684
    public Taxon findBestMatchingTaxon(MatchingTaxonConfigurator config) {
685

  
686
        Taxon bestCandidate = null;
687
        try{
688
            // 1. search for acceptet taxa
689
            List<TaxonBase> taxonList = dao.findByNameTitleCache(Taxon.class, config.getTaxonNameTitle(), null, MatchMode.EXACT, null, 0, null, null);
690
            boolean bestCandidateMatchesSecUuid = false;
691
            boolean bestCandidateIsInClassification = false;
692
            int countEqualCandidates = 0;
693
            for(TaxonBase taxonBaseCandidate : taxonList){
694
                if(taxonBaseCandidate instanceof Taxon){
695
                    Taxon newCanditate = CdmBase.deproxy(taxonBaseCandidate, Taxon.class);
696
                    boolean newCandidateMatchesSecUuid = isMatchesSecUuid(newCanditate, config);
697
                    if (! newCandidateMatchesSecUuid && config.isOnlyMatchingSecUuid() ){
698
                        continue;
699
                    }else if(newCandidateMatchesSecUuid && ! bestCandidateMatchesSecUuid){
700
                        bestCandidate = newCanditate;
701
                        countEqualCandidates = 1;
702
                        bestCandidateMatchesSecUuid = true;
703
                        continue;
704
                    }
705

  
706
                    boolean newCandidateInClassification = isInClassification(newCanditate, config);
707
                    if (! newCandidateInClassification && config.isOnlyMatchingClassificationUuid()){
708
                        continue;
709
                    }else if (newCandidateInClassification && ! bestCandidateIsInClassification){
710
                        bestCandidate = newCanditate;
711
                        countEqualCandidates = 1;
712
                        bestCandidateIsInClassification = true;
713
                        continue;
714
                    }
715
                    if (bestCandidate == null){
716
                        bestCandidate = newCanditate;
717
                        countEqualCandidates = 1;
718
                        continue;
719
                    }
720

  
721
                }else{  //not Taxon.class
722
                    continue;
723
                }
724
                countEqualCandidates++;
725

  
726
            }
727
            if (bestCandidate != null){
728
                if(countEqualCandidates > 1){
729
                    logger.info(countEqualCandidates + " equally matching TaxonBases found, using first accepted Taxon: " + bestCandidate.getTitleCache());
730
                    return bestCandidate;
731
                } else {
732
                    logger.info("using accepted Taxon: " + bestCandidate.getTitleCache());
733
                    return bestCandidate;
734
                }
735
            }
736

  
737

  
738
            // 2. search for synonyms
739
            if (config.isIncludeSynonyms()){
740
                List<TaxonBase> synonymList = dao.findByNameTitleCache(Synonym.class, config.getTaxonNameTitle(), null, MatchMode.EXACT, null, 0, null, null);
741
                for(TaxonBase taxonBase : synonymList){
742
                    if(taxonBase instanceof Synonym){
743
                        Synonym synonym = CdmBase.deproxy(taxonBase, Synonym.class);
744
                        Set<Taxon> acceptetdCandidates = synonym.getAcceptedTaxa();
745
                        if(!acceptetdCandidates.isEmpty()){
746
                            bestCandidate = acceptetdCandidates.iterator().next();
747
                            if(acceptetdCandidates.size() == 1){
748
                                logger.info(acceptetdCandidates.size() + " Accepted taxa found for synonym " + taxonBase.getTitleCache() + ", using first one: " + bestCandidate.getTitleCache());
749
                                return bestCandidate;
750
                            } else {
751
                                logger.info("using accepted Taxon " +  bestCandidate.getTitleCache() + "for synonym " + taxonBase.getTitleCache());
752
                                return bestCandidate;
753
                            }
754
                            //TODO extend method: search using treeUUID, using SecUUID, first find accepted then include synonyms until a matching taxon is found
755
                        }
756
                    }
757
                }
758
            }
759

  
760
        } catch (Exception e){
761
            logger.error(e);
762
        }
763

  
764
        return bestCandidate;
765
    }
766

  
767
    private boolean isInClassification(Taxon taxon, MatchingTaxonConfigurator config) {
768
        UUID configClassificationUuid = config.getClassificationUuid();
769
        if (configClassificationUuid == null){
770
            return false;
771
        }
772
        for (TaxonNode node : taxon.getTaxonNodes()){
773
            UUID classUuid = node.getClassification().getUuid();
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff