3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
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.
11 package eu
.etaxonomy
.cdm
.api
.service
;
13 import java
.util
.ArrayList
;
14 import java
.util
.Comparator
;
15 import java
.util
.List
;
17 import java
.util
.UUID
;
19 import org
.apache
.log4j
.Logger
;
20 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
21 import org
.springframework
.stereotype
.Service
;
22 import org
.springframework
.transaction
.annotation
.Propagation
;
23 import org
.springframework
.transaction
.annotation
.Transactional
;
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
.common
.IProgressMonitor
;
29 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
30 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
31 import eu
.etaxonomy
.cdm
.model
.common
.OrderedTermVocabulary
;
32 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
;
33 import eu
.etaxonomy
.cdm
.model
.common
.RelationshipBase
.Direction
;
34 import eu
.etaxonomy
.cdm
.model
.common
.UuidAndTitleCache
;
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
.media
.MediaUtils
;
40 import eu
.etaxonomy
.cdm
.model
.name
.HomotypicalGroup
;
41 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
42 import eu
.etaxonomy
.cdm
.model
.name
.TaxonNameBase
;
43 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
44 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
45 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
46 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationship
;
47 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationshipType
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
49 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
50 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationship
;
51 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonRelationshipType
;
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
.MatchMode
;
58 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
59 import eu
.etaxonomy
.cdm
.strategy
.cache
.common
.IIdentifiableEntityCacheStrategy
;
63 * @author a.kohlbecker
68 @Transactional(propagation
= Propagation
.SUPPORTS
, readOnly
= true)
69 public class TaxonServiceImpl
extends IdentifiableServiceBase
<TaxonBase
,ITaxonDao
> implements ITaxonService
{
70 private static final Logger logger
= Logger
.getLogger(TaxonServiceImpl
.class);
73 private ITaxonNameDao nameDao
;
76 private IDescriptionDao descriptionDao
;
79 private IOrderedTermVocabularyDao orderedVocabularyDao
;
84 public TaxonServiceImpl(){
85 if (logger
.isDebugEnabled()) { logger
.debug("Load TaxonService Bean"); }
89 * FIXME Candidate for harmonization
90 * rename searchByName ?
92 public List
<TaxonBase
> searchTaxaByName(String name
, Reference sec
) {
93 return dao
.getTaxaByName(name
, sec
);
97 * FIXME Candidate for harmonization
98 * list(Synonym.class, ...)
100 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllSynonyms(int, int)
102 public List
<Synonym
> getAllSynonyms(int limit
, int start
) {
103 return dao
.getAllSynonyms(limit
, start
);
107 * FIXME Candidate for harmonization
108 * list(Taxon.class, ...)
110 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllTaxa(int, int)
112 public List
<Taxon
> getAllTaxa(int limit
, int start
) {
113 return dao
.getAllTaxa(limit
, start
);
118 * FIXME Candidate for harmonization
119 * merge with getRootTaxa(Reference sec, ..., ...)
121 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference)
123 public List
<Taxon
> getRootTaxa(Reference sec
){
124 return getRootTaxa(sec
, CdmFetch
.FETCH_CHILDTAXA(), true);
128 * FIXME Candidate for harmonization
129 * merge with getRootTaxa(Reference sec, ..., ...)
131 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, boolean)
133 public List
<Taxon
> getRootTaxa(Reference sec
, CdmFetch cdmFetch
, boolean onlyWithChildren
) {
134 if (cdmFetch
== null){
135 cdmFetch
= CdmFetch
.NO_FETCH();
137 return dao
.getRootTaxa(sec
, cdmFetch
, onlyWithChildren
, false);
141 * FIXME Candidate for harmonization
142 * merge with getRootTaxa(Reference sec, ..., ...)
144 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, boolean, boolean)
146 public List
<Taxon
> getRootTaxa(Reference sec
, boolean onlyWithChildren
,
147 boolean withMisapplications
) {
148 return dao
.getRootTaxa(sec
, null, onlyWithChildren
, withMisapplications
);
152 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.Reference, boolean, boolean)
154 public List
<Taxon
> getRootTaxa(Rank rank
, Reference sec
, boolean onlyWithChildren
,
155 boolean withMisapplications
, List
<String
> propertyPaths
) {
156 return dao
.getRootTaxa(rank
, sec
, null, onlyWithChildren
, withMisapplications
, propertyPaths
);
160 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllRelationships(int, int)
162 public List
<RelationshipBase
> getAllRelationships(int limit
, int start
){
163 return dao
.getAllRelationships(limit
, start
);
167 * FIXME Candidate for harmonization
168 * is this the same as termService.getVocabulary(VocabularyEnum.TaxonRelationshipType) ?
171 public OrderedTermVocabulary
<TaxonRelationshipType
> getTaxonRelationshipTypeVocabulary() {
173 String taxonRelTypeVocabularyId
= "15db0cf7-7afc-4a86-a7d4-221c73b0c9ac";
174 UUID uuid
= UUID
.fromString(taxonRelTypeVocabularyId
);
175 OrderedTermVocabulary
<TaxonRelationshipType
> taxonRelTypeVocabulary
=
176 (OrderedTermVocabulary
)orderedVocabularyDao
.findByUuid(uuid
);
177 return taxonRelTypeVocabulary
;
184 * @see eu.etaxonomy.cdm.api.service.ITaxonService#swapSynonymWithAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym)
186 @Transactional(readOnly
= false)
187 public void swapSynonymAndAcceptedTaxon(Synonym synonym
, Taxon acceptedTaxon
){
189 TaxonNameBase synonymName
= synonym
.getName();
190 synonymName
.removeTaxonBase(synonym
);
191 TaxonNameBase taxonName
= acceptedTaxon
.getName();
192 taxonName
.removeTaxonBase(acceptedTaxon
);
194 synonym
.setName(taxonName
);
195 acceptedTaxon
.setName(synonymName
);
197 // the accepted taxon needs a new uuid because the concept has changed
198 // FIXME this leads to an error "HibernateException: immutable natural identifier of an instance of eu.etaxonomy.cdm.model.taxon.Taxon was altered"
199 //acceptedTaxon.setUuid(UUID.randomUUID());
204 * @see eu.etaxonomy.cdm.api.service.ITaxonService#changeSynonymToAcceptedTaxon(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.Taxon)
206 //TODO correct delete handling still needs to be implemented / checked
208 @Transactional(readOnly
= false)
209 public Taxon
changeSynonymToAcceptedTaxon(Synonym synonym
, Taxon acceptedTaxon
, boolean deleteSynonym
, boolean copyCitationInfo
, Reference citation
, String microCitation
) throws IllegalArgumentException
{
211 TaxonNameBase acceptedName
= acceptedTaxon
.getName();
212 TaxonNameBase synonymName
= synonym
.getName();
213 HomotypicalGroup synonymHomotypicGroup
= synonymName
.getHomotypicalGroup();
214 if (acceptedName
.getHomotypicalGroup().equals(synonymHomotypicGroup
)){
215 String message
= "The accepted taxon and the synonym are part of the same homotypical group and therefore can not be both accepted.";
216 throw new IllegalArgumentException(message
);
219 Taxon newAcceptedTaxon
= Taxon
.NewInstance(synonym
.getName(), acceptedTaxon
.getSec());
221 SynonymRelationshipType relType
= SynonymRelationshipType
.HOMOTYPIC_SYNONYM_OF();
222 List
<Synonym
> heteroSynonyms
= synonymHomotypicGroup
.getSynonymsInGroup(acceptedTaxon
.getSec());
223 for (Synonym heteroSynonym
: heteroSynonyms
){
224 if (synonym
.equals(heteroSynonym
)){
225 acceptedTaxon
.removeSynonym(heteroSynonym
, false);
227 heteroSynonym
.replaceAcceptedTaxon(newAcceptedTaxon
, relType
, copyCitationInfo
, citation
, microCitation
);
231 // synonym.getName().removeTaxonBase(synonym);
232 //TODO correct delete handling still needs to be implemented / checked
235 this.delete(synonym
);
236 } catch (Exception e
) {
237 logger
.info("Can't delete old synonym from database");
242 return newAcceptedTaxon
;
245 public Taxon
changeSynonymToRelatedTaxon(Synonym synonym
, Taxon toTaxon
, TaxonRelationshipType taxonRelationshipType
, Reference citation
, String microcitation
){
247 // Get name from synonym
248 TaxonNameBase
<?
, ?
> synonymName
= synonym
.getName();
250 // remove synonym from taxon
251 toTaxon
.removeSynonym(synonym
);
253 // Create a taxon with synonym name
254 Taxon fromTaxon
= Taxon
.NewInstance(synonymName
, null);
256 // Add taxon relation
257 fromTaxon
.addTaxonRelation(toTaxon
, taxonRelationshipType
, citation
, microcitation
);
259 // since we are swapping names, we have to detach the name from the synonym completely.
260 // Otherwise the synonym will still be in the list of typified names.
261 synonym
.getName().removeTaxonBase(synonym
);
267 * @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)
269 @Transactional(readOnly
= false)
271 public void changeHomotypicalGroupOfSynonym(Synonym synonym
, HomotypicalGroup newHomotypicalGroup
, Taxon targetTaxon
,
272 boolean removeFromOtherTaxa
, boolean setBasionymRelationIfApplicable
){
274 TaxonNameBase synonymName
= synonym
.getName();
275 HomotypicalGroup oldHomotypicalGroup
= synonymName
.getHomotypicalGroup();
279 oldHomotypicalGroup
.removeTypifiedName(synonymName
);
280 newHomotypicalGroup
.addTypifiedName(synonymName
);
282 //remove existing basionym relationships
283 synonymName
.removeBasionyms();
285 //add basionym relationship
286 if (setBasionymRelationIfApplicable
){
287 Set
<TaxonNameBase
> basionyms
= newHomotypicalGroup
.getBasionyms();
288 for (TaxonNameBase basionym
: basionyms
){
289 synonymName
.addBasionym(basionym
);
293 //set synonym relationship correctly
294 // SynonymRelationship relToTaxon = null;
295 boolean relToTargetTaxonExists
= false;
296 Set
<SynonymRelationship
> existingRelations
= synonym
.getSynonymRelations();
297 for (SynonymRelationship rel
: existingRelations
){
298 Taxon acceptedTaxon
= rel
.getAcceptedTaxon();
299 boolean isTargetTaxon
= acceptedTaxon
!= null && acceptedTaxon
.equals(targetTaxon
);
300 HomotypicalGroup acceptedGroup
= acceptedTaxon
.getHomotypicGroup();
301 boolean isHomotypicToTaxon
= acceptedGroup
.equals(newHomotypicalGroup
);
302 SynonymRelationshipType newRelationType
= isHomotypicToTaxon? SynonymRelationshipType
.HOMOTYPIC_SYNONYM_OF() : SynonymRelationshipType
.HETEROTYPIC_SYNONYM_OF();
303 rel
.setType(newRelationType
);
304 //TODO handle citation and microCitation
307 relToTargetTaxonExists
= true;
309 if (removeFromOtherTaxa
){
310 acceptedTaxon
.removeSynonym(synonym
, false);
316 if (targetTaxon
!= null && ! relToTargetTaxonExists
){
317 Taxon acceptedTaxon
= targetTaxon
;
318 HomotypicalGroup acceptedGroup
= acceptedTaxon
.getHomotypicGroup();
319 boolean isHomotypicToTaxon
= acceptedGroup
.equals(newHomotypicalGroup
);
320 SynonymRelationshipType relType
= isHomotypicToTaxon? SynonymRelationshipType
.HOMOTYPIC_SYNONYM_OF() : SynonymRelationshipType
.HETEROTYPIC_SYNONYM_OF();
321 //TODO handle citation and microCitation
322 Reference citation
= null;
323 String microCitation
= null;
324 acceptedTaxon
.addSynonym(synonym
, relType
, citation
, microCitation
);
331 * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)
334 public void updateTitleCache(Class
<?
extends TaxonBase
> clazz
, Integer stepSize
, IIdentifiableEntityCacheStrategy
<TaxonBase
> cacheStrategy
, IProgressMonitor monitor
) {
336 clazz
= TaxonBase
.class;
338 super.updateTitleCacheImpl(clazz
, stepSize
, cacheStrategy
, monitor
);
342 protected void setDao(ITaxonDao dao
) {
347 * @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)
349 public Pager
<TaxonBase
> findTaxaByName(Class
<?
extends TaxonBase
> clazz
, String uninomial
, String infragenericEpithet
, String specificEpithet
, String infraspecificEpithet
, Rank rank
, Integer pageSize
,Integer pageNumber
) {
350 Integer numberOfResults
= dao
.countTaxaByName(clazz
, uninomial
, infragenericEpithet
, specificEpithet
, infraspecificEpithet
, rank
);
352 List
<TaxonBase
> results
= new ArrayList
<TaxonBase
>();
353 if(numberOfResults
> 0) { // no point checking again
354 results
= dao
.findTaxaByName(clazz
, uninomial
, infragenericEpithet
, specificEpithet
, infraspecificEpithet
, rank
, pageSize
, pageNumber
);
357 return new DefaultPagerImpl
<TaxonBase
>(pageNumber
, numberOfResults
, pageSize
, results
);
361 * @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)
363 public List
<TaxonBase
> listTaxaByName(Class
<?
extends TaxonBase
> clazz
, String uninomial
, String infragenericEpithet
, String specificEpithet
, String infraspecificEpithet
, Rank rank
, Integer pageSize
,Integer pageNumber
) {
364 Integer numberOfResults
= dao
.countTaxaByName(clazz
, uninomial
, infragenericEpithet
, specificEpithet
, infraspecificEpithet
, rank
);
366 List
<TaxonBase
> results
= new ArrayList
<TaxonBase
>();
367 if(numberOfResults
> 0) { // no point checking again
368 results
= dao
.findTaxaByName(clazz
, uninomial
, infragenericEpithet
, specificEpithet
, infraspecificEpithet
, rank
, pageSize
, pageNumber
);
375 * @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)
377 public List
<TaxonRelationship
> listToTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
){
378 Integer numberOfResults
= dao
.countTaxonRelationships(taxon
, type
, TaxonRelationship
.Direction
.relatedTo
);
380 List
<TaxonRelationship
> results
= new ArrayList
<TaxonRelationship
>();
381 if(numberOfResults
> 0) { // no point checking again
382 results
= dao
.getTaxonRelationships(taxon
, type
, pageSize
, pageNumber
, orderHints
, propertyPaths
, TaxonRelationship
.Direction
.relatedTo
);
388 * @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)
390 public Pager
<TaxonRelationship
> pageToTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
391 Integer numberOfResults
= dao
.countTaxonRelationships(taxon
, type
, TaxonRelationship
.Direction
.relatedTo
);
393 List
<TaxonRelationship
> results
= new ArrayList
<TaxonRelationship
>();
394 if(numberOfResults
> 0) { // no point checking again
395 results
= dao
.getTaxonRelationships(taxon
, type
, pageSize
, pageNumber
, orderHints
, propertyPaths
, TaxonRelationship
.Direction
.relatedTo
);
397 return new DefaultPagerImpl
<TaxonRelationship
>(pageNumber
, numberOfResults
, pageSize
, results
);
401 * @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)
403 public List
<TaxonRelationship
> listFromTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
){
404 Integer numberOfResults
= dao
.countTaxonRelationships(taxon
, type
, TaxonRelationship
.Direction
.relatedFrom
);
406 List
<TaxonRelationship
> results
= new ArrayList
<TaxonRelationship
>();
407 if(numberOfResults
> 0) { // no point checking again
408 results
= dao
.getTaxonRelationships(taxon
, type
, pageSize
, pageNumber
, orderHints
, propertyPaths
, TaxonRelationship
.Direction
.relatedFrom
);
414 * @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)
416 public Pager
<TaxonRelationship
> pageFromTaxonRelationships(Taxon taxon
, TaxonRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
417 Integer numberOfResults
= dao
.countTaxonRelationships(taxon
, type
, TaxonRelationship
.Direction
.relatedFrom
);
419 List
<TaxonRelationship
> results
= new ArrayList
<TaxonRelationship
>();
420 if(numberOfResults
> 0) { // no point checking again
421 results
= dao
.getTaxonRelationships(taxon
, type
, pageSize
, pageNumber
, orderHints
, propertyPaths
, TaxonRelationship
.Direction
.relatedFrom
);
423 return new DefaultPagerImpl
<TaxonRelationship
>(pageNumber
, numberOfResults
, pageSize
, results
);
427 * @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)
429 public Pager
<SynonymRelationship
> getSynonyms(Taxon taxon
, SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
430 Integer numberOfResults
= dao
.countSynonyms(taxon
, type
);
432 List
<SynonymRelationship
> results
= new ArrayList
<SynonymRelationship
>();
433 if(numberOfResults
> 0) { // no point checking again
434 results
= dao
.getSynonyms(taxon
, type
, pageSize
, pageNumber
, orderHints
, propertyPaths
);
437 return new DefaultPagerImpl
<SynonymRelationship
>(pageNumber
, numberOfResults
, pageSize
, results
);
441 * @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)
443 public Pager
<SynonymRelationship
> getSynonyms(Synonym synonym
, SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
444 Integer numberOfResults
= dao
.countSynonyms(synonym
, type
);
446 List
<SynonymRelationship
> results
= new ArrayList
<SynonymRelationship
>();
447 if(numberOfResults
> 0) { // no point checking again
448 results
= dao
.getSynonyms(synonym
, type
, pageSize
, pageNumber
, orderHints
, propertyPaths
);
451 return new DefaultPagerImpl
<SynonymRelationship
>(pageNumber
, numberOfResults
, pageSize
, results
);
455 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getHomotypicSynonymsByHomotypicGroup(eu.etaxonomy.cdm.model.taxon.Taxon, java.util.List)
457 public List
<Synonym
> getHomotypicSynonymsByHomotypicGroup(Taxon taxon
, List
<String
> propertyPaths
){
458 Taxon t
= (Taxon
)dao
.load(taxon
.getUuid(), propertyPaths
);
459 return t
.getHomotypicSynonymsByHomotypicGroup();
463 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getHeterotypicSynonymyGroups(eu.etaxonomy.cdm.model.taxon.Taxon, java.util.List)
465 public List
<List
<Synonym
>> getHeterotypicSynonymyGroups(Taxon taxon
, List
<String
> propertyPaths
){
466 Taxon t
= (Taxon
)dao
.load(taxon
.getUuid(), propertyPaths
);
467 List
<HomotypicalGroup
> hsgl
= t
.getHeterotypicSynonymyGroups();
468 List
<List
<Synonym
>> heterotypicSynonymyGroups
= new ArrayList
<List
<Synonym
>>(hsgl
.size());
469 for(HomotypicalGroup hsg
: hsgl
){
470 heterotypicSynonymyGroups
.add(hsg
.getSynonymsInGroup(t
.getSec()));
472 return heterotypicSynonymyGroups
;
475 public List
<UuidAndTitleCache
<TaxonBase
>> findTaxaAndNamesForEditor(ITaxonServiceConfigurator configurator
){
477 List
<UuidAndTitleCache
<TaxonBase
>> result
= new ArrayList
<UuidAndTitleCache
<TaxonBase
>>();
478 Class
<?
extends TaxonBase
> clazz
= null;
479 if ((configurator
.isDoTaxa() && configurator
.isDoSynonyms())) {
480 clazz
= TaxonBase
.class;
481 //propertyPath.addAll(configurator.getTaxonPropertyPath());
482 //propertyPath.addAll(configurator.getSynonymPropertyPath());
483 } else if(configurator
.isDoTaxa()) {
485 //propertyPath = configurator.getTaxonPropertyPath();
486 } else if (configurator
.isDoSynonyms()) {
487 clazz
= Synonym
.class;
488 //propertyPath = configurator.getSynonymPropertyPath();
492 result
= dao
.getTaxaByNameForEditor(clazz
, configurator
.getSearchString(), configurator
.getClassification(), configurator
.getMatchMode(), configurator
.getNamedAreas());
496 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaAndNames(eu.etaxonomy.cdm.api.service.config.ITaxonServiceConfigurator)
498 public Pager
<IdentifiableEntity
> findTaxaAndNames(ITaxonServiceConfigurator configurator
) {
500 List
<IdentifiableEntity
> results
= new ArrayList
<IdentifiableEntity
>();
501 int numberOfResults
= 0; // overall number of results (as opposed to number of results per page)
502 List
<TaxonBase
> taxa
= null;
505 long numberTaxaResults
= 0L;
507 Class
<?
extends TaxonBase
> clazz
= null;
508 List
<String
> propertyPath
= new ArrayList
<String
>();
509 if(configurator
.getTaxonPropertyPath() != null){
510 propertyPath
.addAll(configurator
.getTaxonPropertyPath());
512 if ((configurator
.isDoTaxa() && configurator
.isDoSynonyms())) {
513 clazz
= TaxonBase
.class;
514 //propertyPath.addAll(configurator.getTaxonPropertyPath());
515 //propertyPath.addAll(configurator.getSynonymPropertyPath());
516 } else if(configurator
.isDoTaxa()) {
518 //propertyPath = configurator.getTaxonPropertyPath();
519 } else if (configurator
.isDoSynonyms()) {
520 clazz
= Synonym
.class;
521 //propertyPath = configurator.getSynonymPropertyPath();
525 if(configurator
.getPageSize() != null){ // no point counting if we need all anyway
527 dao
.countTaxaByName(clazz
,
528 configurator
.getSearchString(), configurator
.getClassification(), configurator
.getMatchMode(),
529 configurator
.getNamedAreas());
532 if(configurator
.getPageSize() == null || numberTaxaResults
> configurator
.getPageSize() * configurator
.getPageNumber()){ // no point checking again if less results
533 taxa
= dao
.getTaxaByName(clazz
,
534 configurator
.getSearchString(), configurator
.getClassification(), configurator
.getMatchMode(),
535 configurator
.getNamedAreas(), configurator
.getPageSize(),
536 configurator
.getPageNumber(), propertyPath
);
540 if (logger
.isDebugEnabled()) { logger
.debug(numberTaxaResults
+ " matching taxa counted"); }
543 results
.addAll(taxa
);
546 numberOfResults
+= numberTaxaResults
;
548 // Names without taxa
549 if (configurator
.isDoNamesWithoutTaxa()) {
550 int numberNameResults
= 0;
552 List
<?
extends TaxonNameBase
<?
,?
>> names
=
553 nameDao
.findByName(configurator
.getSearchString(), configurator
.getMatchMode(),
554 configurator
.getPageSize(), configurator
.getPageNumber(), null, configurator
.getTaxonNamePropertyPath());
555 if (logger
.isDebugEnabled()) { logger
.debug(names
.size() + " matching name(s) found"); }
556 if (names
.size() > 0) {
557 for (TaxonNameBase
<?
,?
> taxonName
: names
) {
558 if (taxonName
.getTaxonBases().size() == 0) {
559 results
.add(taxonName
);
563 if (logger
.isDebugEnabled()) { logger
.debug(numberNameResults
+ " matching name(s) without taxa found"); }
564 numberOfResults
+= numberNameResults
;
568 // Taxa from common names
570 if (configurator
.isDoTaxaByCommonNames()) {
572 numberTaxaResults
= 0;
573 if(configurator
.getPageSize() != null){// no point counting if we need all anyway
574 numberTaxaResults
= dao
.countTaxaByCommonName(configurator
.getSearchString(), configurator
.getClassification(), configurator
.getMatchMode(), configurator
.getNamedAreas());
576 if(configurator
.getPageSize() == null || numberTaxaResults
> configurator
.getPageSize() * configurator
.getPageNumber()){
577 taxa
= dao
.getTaxaByCommonName(configurator
.getSearchString(), configurator
.getClassification(), configurator
.getMatchMode(), configurator
.getNamedAreas(), configurator
.getPageSize(), configurator
.getPageNumber(), configurator
.getTaxonPropertyPath());
580 results
.addAll(taxa
);
582 numberOfResults
+= numberTaxaResults
;
586 return new DefaultPagerImpl
<IdentifiableEntity
>
587 (configurator
.getPageNumber(), numberOfResults
, configurator
.getPageSize(), results
);
590 public List
<UuidAndTitleCache
<TaxonBase
>> getTaxonUuidAndTitleCache(){
591 return dao
.getUuidAndTitleCache();
595 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getAllMedia(eu.etaxonomy.cdm.model.taxon.Taxon, int, int, int, java.lang.String[])
597 public List
<MediaRepresentation
> getAllMedia(Taxon taxon
, int size
, int height
, int widthOrDuration
, String
[] mimeTypes
){
598 List
<MediaRepresentation
> medRep
= new ArrayList
<MediaRepresentation
>();
599 taxon
= (Taxon
)dao
.load(taxon
.getUuid());
600 Set
<TaxonDescription
> descriptions
= taxon
.getDescriptions();
601 for (TaxonDescription taxDesc
: descriptions
){
602 Set
<DescriptionElementBase
> elements
= taxDesc
.getElements();
603 for (DescriptionElementBase descElem
: elements
){
604 for(Media media
: descElem
.getMedia()){
606 //find the best matching representation
607 medRep
.add(MediaUtils
.findBestMatchingRepresentation(media
, size
, height
, widthOrDuration
, mimeTypes
));
616 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findTaxaByID(java.util.Set)
618 public List
<TaxonBase
> findTaxaByID(Set
<Integer
> listOfIDs
) {
619 return this.dao
.findById(listOfIDs
);
623 * @see eu.etaxonomy.cdm.api.service.ITaxonService#countAllRelationships()
625 public int countAllRelationships() {
626 return this.dao
.countAllRelationships();
630 * @see eu.etaxonomy.cdm.api.service.ITaxonService#createAllInferredSynonyms(eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.taxon.Taxon)
632 public List
<Synonym
> createAllInferredSynonyms(Classification tree
,
635 return this.dao
.createAllInferredSynonyms(taxon
, tree
);
639 * @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)
641 public List
<Synonym
> createInferredSynonyms(Classification tree
, Taxon taxon
, SynonymRelationshipType type
) {
643 return this.dao
.createInferredSynonyms(taxon
, tree
, type
);
647 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findIdenticalTaxonNames(java.util.List)
649 public List
<TaxonNameBase
> findIdenticalTaxonNames(List
<String
> propertyPath
) {
651 return this.dao
.findIdenticalTaxonNames(propertyPath
);
655 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findIdenticalTaxonNameIds(java.util.List)
657 public List
<TaxonNameBase
> findIdenticalTaxonNameIds(List
<String
> propertyPath
) {
659 return this.dao
.findIdenticalNamesNew(propertyPath
);
663 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getPhylumName(eu.etaxonomy.cdm.model.name.TaxonNameBase)
665 public String
getPhylumName(TaxonNameBase name
){
666 return this.dao
.getPhylumName(name
);
669 private class TaxonAndNameComparator
implements Comparator
{
671 public int compare(Object arg0
, Object arg1
) {
672 IdentifiableEntity castArg0
= (IdentifiableEntity
) arg0
;
673 IdentifiableEntity castArg1
= (IdentifiableEntity
) arg1
;
674 return castArg0
.compareTo(castArg1
);
680 * @see eu.etaxonomy.cdm.api.service.ITaxonService#deleteSynonymRelationships(eu.etaxonomy.cdm.model.taxon.Synonym)
682 public long deleteSynonymRelationships(Synonym syn
) {
684 return dao
.deleteSynonymRelationships(syn
);
689 * @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)
691 public List
<SynonymRelationship
> listSynonymRelationships(
692 TaxonBase taxonBase
, SynonymRelationshipType type
, Integer pageSize
, Integer pageNumber
,
693 List
<OrderHint
> orderHints
, List
<String
> propertyPaths
, Direction direction
) {
694 Integer numberOfResults
= dao
.countSynonymRelationships(taxonBase
, type
, direction
);
696 List
<SynonymRelationship
> results
= new ArrayList
<SynonymRelationship
>();
697 if(numberOfResults
> 0) { // no point checking again
698 results
= dao
.getSynonymRelationships(taxonBase
, type
, pageSize
, pageNumber
, orderHints
, propertyPaths
, direction
);
704 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findBestMatchingTaxon(java.lang.String)
707 public Taxon
findBestMatchingTaxon(String taxonName
) {
709 Taxon matchedTaxon
= null;
711 // 1. search for acceptet taxa
712 List
<TaxonBase
> taxonList
= dao
.findByNameTitleCache(Taxon
.class, taxonName
, null, MatchMode
.EXACT
, null, 0, null, null);
713 for(IdentifiableEntity taxonBaseCandidate
: taxonList
){
714 if(taxonBaseCandidate
instanceof Taxon
){
715 matchedTaxon
= (Taxon
)taxonBaseCandidate
;
716 if(taxonList
.size() > 1){
717 logger
.info(taxonList
.size() + " TaxonBases found, using first accepted Taxon: " + matchedTaxon
.getTitleCache());
720 logger
.info("using accepted Taxon: " + matchedTaxon
.getTitleCache());
723 //TODO extend method: search using treeUUID, using SecUUID, first find accepted then include synonyms until a matching taxon is found
727 // 2. search for synonyms
728 List
<TaxonBase
> synonymList
= dao
.findByNameTitleCache(Synonym
.class, taxonName
, null, MatchMode
.EXACT
, null, 0, null, null);
729 for(TaxonBase taxonBase
: synonymList
){
730 if(taxonBase
instanceof Synonym
){
731 Set
<Taxon
> acceptetdCandidates
= ((Synonym
)taxonBase
).getAcceptedTaxa();
732 if(!acceptetdCandidates
.isEmpty()){
733 matchedTaxon
= acceptetdCandidates
.iterator().next();
734 if(acceptetdCandidates
.size() == 1){
735 logger
.info(acceptetdCandidates
.size() + " Accepted taxa found for synonym " + taxonBase
.getTitleCache() + ", using first one: " + matchedTaxon
.getTitleCache());
738 logger
.info("using accepted Taxon " + matchedTaxon
.getTitleCache() + "for synonym " + taxonBase
.getTitleCache());
741 //TODO extend method: search using treeUUID, using SecUUID, first find accepted then include synonyms until a matching taxon is found
746 } catch (Exception e
){
754 * @see eu.etaxonomy.cdm.api.service.ITaxonService#findBestMatchingSynonym(java.lang.String)
757 public Synonym
findBestMatchingSynonym(String taxonName
) {
758 List
<TaxonBase
> synonymList
= dao
.findByNameTitleCache(Synonym
.class, taxonName
, null, MatchMode
.EXACT
, null, 0, null, null);
759 if(! synonymList
.isEmpty()){
760 Synonym result
= CdmBase
.deproxy(synonymList
.iterator().next(), Synonym
.class);
761 if(synonymList
.size() == 1){
762 logger
.info(synonymList
.size() + " Synonym found " + result
.getTitleCache() );
765 logger
.info("Several matching synonyms found. Using first: " + result
.getTitleCache());
773 * @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)
776 public Taxon
moveSynonymToAnotherTaxon(SynonymRelationship synonymRelation
,
777 Taxon toTaxon
, SynonymRelationshipType synonymRelationshipType
, Reference reference
, String referenceDetail
) {
778 Taxon fromTaxon
= synonymRelation
.getAcceptedTaxon();
780 toTaxon
.addSynonym(synonymRelation
.getSynonym(), synonymRelationshipType
, reference
, referenceDetail
);
782 fromTaxon
.removeSynonymRelation(synonymRelation
);
788 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheTaxon()
791 public List
<UuidAndTitleCache
<TaxonBase
>> getUuidAndTitleCacheTaxon() {
792 return dao
.getUuidAndTitleCacheTaxon();
796 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheSynonym()
799 public List
<UuidAndTitleCache
<TaxonBase
>> getUuidAndTitleCacheSynonym() {
800 return dao
.getUuidAndTitleCacheSynonym();