(no commit message)
[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 counter -=statisticsDao.countNomenclaturalReferences();
138 break;
139
140 case NOMECLATURAL_REFERENCES:
141
142 counter = statisticsDao.countNomenclaturalReferences();
143 break;
144
145 case CLASSIFICATION:
146 counter = Long.valueOf(classificationDao
147 .count(Classification.class));
148
149 break;
150
151 case TAXON_NAMES:
152 counter = Long.valueOf(taxonNameDao.count(TaxonNameBase.class));
153 break;
154
155 case DESCRIPTIVE_SOURCE_REFERENCES:
156
157 counter = statisticsDao.countDescriptiveSourceReferences();
158
159 break;
160 case DESCRIPTIONS:
161
162 counter = Long.valueOf(descriptionDao.count(DescriptionBase.class));
163
164 break;
165 }
166
167 statistics.addCount(type, counter);
168 }
169 statisticsList.add(statistics);
170 }
171
172 @Transactional
173 private void countPart(StatisticsConfigurator configurator,
174 IdentifiableEntity filter) {
175 // TODO maybe remove redundant parameter filter
176 Statistics statistics = new Statistics(configurator);
177
178 Long counter = null;
179
180 if (filter instanceof Classification) {
181
182 for (StatisticsTypeEnum type : configurator.getType()) {
183
184 switch (type) {
185 case CLASSIFICATION:
186 logger.info("there should not be any classification "
187 + "nested in an other classification");
188 // so we set counter to 1, as a classification itself is one classification
189 counter = new Long(1);
190 break;
191 case ACCEPTED_TAXA:
192 counter = statisticsDao.countTaxaInClassification(
193 Taxon.class, (Classification) filter);
194 break;
195
196 case ALL_TAXA:
197 counter = statisticsDao.countTaxaInClassification(
198 TaxonBase.class, (Classification) filter);
199 break;
200 case SYNONYMS:
201 counter = statisticsDao.countTaxaInClassification(
202 Synonym.class, (Classification) filter);
203 break;
204 case TAXON_NAMES:
205 counter = statisticsDao
206 .countTaxonNames((Classification) filter);
207 break;
208 case ALL_REFERENCES:
209 // counter = statisticsDao.countReferencesInClassification((Classification) filter);
210 counter = statisticsDao.countReferencesInClassificationWithUuids((Classification) filter);
211 counter+=statisticsDao
212 .countDescriptive(true, (Classification) filter);
213 break;
214 case DESCRIPTIVE_SOURCE_REFERENCES:
215 counter = statisticsDao
216 .countDescriptive(true, (Classification) filter);
217 break;
218 case DESCRIPTIONS:
219 counter = statisticsDao
220 .countDescriptive(false, (Classification) filter);
221 break;
222 case NOMECLATURAL_REFERENCES:
223 counter = statisticsDao
224 .countNomenclaturalReferences((Classification) filter);
225 break;
226
227 }
228
229 statistics.addCount(type, counter);
230 }
231 } else if(filter instanceof Taxon) {
232 //TODO get all taxa of the tree:
233 do{
234 filter.getUuid();
235 statisticsDao.getTaxonTree(filter);
236 }while(true);
237 }else {
238 // we just return null as count for the statistics
239 // element, if the filter is neither classification nor null.
240 }
241
242 statisticsList.add(statistics);
243 }
244 }