2 * Copyright (C) 2016 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.cdm
.api
.service
.longrunningService
;
11 import java
.io
.Serializable
;
12 import java
.util
.Arrays
;
13 import java
.util
.List
;
15 import org
.apache
.log4j
.Logger
;
16 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
17 import org
.springframework
.stereotype
.Component
;
19 import eu
.etaxonomy
.cdm
.api
.service
.IAgentService
;
20 import eu
.etaxonomy
.cdm
.api
.service
.IClassificationService
;
21 import eu
.etaxonomy
.cdm
.api
.service
.ICollectionService
;
22 import eu
.etaxonomy
.cdm
.api
.service
.IDescriptionService
;
23 import eu
.etaxonomy
.cdm
.api
.service
.IMediaService
;
24 import eu
.etaxonomy
.cdm
.api
.service
.INameService
;
25 import eu
.etaxonomy
.cdm
.api
.service
.IOccurrenceService
;
26 import eu
.etaxonomy
.cdm
.api
.service
.IPolytomousKeyService
;
27 import eu
.etaxonomy
.cdm
.api
.service
.IProgressMonitorService
;
28 import eu
.etaxonomy
.cdm
.api
.service
.IReferenceService
;
29 import eu
.etaxonomy
.cdm
.api
.service
.ITaxonService
;
30 import eu
.etaxonomy
.cdm
.api
.service
.ITermService
;
31 import eu
.etaxonomy
.cdm
.api
.service
.ITermTreeService
;
32 import eu
.etaxonomy
.cdm
.api
.service
.IVocabularyService
;
33 import eu
.etaxonomy
.cdm
.api
.service
.UpdateResult
;
34 import eu
.etaxonomy
.cdm
.api
.service
.config
.CacheUpdaterConfigurator
;
35 import eu
.etaxonomy
.cdm
.common
.monitor
.IProgressMonitor
;
36 import eu
.etaxonomy
.cdm
.common
.monitor
.SubProgressMonitor
;
37 import eu
.etaxonomy
.cdm
.model
.agent
.AgentBase
;
38 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
39 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionBase
;
40 import eu
.etaxonomy
.cdm
.model
.description
.PolytomousKey
;
41 import eu
.etaxonomy
.cdm
.model
.media
.IdentifiableMediaEntity
;
42 import eu
.etaxonomy
.cdm
.model
.media
.Media
;
43 import eu
.etaxonomy
.cdm
.model
.molecular
.Sequence
;
44 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
45 import eu
.etaxonomy
.cdm
.model
.occurrence
.Collection
;
46 import eu
.etaxonomy
.cdm
.model
.occurrence
.SpecimenOrObservationBase
;
47 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
48 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
49 import eu
.etaxonomy
.cdm
.model
.taxon
.TaxonBase
;
50 import eu
.etaxonomy
.cdm
.model
.term
.DefinedTermBase
;
51 import eu
.etaxonomy
.cdm
.model
.term
.TermBase
;
52 import eu
.etaxonomy
.cdm
.model
.term
.TermTree
;
53 import eu
.etaxonomy
.cdm
.model
.term
.TermVocabulary
;
57 * Updates caches for given CDM classes.
63 public class CacheUpdater
implements Serializable
{
65 private static final long serialVersionUID
= -1410600568024821771L;
66 private static final Logger logger
= Logger
.getLogger(CacheUpdater
.class);
69 protected INameService nameService
;
71 protected ITaxonService taxonService
;
73 protected IClassificationService classificationService
;
75 protected IReferenceService referenceService
;
77 protected IAgentService agentService
;
79 protected IOccurrenceService occurrenceService
;
81 protected ITermService termService
;
83 protected IDescriptionService descriptionService
;
85 protected ICollectionService collectionService
;
87 protected ITermTreeService termTreeService
;
89 protected IVocabularyService vocabularyService
;
91 protected IPolytomousKeyService polytomousKeyService
;
93 protected IMediaService mediaService
;
95 protected IProgressMonitorService progressMonitorService
;
99 public UpdateResult
doInvoke(CacheUpdaterConfigurator config
) {
100 UpdateResult result
= new UpdateResult();
101 IProgressMonitor monitor
= config
.getMonitor();
102 monitor
.beginTask("Update caches", 100);
103 monitor
.subTask("Check start conditions");
104 if (config
.getClassList() == null || config
.getClassList().isEmpty()){
105 //!! not yet implemented
106 logger
.warn("Create class list from boolean values is not yet implemented for cache updater");
107 createClassListFromBoolean();
110 monitor
.subTask("Count records");
111 Integer count
= countAllUpdatableObjects(config
.getClassList());
113 SubProgressMonitor subMonitor
= SubProgressMonitor
.NewStarted(monitor
, 90, "Updating secundum for subtree", count
* 2); //*2 1 tick for update and 1 tick for commit
116 result
= handleClassList(config
.getClassList(), subMonitor
);
117 config
.getMonitor().done();
121 private UpdateResult
handleClassList(List
<Class
<?
extends IdentifiableEntity
>> classList
, IProgressMonitor monitor
) {
122 UpdateResult result
= new UpdateResult();
123 int ticksForSubTasks
= 100/classList
.size();
124 for (Class
<?
extends IdentifiableEntity
> clazz
: classList
){
125 //WE need to separate classes , because hibernate
126 //returns multiple values for service.count() for e.g. IdentifableEntity.class
127 //which leads to an exception
128 UpdateResult multipleResult
= handleMultiTableClasses(clazz
, monitor
);
130 if (multipleResult
== null){
131 monitor
.subTask("Update " + clazz
.getSimpleName());
132 // SubProgressMonitor subMonitor= new SubProgressMonitor(monitor, ticksForSubTasks);
133 //subMonitor.setTaskName("Update " + clazz.getSimpleName());
134 result
.includeResult(this.handleSingleTableClass(clazz
, monitor
));
136 result
.includeResult(multipleResult
);
142 private UpdateResult
handleMultiTableClasses(Class
<?
extends IdentifiableEntity
> clazz
, IProgressMonitor monitor
) {
143 if (clazz
.isAssignableFrom(IdentifiableEntity
.class)){
144 @SuppressWarnings("rawtypes")
145 List list
= Arrays
.asList(new Class
[]{
146 DescriptionBase
.class, IdentifiableMediaEntity
.class,
147 Media
.class, Sequence
.class,
148 TaxonBase
.class, TaxonName
.class,
149 Classification
.class, TermBase
.class
151 return handleClassList(list
, monitor
);
152 }else if (clazz
.isAssignableFrom(IdentifiableMediaEntity
.class)){
153 @SuppressWarnings("rawtypes")
154 List list
= Arrays
.asList(new Class
[]{AgentBase
.class, Collection
.class, Reference
.class, SpecimenOrObservationBase
.class});
155 return handleClassList(list
, monitor
);
156 }else if (clazz
.isAssignableFrom(TermBase
.class)){
157 @SuppressWarnings("rawtypes")
158 List list
= Arrays
.asList(new Class
[]{DefinedTermBase
.class, TermTree
.class, TermVocabulary
.class });
159 return handleClassList(list
, monitor
);
165 private UpdateResult
handleSingleTableClass(Class
<?
extends IdentifiableEntity
> clazz
, IProgressMonitor subMonitor
) {
167 UpdateResult result
= new UpdateResult();
171 logger
.info("Updating class " + clazz
.getSimpleName() + " ...");
175 if (DefinedTermBase
.class.isAssignableFrom(clazz
)){
176 result
.includeResult(termService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
177 }else if (TermTree
.class.isAssignableFrom(clazz
)){
178 result
.includeResult(termTreeService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
179 }else if (TermVocabulary
.class.isAssignableFrom(clazz
)){
180 result
.includeResult(vocabularyService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
183 else if (DescriptionBase
.class.isAssignableFrom(clazz
)){
184 result
.includeResult(descriptionService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
187 else if (Media
.class.isAssignableFrom(clazz
)){
188 result
.includeResult(mediaService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
190 else if (TaxonBase
.class.isAssignableFrom(clazz
)){
191 result
.includeResult(taxonService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
193 //IdentifiableMediaEntity
194 else if (AgentBase
.class.isAssignableFrom(clazz
)){
195 result
.includeResult(agentService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
196 }else if (Collection
.class.isAssignableFrom(clazz
)){
197 result
.includeResult(collectionService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
198 }else if (Reference
.class.isAssignableFrom(clazz
)){
199 result
.includeResult(referenceService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
200 }else if (SpecimenOrObservationBase
.class.isAssignableFrom(clazz
)){
201 result
.includeResult(occurrenceService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
204 // //Sequence //currently not identifiable and therefore has not caches
205 // else if (Sequence.class.isAssignableFrom(clazz)){
206 // //TODO misuse TaxonService for sequence update, use sequence service when it exists
207 // getTaxonService().updateTitleCache((Class) clazz, null, null, null);
210 else if (TaxonName
.class.isAssignableFrom(clazz
)){
212 result
.includeResult(nameService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
215 else if (Classification
.class.isAssignableFrom(clazz
)){
216 result
.includeResult(classificationService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
219 else if (PolytomousKey
.class.isAssignableFrom(clazz
)){
220 result
.includeResult(polytomousKeyService
.updateCaches((Class
) clazz
, null, null, subMonitor
));
225 String warning
= "Unknown identifable entity subclass + " + clazz
.getName();
226 logger
.error(warning
);
228 result
.addException(new Exception(warning
));
232 } catch (Exception e
) {
233 String warning
= "Exception occurred when trying to update class + " + clazz
.getName();
234 warning
+= " Exception was: " + e
.getMessage();
235 logger
.error(warning
);
238 result
.addException(e
);
243 private Integer
countAllUpdatableObjects(List
<Class
<?
extends IdentifiableEntity
>> list
){
247 for (Class clazz
: list
){
249 logger
.info("count class " + clazz
.getSimpleName() + " ...");
253 if (DefinedTermBase
.class.isAssignableFrom(clazz
)){
254 count
+= termService
.count(clazz
);
255 }else if (TermTree
.class.isAssignableFrom(clazz
)){
256 count
+=termTreeService
.count(clazz
);
257 }else if (TermVocabulary
.class.isAssignableFrom(clazz
)){
258 count
+= vocabularyService
.count(clazz
);
261 else if (DescriptionBase
.class.isAssignableFrom(clazz
)){
262 count
+= descriptionService
.count(clazz
);
265 else if (Media
.class.isAssignableFrom(clazz
)){
266 count
+= mediaService
.count(clazz
);
268 else if (TaxonBase
.class.isAssignableFrom(clazz
)){
269 count
+= taxonService
.count(clazz
);
271 //IdentifiableMediaEntity
272 else if (AgentBase
.class.isAssignableFrom(clazz
)){
273 count
+= agentService
.count(clazz
);
274 }else if (Collection
.class.isAssignableFrom(clazz
)){
275 count
+= collectionService
.count(clazz
);
276 }else if (Reference
.class.isAssignableFrom(clazz
)){
277 count
+= referenceService
.count(clazz
);
278 }else if (SpecimenOrObservationBase
.class.isAssignableFrom(clazz
)){
279 count
+= occurrenceService
.count(clazz
);
282 // //Sequence //currently not identifiable and therefore has not caches
283 // else if (Sequence.class.isAssignableFrom(clazz)){
284 // //TODO misuse TaxonService for sequence update, use sequence service when it exists
285 // getTaxonService().updateTitleCache((Class) clazz, null, null, null);
288 else if (TaxonName
.class.isAssignableFrom(clazz
)){
290 count
+= nameService
.count(clazz
);
293 else if (Classification
.class.isAssignableFrom(clazz
)){
294 count
+= classificationService
.count(clazz
);
297 else if (PolytomousKey
.class.isAssignableFrom(clazz
)){
298 count
+= polytomousKeyService
.count(clazz
);
304 private void createClassListFromBoolean() {
305 logger
.warn("Create class list from boolean not yet implemented. Can't run cache updater");