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
.Collection
;
15 import java
.util
.Collections
;
16 import java
.util
.Comparator
;
17 import java
.util
.List
;
19 import java
.util
.TreeMap
;
20 import java
.util
.UUID
;
22 import org
.apache
.log4j
.Logger
;
23 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
24 import org
.springframework
.stereotype
.Service
;
25 import org
.springframework
.transaction
.annotation
.Transactional
;
27 import eu
.etaxonomy
.cdm
.api
.service
.pager
.Pager
;
28 import eu
.etaxonomy
.cdm
.api
.service
.pager
.PagerUtils
;
29 import eu
.etaxonomy
.cdm
.api
.service
.pager
.impl
.DefaultPagerImpl
;
30 import eu
.etaxonomy
.cdm
.common
.monitor
.IProgressMonitor
;
31 import eu
.etaxonomy
.cdm
.model
.common
.UuidAndTitleCache
;
32 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
33 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
34 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
35 import eu
.etaxonomy
.cdm
.model
.media
.MediaRepresentation
;
36 import eu
.etaxonomy
.cdm
.model
.media
.MediaUtils
;
37 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
38 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
39 import eu
.etaxonomy
.cdm
.model
.taxon
.ITaxonNodeComparator
;
40 import eu
.etaxonomy
.cdm
.model
.taxon
.ITreeNode
;
41 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
42 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonNode
;
43 import eu
.etaxonomy
.cdm
.persistence
.dao
.IBeanInitializer
;
44 import eu
.etaxonomy
.cdm
.persistence
.dao
.taxon
.IClassificationDao
;
45 import eu
.etaxonomy
.cdm
.persistence
.dao
.taxon
.ITaxonDao
;
46 import eu
.etaxonomy
.cdm
.persistence
.dao
.taxon
.ITaxonNodeDao
;
47 import eu
.etaxonomy
.cdm
.persistence
.query
.OrderHint
;
48 import eu
.etaxonomy
.cdm
.strategy
.cache
.common
.IIdentifiableEntityCacheStrategy
;
52 * @created Sep 21, 2009
55 @Transactional(readOnly
= true)
56 public class ClassificationServiceImpl
extends IdentifiableServiceBase
<Classification
, IClassificationDao
> implements IClassificationService
{
57 private static final Logger logger
= Logger
.getLogger(ClassificationServiceImpl
.class);
60 private ITaxonNodeDao taxonNodeDao
;
63 private ITaxonDao taxonDao
;
66 private IBeanInitializer defaultBeanInitializer
;
70 * @see eu.etaxonomy.cdm.api.service.ServiceBase#setDao(eu.etaxonomy.cdm.persistence.dao.common.ICdmEntityDao)
74 protected void setDao(IClassificationDao dao
) {
78 private Comparator
<?
super TaxonNode
> taxonNodeComparator
;
81 public void setTaxonNodeComparator(ITaxonNodeComparator
<?
super TaxonNode
> taxonNodeComparator
){
82 this.taxonNodeComparator
= (Comparator
<?
super TaxonNode
>) taxonNodeComparator
;
88 * @see eu.etaxonomy.cdm.api.service.IClassificationService#loadTaxonNodeByTaxon(eu.etaxonomy.cdm.model.taxon.Taxon, java.util.UUID, java.util.List)
91 public TaxonNode
loadTaxonNodeByTaxon(Taxon taxon
, UUID classificationUuid
, List
<String
> propertyPaths
){
92 Classification tree
= dao
.load(classificationUuid
);
93 TaxonNode node
= tree
.getNode(taxon
);
95 return loadTaxonNode(node
.getUuid(), propertyPaths
);
99 @Deprecated // use loadTaxonNode(UUID, List<String>) instead
100 public TaxonNode
loadTaxonNode(TaxonNode taxonNode
, List
<String
> propertyPaths
){
101 return taxonNodeDao
.load(taxonNode
.getUuid(), propertyPaths
);
104 public TaxonNode
loadTaxonNode(UUID taxonNodeUuid
, List
<String
> propertyPaths
){
105 return taxonNodeDao
.load(taxonNodeUuid
, propertyPaths
);
110 * @see eu.etaxonomy.cdm.api.service.IClassificationService#loadRankSpecificRootNodes(eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.name.Rank, java.util.List)
114 public List
<TaxonNode
> loadRankSpecificRootNodes(Classification classification
, Rank rank
, Integer limit
, Integer start
, List
<String
> propertyPaths
){
116 List
<TaxonNode
> rootNodes
= dao
.loadRankSpecificRootNodes(classification
, rank
, limit
, start
, propertyPaths
);
118 //sort nodes by TaxonName
119 Collections
.sort(rootNodes
, taxonNodeComparator
);
121 // initialize all nodes
122 defaultBeanInitializer
.initializeAll(rootNodes
, propertyPaths
);
128 * @see eu.etaxonomy.cdm.api.service.IClassificationService#listRankSpecificRootNodes(eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer, java.util.List)
131 public List
<TaxonNode
> listRankSpecificRootNodes(Classification classification
, Rank rank
, Integer pageSize
,
132 Integer pageIndex
, List
<String
> propertyPaths
) {
133 return pageRankSpecificRootNodes(classification
, rank
, pageSize
, pageIndex
, propertyPaths
).getRecords();
137 * @see eu.etaxonomy.cdm.api.service.IClassificationService#pageRankSpecificRootNodes(eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer, java.util.List)
140 public Pager
<TaxonNode
> pageRankSpecificRootNodes(Classification classification
, Rank rank
, Integer pageSize
,
141 Integer pageIndex
, List
<String
> propertyPaths
) {
142 Long numberOfResults
= dao
.countRankSpecificRootNodes(classification
, rank
);
144 List
<TaxonNode
> results
= new ArrayList
<TaxonNode
>();
145 if (numberOfResults
> 0) { // no point checking again
147 results
= dao
.loadRankSpecificRootNodes(classification
, rank
, PagerUtils
.limitFor(pageSize
),
148 PagerUtils
.startFor(pageSize
, pageIndex
), propertyPaths
);
151 return new DefaultPagerImpl
<TaxonNode
>(pageIndex
, numberOfResults
.intValue(), pageSize
, results
);
157 * @see eu.etaxonomy.cdm.api.service.ITaxonService#loadTreeBranchTo(eu.etaxonomy.cdm.model.taxon.TaxonNode, eu.etaxonomy.cdm.model.name.Rank, java.util.List)
158 * FIXME Candidate for harmonization
159 * move to classification service
162 public List
<TaxonNode
> loadTreeBranch(TaxonNode taxonNode
, Rank baseRank
, List
<String
> propertyPaths
){
164 TaxonNode thisNode
= taxonNodeDao
.load(taxonNode
.getUuid(), propertyPaths
);
165 List
<TaxonNode
> pathToRoot
= new ArrayList
<TaxonNode
>();
166 pathToRoot
.add(thisNode
);
168 TaxonNode parentNode
= thisNode
.getParent();
169 while(parentNode
!= null){
170 TaxonNode parent
= parentNode
;
171 Rank parentNodeRank
= parent
.getTaxon().getName().getRank();
172 // stop if the next parent is higher than the baseRank
173 if(baseRank
!= null && baseRank
.isLower(parentNodeRank
)){
176 pathToRoot
.add(parentNode
);
177 parentNode
= parentNode
.getParent();
180 // initialize and invert order of nodes in list
181 defaultBeanInitializer
.initializeAll(pathToRoot
, propertyPaths
);
182 Collections
.reverse(pathToRoot
);
189 * @see eu.etaxonomy.cdm.api.service.IClassificationService#loadTreeBranchToTaxon(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.name.Rank, java.util.List)
192 public List
<TaxonNode
> loadTreeBranchToTaxon(Taxon taxon
, Classification classification
, Rank baseRank
, List
<String
> propertyPaths
){
193 Classification tree
= dao
.load(classification
.getUuid());
194 taxon
= (Taxon
) taxonDao
.load(taxon
.getUuid());
195 TaxonNode node
= tree
.getNode(taxon
);
197 logger
.warn("The specified taxon is not found in the given tree.");
200 return loadTreeBranch(node
, baseRank
, propertyPaths
);
205 * @see eu.etaxonomy.cdm.api.service.IClassificationService#loadChildNodesOfTaxon(eu.etaxonomy.cdm.model.taxon.TaxonNode, java.util.List)
208 public List
<TaxonNode
> loadChildNodesOfTaxonNode(TaxonNode taxonNode
,
209 List
<String
> propertyPaths
) {
210 taxonNode
= taxonNodeDao
.load(taxonNode
.getUuid());
211 List
<TaxonNode
> childNodes
= new ArrayList
<TaxonNode
>(taxonNode
.getChildNodes());
212 defaultBeanInitializer
.initializeAll(childNodes
, propertyPaths
);
213 Collections
.sort(childNodes
, taxonNodeComparator
);
219 * @see eu.etaxonomy.cdm.api.service.IClassificationService#loadChildNodesOfTaxon(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.Classification, java.util.List)
222 public List
<TaxonNode
> loadChildNodesOfTaxon(Taxon taxon
, Classification classification
, List
<String
> propertyPaths
){
223 Classification tree
= dao
.load(classification
.getUuid());
224 taxon
= (Taxon
) taxonDao
.load(taxon
.getUuid());
226 TaxonNode node
= tree
.getNode(taxon
);
228 return loadChildNodesOfTaxonNode(node
, propertyPaths
);
238 * @see eu.etaxonomy.cdm.api.service.IClassificationService#getTaxonNodeByUuid(java.util.UUID)
241 public TaxonNode
getTaxonNodeByUuid(UUID uuid
) {
242 return taxonNodeDao
.findByUuid(uuid
);
247 * @see eu.etaxonomy.cdm.api.service.IClassificationService#getTreeNodeByUuid(java.util.UUID)
250 public ITreeNode
getTreeNodeByUuid(UUID uuid
){
251 ITreeNode treeNode
= taxonNodeDao
.findByUuid(uuid
);
252 if(treeNode
== null){
253 treeNode
= dao
.findByUuid(uuid
);
260 * @see eu.etaxonomy.cdm.api.service.IClassificationService#listClassifications(java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
263 public List
<Classification
> listClassifications(Integer limit
, Integer start
, List
<OrderHint
> orderHints
, List
<String
> propertyPaths
) {
264 return dao
.list(limit
, start
, orderHints
, propertyPaths
);
268 * @see eu.etaxonomy.cdm.api.service.IClassificationService#removeTaxonNode(eu.etaxonomy.cdm.model.taxon.Classification)
271 public UUID
removeTaxonNode(TaxonNode taxonNode
) {
272 return taxonNodeDao
.delete(taxonNode
);
275 * @see eu.etaxonomy.cdm.api.service.IClassificationService#removeTreeNode(eu.etaxonomy.cdm.model.taxon.ITreeNode)
278 public UUID
removeTreeNode(ITreeNode treeNode
) {
279 if(treeNode
instanceof Classification
){
280 return dao
.delete((Classification
) treeNode
);
281 }else if(treeNode
instanceof TaxonNode
){
282 return taxonNodeDao
.delete((TaxonNode
)treeNode
);
287 * @see eu.etaxonomy.cdm.api.service.IClassificationService#saveTaxonNode(eu.etaxonomy.cdm.model.taxon.Classification)
290 public UUID
saveTaxonNode(TaxonNode taxonNode
) {
291 return taxonNodeDao
.save(taxonNode
);
296 * @see eu.etaxonomy.cdm.api.service.IClassificationService#saveTaxonNodeAll(java.util.Collection)
299 public Map
<UUID
, TaxonNode
> saveTaxonNodeAll(
300 Collection
<TaxonNode
> taxonNodeCollection
) {
301 return taxonNodeDao
.saveAll(taxonNodeCollection
);
305 * @see eu.etaxonomy.cdm.api.service.IClassificationService#saveTreeNode(eu.etaxonomy.cdm.model.taxon.ITreeNode)
308 public UUID
saveTreeNode(ITreeNode treeNode
) {
309 if(treeNode
instanceof Classification
){
310 return dao
.save((Classification
) treeNode
);
311 }else if(treeNode
instanceof TaxonNode
){
312 return taxonNodeDao
.save((TaxonNode
)treeNode
);
318 public List
<TaxonNode
> getAllNodes(){
319 return taxonNodeDao
.list(null,null);
324 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheOfAcceptedTaxa(eu.etaxonomy.cdm.model.taxon.Classification)
327 public List
<UuidAndTitleCache
<TaxonNode
>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(Classification classification
) {
328 return taxonDao
.getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(classification
);
332 * @see eu.etaxonomy.cdm.api.service.IdentifiableServiceBase#getUuidAndTitleCache()
335 public List
<UuidAndTitleCache
<Classification
>> getUuidAndTitleCache() {
336 return dao
.getUuidAndTitleCache();
340 * @see eu.etaxonomy.cdm.api.service.IClassificationService#getAllMediaForChildNodes(eu.etaxonomy.cdm.model.taxon.TaxonNode, java.util.List, int, int, int, java.lang.String[])
343 public Map
<UUID
, List
<MediaRepresentation
>> getAllMediaForChildNodes(
344 TaxonNode taxonNode
, List
<String
> propertyPaths
, int size
,
345 int height
, int widthOrDuration
, String
[] mimeTypes
) {
347 TreeMap
<UUID
, List
<MediaRepresentation
>> result
= new TreeMap
<UUID
, List
<MediaRepresentation
>>();
348 List
<Media
> taxonMedia
= new ArrayList
<Media
>();
349 List
<MediaRepresentation
> mediaRepresentations
= new ArrayList
<MediaRepresentation
>();
351 //add all media of the children to the result map
352 if (taxonNode
!= null){
354 List
<TaxonNode
> nodes
= new ArrayList
<TaxonNode
>();
356 nodes
.add(loadTaxonNode(taxonNode
, propertyPaths
));
357 nodes
.addAll(loadChildNodesOfTaxonNode(taxonNode
, propertyPaths
));
360 for(TaxonNode node
: nodes
){
361 Taxon taxon
= node
.getTaxon();
362 for (TaxonDescription taxonDescription
: taxon
.getDescriptions()){
363 for (DescriptionElementBase descriptionElement
: taxonDescription
.getElements()){
364 for(Media media
: descriptionElement
.getMedia()){
365 taxonMedia
.add(media
);
367 //find the best matching representation
368 mediaRepresentations
.add(MediaUtils
.findBestMatchingRepresentation(media
,null, size
, height
, widthOrDuration
, mimeTypes
));
373 result
.put(taxon
.getUuid(), mediaRepresentations
);
385 public Map
<UUID
, List
<MediaRepresentation
>> getAllMediaForChildNodes(Taxon taxon
, Classification taxTree
, List
<String
> propertyPaths
, int size
, int height
, int widthOrDuration
, String
[] mimeTypes
){
386 TaxonNode node
= taxTree
.getNode(taxon
);
388 return getAllMediaForChildNodes(node
, propertyPaths
, size
, height
, widthOrDuration
, mimeTypes
);
392 * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)
395 @Transactional(readOnly
= false)
396 public void updateTitleCache(Class
<?
extends Classification
> clazz
, Integer stepSize
, IIdentifiableEntityCacheStrategy
<Classification
> cacheStrategy
, IProgressMonitor monitor
) {
398 clazz
= Classification
.class;
400 super.updateTitleCacheImpl(clazz
, stepSize
, cacheStrategy
, monitor
);