implement list find method for user and group services (#2283 and #2284). Tests are...
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / ClassificationServiceImpl.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.cdm.api.service;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.Comparator;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.TreeMap;
20 import java.util.UUID;
21
22 import javax.swing.tree.TreeNode;
23
24 import org.apache.log4j.Logger;
25 import org.springframework.beans.factory.annotation.Autowired;
26 import org.springframework.stereotype.Service;
27 import org.springframework.transaction.annotation.Propagation;
28 import org.springframework.transaction.annotation.Transactional;
29
30 import eu.etaxonomy.cdm.common.IProgressMonitor;
31 import eu.etaxonomy.cdm.model.agent.AgentBase;
32 import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;
33 import eu.etaxonomy.cdm.model.description.DescriptionBase;
34 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
35 import eu.etaxonomy.cdm.model.description.TaxonDescription;
36 import eu.etaxonomy.cdm.model.media.Media;
37 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
38 import eu.etaxonomy.cdm.model.media.MediaUtils;
39 import eu.etaxonomy.cdm.model.name.Rank;
40 import eu.etaxonomy.cdm.model.taxon.ITreeNode;
41 import eu.etaxonomy.cdm.model.taxon.Taxon;
42 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
43 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
44 import eu.etaxonomy.cdm.model.taxon.Classification;
45 import eu.etaxonomy.cdm.persistence.dao.BeanInitializer;
46 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
47 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
48 import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;
49 import eu.etaxonomy.cdm.persistence.query.OrderHint;
50 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
51
52 /**
53 * @author n.hoffmann
54 * @created Sep 21, 2009
55 * @version 1.0
56 */
57 @Service
58 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
59 public class ClassificationServiceImpl extends IdentifiableServiceBase<Classification, IClassificationDao> implements IClassificationService {
60 private static final Logger logger = Logger.getLogger(ClassificationServiceImpl.class);
61
62 @Autowired
63 private ITaxonNodeDao taxonNodeDao;
64 @Autowired
65 private ITaxonDao taxonDao;
66 @Autowired
67 private BeanInitializer defaultBeanInitializer;
68 private Comparator<? super TaxonNode> taxonNodeComparator;
69 @Autowired
70 public void setTaxonNodeComparator(ITaxonNodeComparator<? super TaxonNode> taxonNodeComparator){
71 this.taxonNodeComparator = (Comparator<? super TaxonNode>) taxonNodeComparator;
72 }
73
74
75 /*
76 * (non-Javadoc)
77 * @see eu.etaxonomy.cdm.api.service.IClassificationService#loadTaxonNodeByTaxon(eu.etaxonomy.cdm.model.taxon.Taxon, java.util.UUID, java.util.List)
78 */
79 public TaxonNode loadTaxonNodeByTaxon(Taxon taxon, UUID classificationUuid, List<String> propertyPaths){
80 Classification tree = dao.load(classificationUuid);
81 TaxonNode node = tree.getNode(taxon);
82
83 return loadTaxonNode(node.getUuid(), propertyPaths);
84 }
85
86 @Deprecated // use loadTaxonNode(UUID, List<String>) instead
87 public TaxonNode loadTaxonNode(TaxonNode taxonNode, List<String> propertyPaths){
88 return taxonNodeDao.load(taxonNode.getUuid(), propertyPaths);
89 }
90
91 public TaxonNode loadTaxonNode(UUID taxonNodeUuid, List<String> propertyPaths){
92 return taxonNodeDao.load(taxonNodeUuid, propertyPaths);
93 }
94
95 /*
96 * (non-Javadoc)
97 * @see eu.etaxonomy.cdm.api.service.IClassificationService#loadRankSpecificRootNodes(eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.model.name.Rank, java.util.List)
98 */
99 public List<TaxonNode> loadRankSpecificRootNodes(Classification classification, Rank rank, List<String> propertyPaths){
100
101 List<TaxonNode> rootNodes = dao.loadRankSpecificRootNodes(classification, rank, propertyPaths);
102
103 //sort nodes by TaxonName
104 Collections.sort(rootNodes, taxonNodeComparator);
105
106 // initialize all nodes
107 defaultBeanInitializer.initializeAll(rootNodes, propertyPaths);
108
109 return rootNodes;
110 }
111
112 /**
113 * (non-Javadoc)
114 * @see eu.etaxonomy.cdm.api.service.ITaxonService#loadTreeBranchTo(eu.etaxonomy.cdm.model.taxon.TaxonNode, eu.etaxonomy.cdm.model.name.Rank, java.util.List)
115 * FIXME Candidate for harmonization
116 * move to classification service
117 */
118 public List<TaxonNode> loadTreeBranch(TaxonNode taxonNode, Rank baseRank, List<String> propertyPaths){
119
120 TaxonNode thisNode = taxonNodeDao.load(taxonNode.getUuid(), propertyPaths);
121 List<TaxonNode> pathToRoot = new ArrayList<TaxonNode>();
122 pathToRoot.add(thisNode);
123
124 TaxonNode parentNode = thisNode.getParent();
125 while(parentNode != null){
126 TaxonNode parent = parentNode;
127 Rank parentNodeRank = parent.getTaxon().getName().getRank();
128 // stop if the next parent is higher than the baseRank
129 if(baseRank != null && baseRank.isLower(parentNodeRank)){
130 break;
131 }
132 pathToRoot.add(parentNode);
133 parentNode = parentNode.getParent();
134 }
135
136 // initialize and invert order of nodes in list
137 defaultBeanInitializer.initializeAll(pathToRoot, propertyPaths);
138 Collections.reverse(pathToRoot);
139
140 return pathToRoot;
141 }
142
143 /*
144 * (non-Javadoc)
145 * @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)
146 */
147 public List<TaxonNode> loadTreeBranchToTaxon(Taxon taxon, Classification classification, Rank baseRank, List<String> propertyPaths){
148 Classification tree = dao.load(classification.getUuid());
149 taxon = (Taxon) taxonDao.load(taxon.getUuid());
150 TaxonNode node = tree.getNode(taxon);
151 if(node == null){
152 logger.warn("The specified taxon is not found in the given tree.");
153 return null;
154 }
155 return loadTreeBranch(node, baseRank, propertyPaths);
156 }
157
158
159 /* (non-Javadoc)
160 * @see eu.etaxonomy.cdm.api.service.IClassificationService#loadChildNodesOfTaxon(eu.etaxonomy.cdm.model.taxon.TaxonNode, java.util.List)
161 */
162 public List<TaxonNode> loadChildNodesOfTaxonNode(TaxonNode taxonNode,
163 List<String> propertyPaths) {
164 taxonNode = taxonNodeDao.load(taxonNode.getUuid());
165 List<TaxonNode> childNodes = new ArrayList<TaxonNode>(taxonNode.getChildNodes());
166 defaultBeanInitializer.initializeAll(childNodes, propertyPaths);
167 Collections.sort(childNodes, taxonNodeComparator);
168 return childNodes;
169 }
170
171 /*
172 * (non-Javadoc)
173 * @see eu.etaxonomy.cdm.api.service.IClassificationService#loadChildNodesOfTaxon(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.Classification, java.util.List)
174 */
175 public List<TaxonNode> loadChildNodesOfTaxon(Taxon taxon, Classification classification, List<String> propertyPaths){
176 Classification tree = dao.load(classification.getUuid());
177 taxon = (Taxon) taxonDao.load(taxon.getUuid());
178
179 TaxonNode node = tree.getNode(taxon);
180 if(node != null){
181 return loadChildNodesOfTaxonNode(node, propertyPaths);
182 } else {
183 return null;
184 }
185 }
186
187
188
189 /*
190 * (non-Javadoc)
191 * @see eu.etaxonomy.cdm.api.service.IClassificationService#getTaxonNodeByUuid(java.util.UUID)
192 */
193 public TaxonNode getTaxonNodeByUuid(UUID uuid) {
194 return taxonNodeDao.findByUuid(uuid);
195 }
196
197 /*
198 * (non-Javadoc)
199 * @see eu.etaxonomy.cdm.api.service.IClassificationService#getTreeNodeByUuid(java.util.UUID)
200 */
201 public ITreeNode getTreeNodeByUuid(UUID uuid){
202 ITreeNode treeNode = taxonNodeDao.findByUuid(uuid);
203 if(treeNode == null){
204 treeNode = dao.findByUuid(uuid);
205 }
206
207 return treeNode;
208 }
209
210 /* (non-Javadoc)
211 * @see eu.etaxonomy.cdm.api.service.IClassificationService#listClassifications(java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
212 */
213 public List<Classification> listClassifications(Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
214 return dao.list(limit, start, orderHints, propertyPaths);
215 }
216
217 /* (non-Javadoc)
218 * @see eu.etaxonomy.cdm.api.service.IClassificationService#getClassificationByUuid(java.util.UUID)
219 */
220 public Classification getClassificationByUuid(UUID uuid){
221 return dao.findByUuid(uuid);
222 }
223
224 /* (non-Javadoc)
225 * @see eu.etaxonomy.cdm.api.service.IClassificationService#removeTaxonNode(eu.etaxonomy.cdm.model.taxon.Classification)
226 */
227 public UUID removeTaxonNode(TaxonNode taxonNode) {
228 return taxonNodeDao.delete(taxonNode);
229 }
230 /* (non-Javadoc)
231 * @see eu.etaxonomy.cdm.api.service.IClassificationService#removeTreeNode(eu.etaxonomy.cdm.model.taxon.ITreeNode)
232 */
233 public UUID removeTreeNode(ITreeNode treeNode) {
234 if(treeNode instanceof Classification){
235 return dao.delete((Classification) treeNode);
236 }else if(treeNode instanceof TaxonNode){
237 return taxonNodeDao.delete((TaxonNode)treeNode);
238 }
239 return null;
240 }
241 /* (non-Javadoc)
242 * @see eu.etaxonomy.cdm.api.service.IClassificationService#saveTaxonNode(eu.etaxonomy.cdm.model.taxon.Classification)
243 */
244 public UUID saveTaxonNode(TaxonNode taxonNode) {
245 return taxonNodeDao.save(taxonNode);
246 }
247
248 /*
249 * (non-Javadoc)
250 * @see eu.etaxonomy.cdm.api.service.IClassificationService#saveTaxonNodeAll(java.util.Collection)
251 */
252 public Map<UUID, TaxonNode> saveTaxonNodeAll(
253 Collection<TaxonNode> taxonNodeCollection) {
254 return taxonNodeDao.saveAll(taxonNodeCollection);
255 }
256
257 /* (non-Javadoc)
258 * @see eu.etaxonomy.cdm.api.service.IClassificationService#saveTreeNode(eu.etaxonomy.cdm.model.taxon.ITreeNode)
259 */
260 public UUID saveTreeNode(ITreeNode treeNode) {
261 if(treeNode instanceof Classification){
262 return dao.save((Classification) treeNode);
263 }else if(treeNode instanceof TaxonNode){
264 return taxonNodeDao.save((TaxonNode)treeNode);
265 }
266 return null;
267 }
268
269 public List<TaxonNode> getAllNodes(){
270 return taxonNodeDao.list(null,null);
271 }
272
273 /*
274 * (non-Javadoc)
275 * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheOfAcceptedTaxa(eu.etaxonomy.cdm.model.taxon.Classification)
276 */
277 public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(Classification classification) {
278 return taxonDao.getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(classification);
279 }
280
281 /* (non-Javadoc)
282 * @see eu.etaxonomy.cdm.api.service.IdentifiableServiceBase#getUuidAndTitleCache()
283 */
284 @Override
285 public List<UuidAndTitleCache<Classification>> getUuidAndTitleCache() {
286 return dao.getUuidAndTitleCache();
287 }
288
289 /* (non-Javadoc)
290 * @see eu.etaxonomy.cdm.api.service.IClassificationService#getAllMediaForChildNodes(eu.etaxonomy.cdm.model.taxon.TaxonNode, java.util.List, int, int, int, java.lang.String[])
291 */
292 public Map<UUID, List<MediaRepresentation>> getAllMediaForChildNodes(
293 TaxonNode taxonNode, List<String> propertyPaths, int size,
294 int height, int widthOrDuration, String[] mimeTypes) {
295
296 TreeMap<UUID, List<MediaRepresentation>> result = new TreeMap<UUID, List<MediaRepresentation>>();
297 List<Media> taxonMedia = new ArrayList<Media>();
298 List<MediaRepresentation> mediaRepresentations = new ArrayList<MediaRepresentation>();
299
300 //add all media of the children to the result map
301 if (taxonNode != null){
302
303 List<TaxonNode> nodes = new ArrayList<TaxonNode>();
304
305 nodes.add(loadTaxonNode(taxonNode, propertyPaths));
306 nodes.addAll(loadChildNodesOfTaxonNode(taxonNode, propertyPaths));
307
308 if (nodes != null){
309 for(TaxonNode node : nodes){
310 Taxon taxon = node.getTaxon();
311 for (TaxonDescription taxonDescription: taxon.getDescriptions()){
312 for (DescriptionElementBase descriptionElement: taxonDescription.getElements()){
313 for(Media media : descriptionElement.getMedia()){
314 taxonMedia.add(media);
315
316 //find the best matching representation
317 mediaRepresentations.add(MediaUtils.findBestMatchingRepresentation(media,size, height, widthOrDuration, mimeTypes));
318
319 }
320 }
321 }
322 result.put(taxon.getUuid(), mediaRepresentations);
323
324 }
325 }
326
327 }
328
329
330 return result;
331
332 }
333
334 public Map<UUID, List<MediaRepresentation>> getAllMediaForChildNodes(Taxon taxon, Classification taxTree, List<String> propertyPaths, int size, int height, int widthOrDuration, String[] mimeTypes){
335 TaxonNode node = taxTree.getNode(taxon);
336
337 return getAllMediaForChildNodes(node, propertyPaths, size, height, widthOrDuration, mimeTypes);
338 }
339
340
341
342
343
344 /* (non-Javadoc)
345 * @see eu.etaxonomy.cdm.api.service.ServiceBase#setDao(eu.etaxonomy.cdm.persistence.dao.common.ICdmEntityDao)
346 */
347 @Autowired
348 protected void setDao(IClassificationDao dao) {
349 this.dao = dao;
350 }
351
352
353 /* (non-Javadoc)
354 * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)
355 */
356 @Override
357 public void updateTitleCache(Class<? extends Classification> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<Classification> cacheStrategy, IProgressMonitor monitor) {
358 if (clazz == null){
359 clazz = Classification.class;
360 }
361 super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
362 }
363
364
365 }