Major Update to cdmlib-3.3
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / StatisticsServiceImpl.java
1 package eu.etaxonomy.cdm.api.service;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.apache.log4j.Logger;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.stereotype.Service;
9 import org.springframework.transaction.annotation.Transactional;
10
11 import eu.etaxonomy.cdm.api.service.statistics.Statistics;
12 import eu.etaxonomy.cdm.api.service.statistics.StatisticsConfigurator;
13 import eu.etaxonomy.cdm.api.service.statistics.StatisticsTypeEnum;
14 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
15 import eu.etaxonomy.cdm.model.description.DescriptionBase;
16 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
17 import eu.etaxonomy.cdm.model.taxon.Classification;
18 import eu.etaxonomy.cdm.model.taxon.Synonym;
19 import eu.etaxonomy.cdm.model.taxon.Taxon;
20 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
21 import eu.etaxonomy.cdm.persistence.dao.description.IDescriptionDao;
22 import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
23 import eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao;
24 import eu.etaxonomy.cdm.persistence.dao.statistics.IStatisticsDao;
25 import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;
26 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
27
28 /**
29 *
30 * @author s.buers Service to provide statistic data of the database elements
31 */
32
33 @Service
34 @Transactional
35 public class StatisticsServiceImpl implements IStatisticsService {
36
37 private static final Logger logger = Logger
38 .getLogger(StatisticsServiceImpl.class);
39
40
41
42 // this does not make sense, we just count nothing if no type is given.
43 // the one who calls this service should check that there are types given!
44 // private static final StatisticsTypeEnum DEFAULT_TYPE=StatisticsTypeEnum.ALL_TAXA;
45 //TODO create a list with all types.
46
47 // this constant can also be used by the ones that use the service
48
49 private static final IdentifiableEntity<?> ALL_DB = null;
50
51 @Override
52 @Transactional
53 public IdentifiableEntity<?> getFilterALL_DB(){
54 return ALL_DB;
55 }
56
57 private ArrayList<Statistics> statisticsList;
58
59 @Autowired
60 private ITaxonDao taxonDao;
61
62 @Autowired
63 private ITaxonNameDao taxonNameDao;
64
65 @Autowired
66 private IClassificationDao classificationDao;
67
68 @Autowired
69 private IReferenceDao referenceDao;
70
71 @Autowired
72 private IStatisticsDao statisticsDao;
73
74 @Autowired
75 private IDescriptionDao descriptionDao;
76
77 /**
78 * counts all the elements referenced in the configurator from the part of
79 * the database referenced in the configurator
80 *
81 * @param configurators
82 * @return be aware that a Statistics.countMap might contain "null"
83 * {@link Number} values, if the count failed (, if the value is "0"
84 * the count succeeded in counting zero elements.)
85 */
86 @Override
87 @Transactional
88 public List<Statistics> getCountStatistics(
89 List<StatisticsConfigurator> configurators) {
90
91 statisticsList = new ArrayList<Statistics>();
92
93 for (StatisticsConfigurator statisticsConfigurator : configurators) {
94 // create a Statistics element for each configurator
95 countStatisticsPart(statisticsConfigurator);
96 }
97 return this.statisticsList;
98 }
99
100 @Transactional
101 private void countStatisticsPart(StatisticsConfigurator configurator) {
102 // get last element of configurator.filter (the node that is the root
103 // for the count):
104 IdentifiableEntity filter = configurator.getFilter().get(
105 (configurator.getFilter().size()) - 1);
106 if (filter == getFilterALL_DB()) {
107 countAll(configurator);
108 } else { // check for classtype classification
109 countPart(configurator, filter);
110 }
111
112 }
113
114 /**
115 * @param configurator
116 */
117 private void countAll(StatisticsConfigurator configurator) {
118 Statistics statistics = new Statistics(configurator);
119
120 for (StatisticsTypeEnum type : configurator.getType()) {
121 Long counter = null;
122 switch (type) {
123
124 case ALL_TAXA:
125 counter = Long.valueOf(taxonDao.count(TaxonBase.class));
126 break;
127 case SYNONYMS:
128 counter = Long.valueOf(taxonDao.count(Synonym.class));
129 break;
130 case ACCEPTED_TAXA:
131 counter = Long.valueOf(taxonDao.count(Taxon.class));
132 break;
133 case ALL_REFERENCES:
134 counter = Long
135 .valueOf(referenceDao
136 .count(eu.etaxonomy.cdm.model.reference.Reference.class));
137 break;
138
139 case NOMECLATURAL_REFERENCES:
140
141 counter = statisticsDao.countNomenclaturalReferences();
142 break;
143
144 case CLASSIFICATION:
145 counter = Long.valueOf(classificationDao
146 .count(Classification.class));
147
148 break;
149
150 case TAXON_NAMES:
151 counter = Long.valueOf(taxonNameDao.count(TaxonNameBase.class));
152 break;
153
154 case DESCRIPTIVE_SOURCE_REFERENCES:
155
156 counter = statisticsDao.countDescriptiveSourceReferences();
157
158 break;
159 case DESCRIPTIONS:
160
161 counter = Long.valueOf(descriptionDao.count(DescriptionBase.class));
162
163 break;
164 }
165
166 statistics.addCount(type, counter);
167 }
168 statisticsList.add(statistics);
169 }
170
171 @Transactional
172 private void countPart(StatisticsConfigurator configurator,
173 IdentifiableEntity filter) {
174 // TODO maybe remove redundant parameter filter
175 Statistics statistics = new Statistics(configurator);
176
177 Long counter = null;
178
179 if (filter instanceof Classification) {
180
181 for (StatisticsTypeEnum type : configurator.getType()) {
182
183 switch (type) {
184 case CLASSIFICATION:
185 logger.info("there should not be any classification "
186 + "nested in an other classification");
187 // so do nothing
188 break;
189 case ACCEPTED_TAXA:
190 counter = statisticsDao.countTaxaInClassification(
191 Taxon.class, (Classification) filter);
192 break;
193
194 case ALL_TAXA:
195 counter = statisticsDao.countTaxaInClassification(
196 TaxonBase.class, (Classification) filter);
197 break;
198 case SYNONYMS:
199 counter = statisticsDao.countTaxaInClassification(
200 Synonym.class, (Classification) filter);
201 break;
202 case TAXON_NAMES:
203 counter = statisticsDao
204 .countTaxonNames((Classification) filter);
205 break;
206 case ALL_REFERENCES:
207 counter = statisticsDao.countReferencesInClassification((Classification) filter);
208 break;
209 case DESCRIPTIVE_SOURCE_REFERENCES:
210 counter = statisticsDao
211 .countDescriptive(true, (Classification) filter);
212 break;
213 case DESCRIPTIONS:
214 counter = statisticsDao
215 .countDescriptive(false, (Classification) filter);
216 break;
217 case NOMECLATURAL_REFERENCES:
218 counter = statisticsDao
219 .countNomenclaturalReferences((Classification) filter);
220 break;
221
222 }
223
224 statistics.addCount(type, counter);
225 }
226 } else if(filter instanceof Taxon) {
227 //TODO get all taxa of the tree:
228 do{
229 filter.getUuid();
230 statisticsDao.getTaxonTree(filter);
231 }while(true);
232 }else {
233 // we just return null as count for the statistics
234 // element, if the filter is neither classification nor null.
235 }
236
237 statisticsList.add(statistics);
238 }
239 }