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