Session clean
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / DescriptionServiceImpl.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.List;
16 import java.util.Map;
17 import java.util.Set;
18 import java.util.UUID;
19
20 import org.apache.log4j.Logger;
21 import org.springframework.beans.factory.annotation.Autowired;
22 import org.springframework.stereotype.Service;
23 import org.springframework.transaction.annotation.Transactional;
24
25 import eu.etaxonomy.cdm.api.service.pager.Pager;
26 import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
27 import eu.etaxonomy.cdm.model.common.TermVocabulary;
28 import eu.etaxonomy.cdm.model.common.VersionableEntity;
29 import eu.etaxonomy.cdm.model.description.DescriptionBase;
30 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
31 import eu.etaxonomy.cdm.model.description.Feature;
32 import eu.etaxonomy.cdm.model.description.FeatureNode;
33 import eu.etaxonomy.cdm.model.description.FeatureTree;
34 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTermBase;
35 import eu.etaxonomy.cdm.model.description.Scope;
36 import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
37 import eu.etaxonomy.cdm.model.description.TaxonDescription;
38 import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
39 import eu.etaxonomy.cdm.model.location.NamedArea;
40 import eu.etaxonomy.cdm.model.media.Media;
41 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
42 import eu.etaxonomy.cdm.model.taxon.Taxon;
43 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
44 import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
45 import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;
46 import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionElementDao;
47 import eu.etaxonomy.cdm.persistence.dao.description.IFeatureDao;
48 import eu.etaxonomy.cdm.persistence.dao.description.IFeatureNodeDao;
49 import eu.etaxonomy.cdm.persistence.dao.description.IFeatureTreeDao;
50 import eu.etaxonomy.cdm.persistence.dao.description.IStatisticalMeasurementValueDao;
51 import eu.etaxonomy.cdm.persistence.query.OrderHint;
52
53 /**
54 * @author a.mueller
55 * @created 24.06.2008
56 * @version 1.0
57 */
58 @Service
59 @Transactional(readOnly = true)
60 public class DescriptionServiceImpl extends IdentifiableServiceBase<DescriptionBase,IDescriptionDao> implements IDescriptionService {
61
62 private static final Logger logger = Logger.getLogger(DescriptionServiceImpl.class);
63
64 protected IDescriptionElementDao descriptionElementDao;
65 protected IFeatureTreeDao featureTreeDao;
66 protected IFeatureNodeDao featureNodeDao;
67 protected IFeatureDao featureDao;
68 protected ITermVocabularyDao vocabularyDao;
69 protected IStatisticalMeasurementValueDao statisticalMeasurementValueDao;
70
71 @Autowired
72 protected void setFeatureTreeDao(IFeatureTreeDao featureTreeDao) {
73 this.featureTreeDao = featureTreeDao;
74 }
75
76 @Autowired
77 protected void setFeatureNodeDao(IFeatureNodeDao featureNodeDao) {
78 this.featureNodeDao = featureNodeDao;
79 }
80
81 @Autowired
82 protected void setFeatureDao(IFeatureDao featureDao) {
83 this.featureDao = featureDao;
84 }
85
86 @Autowired
87 protected void setVocabularyDao(ITermVocabularyDao vocabularyDao) {
88 this.vocabularyDao = vocabularyDao;
89 }
90
91 @Autowired
92 protected void statisticalMeasurementValueDao(IStatisticalMeasurementValueDao statisticalMeasurementValueDao) {
93 this.statisticalMeasurementValueDao = statisticalMeasurementValueDao;
94 }
95
96 @Autowired
97 protected void setDescriptionElementDao(IDescriptionElementDao descriptionElementDao) {
98 this.descriptionElementDao = descriptionElementDao;
99 }
100
101 /**
102 *
103 */
104 public DescriptionServiceImpl() {
105 logger.debug("Load DescriptionService Bean");
106 }
107
108 /* (non-Javadoc)
109 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#getDescriptionBaseByUuid(java.util.UUID)
110 * FIXME Candidate for harmonization
111 * find
112 */
113 public DescriptionBase getDescriptionBaseByUuid(UUID uuid) {
114 return super.getCdmObjectByUuid(uuid);
115 }
116
117 /* (non-Javadoc)
118 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#saveDescription(eu.etaxonomy.cdm.model.description.DescriptionBase)
119 * FIXME Candidate for harmonization
120 * save
121 */
122 @Transactional(readOnly = false)
123 public UUID saveDescription(DescriptionBase description) {
124 return super.saveCdmObject(description);
125 }
126
127 /* (non-Javadoc)
128 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#saveDescription(eu.etaxonomy.cdm.model.description.DescriptionBase)
129 * FIXME Candidate for harmonization
130 * Given that statistcal measurement values are wholy owned by their parent QuantitativeData, do we need this method? could we not
131 * save / update statistical measurement values as part of descriptionElementService.update or descriptionElementService.save?
132 */
133 @Transactional(readOnly = false)
134 public UUID saveStatisticalMeasurementValue(StatisticalMeasurementValue statisticalMeasurementValue) {
135 return statisticalMeasurementValueDao.saveOrUpdate(statisticalMeasurementValue);
136 }
137
138 /* (non-Javadoc)
139 * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#generateTitleCache()
140 */
141 public void generateTitleCache() {
142 logger.warn("generateTitleCache not yet implemented");
143 }
144
145 /* (non-Javadoc)
146 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#saveFeatureTree(eu.etaxonomy.cdm.model.description.FeatureTree)
147 * FIXME Candidate for harmonization
148 * featureTreeService.save
149 */
150 @Transactional(readOnly = false)
151 public UUID saveFeatureTree(FeatureTree tree) {
152 return featureTreeDao.saveOrUpdate(tree);
153 }
154
155 /*
156 * (non-Javadoc)
157 * @see eu.etaxonomy.cdm.api.service.IDescriptionService#saveFeatureDataAll(java.util.Collection)
158 * FIXME Candidate for harmonization
159 * remove
160 * featureTreeService.save(FeatureTree f) and this cascades to child nodes or does this not work?
161 * CDM Xml now only has a list of FeatureTrees, and calls saveFeatureTreeAll(featureTrees);
162 */
163 @Transactional(readOnly = false)
164 public void saveFeatureDataAll(Collection<VersionableEntity> featureData) {
165
166 List<FeatureTree> trees = new ArrayList<FeatureTree>();
167 List<FeatureNode> nodes = new ArrayList<FeatureNode>();
168
169 for ( VersionableEntity featureItem : featureData) {
170 if (featureItem instanceof FeatureTree) {
171 trees.add((FeatureTree)featureItem);
172 } else if (featureItem instanceof FeatureNode) {
173 nodes.add((FeatureNode)featureItem);
174 } else {
175 logger.error("Entry of wrong type: " + featureItem.toString());
176 }
177 }
178
179 if (trees.size() > 0) { saveFeatureTreeAll(trees); }
180 if (nodes.size() > 0) { saveFeatureNodeAll(nodes); }
181 }
182
183 /**
184 * FIXME Candidate for harmonization
185 * featureTreeService.save(Set<FeatureTree> featureTrees)
186 */
187 @Transactional(readOnly = false)
188 public Map<UUID, FeatureTree> saveFeatureTreeAll(Collection<FeatureTree> trees) {
189 return featureTreeDao.saveAll(trees);
190 }
191
192 /**
193 * FIXME Candidate for harmonization
194 * is this needed?
195 */
196 @Transactional(readOnly = false)
197 public Map<UUID, FeatureNode> saveFeatureNodeAll(Collection<FeatureNode> trees) {
198 return featureNodeDao.saveAll(trees);
199 }
200
201 /**
202 * FIXME Candidate for harmonization
203 * vocabularyService.find(UUID uuid)
204 */
205 public TermVocabulary<Feature> getFeatureVocabulary(UUID uuid){
206 TermVocabulary<Feature> featureVocabulary;
207 try {
208 featureVocabulary = (TermVocabulary)vocabularyDao.findByUuid(uuid);
209 } catch (ClassCastException e) {
210 return null;
211 }
212 return featureVocabulary;
213 }
214
215 // public TermVocabulary<Feature> getFeatureVocabulary(){
216 // TermVocabulary<Feature> featureVocabulary;
217 // try {
218 // featureVocabulary = (TermVocabulary)vocabularyDao.findByUuid(uuid);
219 // } catch (ClassCastException e) {
220 // return null;
221 // }
222 // return featureVocabulary;
223 // }
224
225 public TermVocabulary<Feature> getDefaultFeatureVocabulary(){
226 String uuidFeature = "b187d555-f06f-4d65-9e53-da7c93f8eaa8";
227 UUID featureUuid = UUID.fromString(uuidFeature);
228 return getFeatureVocabulary(featureUuid);
229 }
230
231 /**
232 * FIXME Candidate for harmonization
233 * featureTreeService.list()
234 * @return
235 */
236 public List<FeatureTree> getFeatureTreesAll() {
237 return featureTreeDao.list();
238 }
239
240 /**
241 * FIXME Candidate for harmonization
242 * is this needed?
243 */
244 public List<FeatureNode> getFeatureNodesAll() {
245 return featureNodeDao.list();
246 }
247
248 /**
249 * FIXME Candidate for harmonization
250 * termService.list(Feature.class, null,null,...)
251 */
252 public List<Feature> getFeaturesAll() {
253 return featureDao.list();
254 }
255
256 /**
257 * FIXME Candidate for harmonization
258 * featureTreeService.list
259 */
260 public List<FeatureTree> getFeatureTreesAll(List<String> propertyPaths){
261 return featureTreeDao.list(null, null, null, propertyPaths);
262 }
263
264 /**
265 * FIXME Candidate for harmonization
266 * is this needed?
267 */
268 public List<FeatureNode> getFeatureNodesAll(List<String> propertyPaths){
269 return featureNodeDao.list(null, null, null, propertyPaths);
270 }
271
272 /**
273 * FIXME Candidate for harmonization
274 * termService.list
275 */
276 public List<Feature> getFeaturesAll(List<String> propertyPaths){
277 return featureDao.list(null, null, null, propertyPaths);
278 }
279
280 @Autowired
281 protected void setDao(IDescriptionDao dao) {
282 this.dao = dao;
283 }
284
285 /**
286 * FIXME Candidate for harmonization
287 * rename -> count
288 */
289 public <TYPE extends DescriptionBase> int countDescriptions(Class<TYPE> type, Boolean hasImages, Boolean hasText,Set<Feature> feature) {
290 return dao.countDescriptions(type, hasImages, hasText, feature);
291 }
292
293 /**
294 * FIXME Candidate for harmonization
295 * rename -> getElements
296 */
297 public <TYPE extends DescriptionElementBase> Pager<TYPE> getDescriptionElements(DescriptionBase description,
298 Set<Feature> features, Class<TYPE> type, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
299 Integer numberOfResults = dao.countDescriptionElements(description, features, type);
300
301 List<TYPE> results = new ArrayList<TYPE>();
302 if (numberOfResults > 0) { // no point checking again
303 results = dao.getDescriptionElements(description, features, type, pageSize, pageNumber, propertyPaths);
304 }
305
306 return new DefaultPagerImpl<TYPE>(pageNumber, numberOfResults, pageSize, results);
307 }
308
309
310 public Pager<Media> getMedia(DescriptionElementBase descriptionElement, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
311 Integer numberOfResults = descriptionElementDao.countMedia(descriptionElement);
312
313 List<Media> results = new ArrayList<Media>();
314 if(numberOfResults > 0) { // no point checking again
315 results = descriptionElementDao.getMedia(descriptionElement, pageSize, pageNumber, propertyPaths);
316 }
317
318 return new DefaultPagerImpl<Media>(pageNumber, numberOfResults, pageSize, results);
319 }
320
321 public Pager<TaxonDescription> getTaxonDescriptions(Taxon taxon, Set<Scope> scopes, Set<NamedArea> geographicalScope, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
322 Integer numberOfResults = dao.countTaxonDescriptions(taxon, scopes, geographicalScope);
323
324 List<TaxonDescription> results = new ArrayList<TaxonDescription>();
325 if(numberOfResults > 0) { // no point checking again
326 results = dao.getTaxonDescriptions(taxon, scopes, geographicalScope, pageSize, pageNumber, propertyPaths);
327 }
328
329 return new DefaultPagerImpl<TaxonDescription>(pageNumber, numberOfResults, pageSize, results);
330 }
331
332 public Pager<TaxonNameDescription> getTaxonNameDescriptions(TaxonNameBase name, Integer pageSize, Integer pageNumber, List<String> propertyPaths) {
333 Integer numberOfResults = dao.countTaxonNameDescriptions(name);
334
335 List<TaxonNameDescription> results = new ArrayList<TaxonNameDescription>();
336 if(numberOfResults > 0) { // no point checking again
337 results = dao.getTaxonNameDescriptions(name, pageSize, pageNumber,propertyPaths);
338 }
339
340 return new DefaultPagerImpl<TaxonNameDescription>(pageNumber, numberOfResults, pageSize, results);
341 }
342
343 /**
344 * FIXME Candidate for harmonization
345 * rename list
346 */
347 public <TYPE extends DescriptionBase> Pager<TYPE> listDescriptions(Class<TYPE> type, Boolean hasImages, Boolean hasText, Set<Feature> feature, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
348 Integer numberOfResults = dao.countDescriptions(type, hasImages, hasText, feature);
349
350 List<TYPE> results = new ArrayList<TYPE>();
351 if(numberOfResults > 0) { // no point checking again
352 results = dao.listDescriptions(type, hasImages, hasText, feature, pageSize, pageNumber,orderHints,propertyPaths);
353 }
354
355 return new DefaultPagerImpl<TYPE>(pageNumber, numberOfResults, pageSize, results);
356 }
357
358 /**
359 * FIXME Candidate for harmonization
360 * Rename: searchByDistribution
361 */
362 public Pager<TaxonDescription> searchDescriptionByDistribution(Set<NamedArea> namedAreas, PresenceAbsenceTermBase presence, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
363 Integer numberOfResults = dao.countDescriptionByDistribution(namedAreas, presence);
364
365 List<TaxonDescription> results = new ArrayList<TaxonDescription>();
366 if(numberOfResults > 0) { // no point checking again
367 results = dao.searchDescriptionByDistribution(namedAreas, presence, pageSize, pageNumber,orderHints,propertyPaths);
368 }
369
370 return new DefaultPagerImpl<TaxonDescription>(pageNumber, numberOfResults, pageSize, results);
371 }
372
373 /**
374 * FIXME Candidate for harmonization
375 * move: descriptionElementService.search
376 */
377 public Pager<DescriptionElementBase> search(Class<? extends DescriptionElementBase> clazz, String queryString, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
378 Integer numberOfResults = descriptionElementDao.count(clazz,queryString);
379
380 List<DescriptionElementBase> results = new ArrayList<DescriptionElementBase>();
381 if(numberOfResults > 0) { // no point checking again
382 results = descriptionElementDao.search(clazz, queryString, pageSize, pageNumber, orderHints, propertyPaths);
383 }
384
385 return new DefaultPagerImpl<DescriptionElementBase>(pageNumber, numberOfResults, pageSize, results);
386 }
387
388 /**
389 * FIXME Candidate for harmonization
390 * featureTreeService.find
391 */
392 public FeatureTree getFeatureTreeByUuid(UUID uuid) {
393 return featureTreeDao.findByUuid(uuid);
394 }
395
396 /**
397 * FIXME Candidate for harmonization
398 * descriptionElementService.find
399 */
400 public DescriptionElementBase getDescriptionElementByUuid(UUID uuid) {
401 return descriptionElementDao.findByUuid(uuid);
402 }
403
404 /**
405 * FIXME Candidate for harmonization
406 * is this needed? yes, I think it is, because there is no way to recursively
407 * initialize feature trees and all of their children otherwise
408 */
409 public FeatureNode loadFeatureNode(UUID uuid, List<String> propertyPaths) {
410 return featureNodeDao.load(uuid, propertyPaths);
411 }
412
413 /**
414 * FIXME Candidate for harmonization
415 * featureTreeService.load
416 */
417 public FeatureTree loadFeatureTree(UUID uuid, List<String> propertyPaths) {
418 return featureTreeDao.load(uuid, propertyPaths);
419 }
420
421 /**
422 * FIXME Candidate for harmonization
423 * descriptionElementService.load
424 */
425 public DescriptionElementBase loadDescriptionElement(UUID uuid, List<String> propertyPaths) {
426 return descriptionElementDao.load(uuid, propertyPaths);
427 }
428
429 /**
430 * FIXME Candidate for harmonization
431 * descriptionElementService.save
432 */
433 public UUID saveDescriptionElement(DescriptionElementBase descriptionElement) {
434 return descriptionElementDao.save(descriptionElement);
435 }
436
437 /**
438 * FIXME Candidate for harmonization
439 * descriptionElementService.delete
440 */
441 public UUID deleteDescriptionElement(DescriptionElementBase descriptionElement) {
442 return descriptionElementDao.delete(descriptionElement);
443 }
444 }