Revision 3dd6c00e
Added by Andreas Müller over 8 years ago
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/validation/batch/BatchValidator.java | ||
---|---|---|
1 |
// $Id$ |
|
2 |
/** |
|
3 |
* Copyright (C) 2015 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 |
package eu.etaxonomy.cdm.api.validation.batch; |
|
11 |
|
|
12 |
import java.util.List; |
|
13 |
import java.util.Set; |
|
14 |
|
|
15 |
import javax.validation.ConstraintViolation; |
|
16 |
import javax.validation.Validation; |
|
17 |
import javax.validation.Validator; |
|
18 |
import javax.validation.ValidatorFactory; |
|
19 |
|
|
20 |
import org.apache.log4j.Logger; |
|
21 |
import org.hibernate.validator.HibernateValidator; |
|
22 |
import org.hibernate.validator.HibernateValidatorConfiguration; |
|
23 |
import org.springframework.context.ApplicationContext; |
|
24 |
import org.springframework.context.ApplicationContextAware; |
|
25 |
import org.springframework.orm.hibernate4.HibernateTransactionManager; |
|
26 |
import org.springframework.stereotype.Component; |
|
27 |
import org.springframework.transaction.PlatformTransactionManager; |
|
28 |
import org.springframework.transaction.TransactionDefinition; |
|
29 |
import org.springframework.transaction.TransactionStatus; |
|
30 |
import org.springframework.transaction.support.DefaultTransactionDefinition; |
|
31 |
|
|
32 |
import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration; |
|
33 |
import eu.etaxonomy.cdm.api.service.ICommonService; |
|
34 |
import eu.etaxonomy.cdm.api.service.IEntityValidationService; |
|
35 |
import eu.etaxonomy.cdm.api.service.IService; |
|
36 |
import eu.etaxonomy.cdm.model.common.CdmBase; |
|
37 |
import eu.etaxonomy.cdm.model.common.ICdmBase; |
|
38 |
import eu.etaxonomy.cdm.model.validation.CRUDEventType; |
|
39 |
import eu.etaxonomy.cdm.persistence.dao.jdbc.validation.EntityValidationCrudJdbcImpl; |
|
40 |
import eu.etaxonomy.cdm.validation.Level2; |
|
41 |
import eu.etaxonomy.cdm.validation.Level3; |
|
42 |
|
|
43 |
/** |
|
44 |
* @author ayco_holleman |
|
45 |
* @author a.mueller |
|
46 |
* @date 27 jan. 2015 |
|
47 |
* |
|
48 |
*/ |
|
49 |
@Component("batchValidator") |
|
50 |
public class BatchValidator implements Runnable, ApplicationContextAware { |
|
51 |
|
|
52 |
static final Class<?>[] DEFAULT_VALIDATION_GROUPS = new Class<?>[] { Level2.class, Level3.class }; |
|
53 |
|
|
54 |
private static final Logger logger = Logger.getLogger(BatchValidator.class); |
|
55 |
|
|
56 |
|
|
57 |
private ICdmApplicationConfiguration repository; |
|
58 |
|
|
59 |
private ApplicationContext appContext; |
|
60 |
|
|
61 |
private Validator validator; |
|
62 |
private Class<?>[] validationGroups; |
|
63 |
|
|
64 |
|
|
65 |
@Override |
|
66 |
public void setApplicationContext(ApplicationContext appContext) { |
|
67 |
this.appContext = appContext; |
|
68 |
} |
|
69 |
|
|
70 |
@Override |
|
71 |
public void run() { |
|
72 |
Thread.currentThread().setPriority(1); |
|
73 |
initValidator(); |
|
74 |
validate(); |
|
75 |
} |
|
76 |
|
|
77 |
/** |
|
78 |
* |
|
79 |
*/ |
|
80 |
private void initValidator() { |
|
81 |
if (getValidator() == null){ |
|
82 |
HibernateValidatorConfiguration config = Validation.byProvider(HibernateValidator.class).configure(); |
|
83 |
ValidatorFactory factory = config.buildValidatorFactory(); |
|
84 |
setValidator(factory.getValidator()); |
|
85 |
} |
|
86 |
if (validationGroups == null) { |
|
87 |
validationGroups = DEFAULT_VALIDATION_GROUPS; |
|
88 |
} |
|
89 |
} |
|
90 |
|
|
91 |
|
|
92 |
|
|
93 |
private <T extends ICdmBase, S extends T> void validate() { |
|
94 |
logger.info("Starting batch validation"); |
|
95 |
|
|
96 |
// Get service for saving errors to database |
|
97 |
// IEntityValidationService validationResultService = context.getEntityValidationService(); |
|
98 |
IEntityValidationService entityValidationService = appContext.getBean(IEntityValidationService.class); |
|
99 |
|
|
100 |
EntityValidationCrudJdbcImpl jdbcPersister = appContext.getBean(EntityValidationCrudJdbcImpl.class); |
|
101 |
|
|
102 |
// Get all services dealing with "real" entities |
|
103 |
List<Class<CdmBase>> classesToValidate = BatchValidationUtil.getClassesToValidate(); |
|
104 |
|
|
105 |
for (Class<CdmBase> entityClass : classesToValidate) { |
|
106 |
//TODO currently this seems to work only on the exact class, we may move it down |
|
107 |
//to single entity validation again but cache the information for each class |
|
108 |
if (true || BatchValidationUtil.isConstrainedEntityClass(validator, entityClass)){ |
|
109 |
|
|
110 |
// ICommonService commonService = repository.getCommonService(); |
|
111 |
ICommonService commonService = appContext.getBean(ICommonService.class); |
|
112 |
logger.info("Loading entities of type " + entityClass.getName()); |
|
113 |
//false for saving validation results |
|
114 |
//TODO can we handle results in a different transaction? |
|
115 |
boolean readOnly = false; |
|
116 |
TransactionStatus txStatus = startTransaction(readOnly); |
|
117 |
handleSingleClass(commonService, entityClass, entityValidationService, jdbcPersister); |
|
118 |
commitTransaction(txStatus); |
|
119 |
} |
|
120 |
} |
|
121 |
|
|
122 |
logger.info("Batch validation complete"); |
|
123 |
} |
|
124 |
|
|
125 |
/** |
|
126 |
* @param txStatus |
|
127 |
*/ |
|
128 |
private void commitTransaction(TransactionStatus txStatus) { |
|
129 |
PlatformTransactionManager txManager = getTransactionManager(); |
|
130 |
txManager.commit(txStatus); |
|
131 |
|
|
132 |
} |
|
133 |
|
|
134 |
/** |
|
135 |
* @param readOnly |
|
136 |
* @return |
|
137 |
* |
|
138 |
*/ |
|
139 |
private TransactionStatus startTransaction(boolean readOnly) { |
|
140 |
PlatformTransactionManager txManager = getTransactionManager(); |
|
141 |
|
|
142 |
DefaultTransactionDefinition defaultTxDef = new DefaultTransactionDefinition(); |
|
143 |
defaultTxDef.setReadOnly(readOnly); |
|
144 |
TransactionDefinition txDef = defaultTxDef; |
|
145 |
TransactionStatus txStatus = txManager.getTransaction(txDef); |
|
146 |
return txStatus; |
|
147 |
} |
|
148 |
|
|
149 |
/** |
|
150 |
* @return |
|
151 |
*/ |
|
152 |
private PlatformTransactionManager getTransactionManager() { |
|
153 |
PlatformTransactionManager txManager = appContext.getBean(HibernateTransactionManager.class); |
|
154 |
return txManager; |
|
155 |
} |
|
156 |
|
|
157 |
private void handleSingleClass(ICommonService commonService, Class<CdmBase> entityClass, IEntityValidationService entityValidationService, EntityValidationCrudJdbcImpl jdbcPersister) { |
|
158 |
int n = commonService.count(entityClass); |
|
159 |
int pageSize = 1000; |
|
160 |
for (int page = 0; page < n ; page = page + pageSize ){ |
|
161 |
handlePage(commonService, entityClass, entityValidationService, jdbcPersister, |
|
162 |
page/pageSize, pageSize); |
|
163 |
} |
|
164 |
} |
|
165 |
|
|
166 |
|
|
167 |
/** |
|
168 |
* @param commonService |
|
169 |
* @param entityClass |
|
170 |
* @param entityValidationService |
|
171 |
* @param jdbcPersister |
|
172 |
* |
|
173 |
*/ |
|
174 |
private void handlePage(ICommonService commonService, Class<CdmBase> entityClass, IEntityValidationService entityValidationService, EntityValidationCrudJdbcImpl jdbcPersister, int start, int pageSize) { |
|
175 |
|
|
176 |
List<CdmBase> entities; |
|
177 |
|
|
178 |
try { |
|
179 |
// commonService.count() |
|
180 |
entities = commonService.list(entityClass, pageSize, 0, null, null); |
|
181 |
} catch (Throwable t) { |
|
182 |
//TODO handle exception |
|
183 |
logger.error("Failed to load entities", t); |
|
184 |
return; |
|
185 |
} |
|
186 |
for (CdmBase entity : entities) { |
|
187 |
try { |
|
188 |
Set<ConstraintViolation<CdmBase>> errors = getValidator().validate(entity, getValidationGroups()); |
|
189 |
if (errors.size() != 0) { |
|
190 |
if (logger.isInfoEnabled()){logger.info(errors.size() + " constraint violation(s) detected in entity " + entity.toString());} |
|
191 |
// entityValidationService.saveEntityValidation(entity, errors, CRUDEventType.NONE, |
|
192 |
// getValidationGroups()); |
|
193 |
|
|
194 |
jdbcPersister.saveEntityValidation(entity, errors, CRUDEventType.NONE, getValidationGroups()); |
|
195 |
} |
|
196 |
} catch (Exception e) { |
|
197 |
// TODO Exception handling |
|
198 |
e.printStackTrace(); |
|
199 |
} |
|
200 |
} |
|
201 |
|
|
202 |
} |
|
203 |
|
|
204 |
private <T extends ICdmBase, S extends T> void validate_old() { |
|
205 |
logger.info("Starting batch validation"); |
|
206 |
|
|
207 |
if (validationGroups == null) { |
|
208 |
validationGroups = DEFAULT_VALIDATION_GROUPS; |
|
209 |
} |
|
210 |
|
|
211 |
// Get service for saving errors to database |
|
212 |
IEntityValidationService validationResultService = repository.getEntityValidationService(); |
|
213 |
|
|
214 |
// Get all services dealing with "real" entities |
|
215 |
List<EntityValidationUnit<T, S>> validationUnits = BatchValidationUtil.getAvailableServices(repository); |
|
216 |
|
|
217 |
for (EntityValidationUnit<T, S> unit : validationUnits) { |
|
218 |
Class<S> entityClass = unit.getEntityClass(); |
|
219 |
IService<T> entityLoader = unit.getEntityLoader(); |
|
220 |
logger.info("Loading entities of type " + entityClass.getName()); |
|
221 |
List<S> entities; |
|
222 |
try { |
|
223 |
entities = entityLoader.list(entityClass, 0, 0, null, null); |
|
224 |
} catch (Throwable t) { |
|
225 |
logger.error("Failed to load entities", t); |
|
226 |
continue; |
|
227 |
} |
|
228 |
for (S entity : entities) { |
|
229 |
if (BatchValidationUtil.isConstrainedEntityClass(getValidator(), entity.getClass())) { |
|
230 |
Set<ConstraintViolation<S>> errors = getValidator().validate(entity, validationGroups); |
|
231 |
if (errors.size() != 0) { |
|
232 |
logger.warn(errors.size() + " error(s) detected in entity " + entity.toString()); |
|
233 |
validationResultService.saveEntityValidation(entity, errors, CRUDEventType.NONE, |
|
234 |
validationGroups); |
|
235 |
} |
|
236 |
} |
|
237 |
} |
|
238 |
} |
|
239 |
|
|
240 |
logger.info("Batch validation complete"); |
|
241 |
} |
|
242 |
|
|
243 |
/** |
|
244 |
* Get the application context that will provide the services that will, on |
|
245 |
* their turn, provide the entities to be validated. |
|
246 |
* |
|
247 |
* @return The application context |
|
248 |
*/ |
|
249 |
public ICdmApplicationConfiguration getAppController() { |
|
250 |
return repository; |
|
251 |
} |
|
252 |
|
|
253 |
/** |
|
254 |
* Set the application context. |
|
255 |
* |
|
256 |
* @param context |
|
257 |
* The application context |
|
258 |
*/ |
|
259 |
public void setAppController(ICdmApplicationConfiguration context) { |
|
260 |
this.repository = context; |
|
261 |
} |
|
262 |
|
|
263 |
/** |
|
264 |
* Get the {@code Validator} instance that will carry out the validations. |
|
265 |
* |
|
266 |
* @return The {@code Validator} |
|
267 |
*/ |
|
268 |
public Validator getValidator() { |
|
269 |
return validator; |
|
270 |
} |
|
271 |
|
|
272 |
/** |
|
273 |
* Set the {@code Validator} instance that will carry out the validations. |
|
274 |
* |
|
275 |
* @param validator |
|
276 |
* The {@code Validator} |
|
277 |
*/ |
|
278 |
public void setValidator(Validator validator) { |
|
279 |
this.validator = validator; |
|
280 |
} |
|
281 |
|
|
282 |
/** |
|
283 |
* Get the validation groups to be applied by the {@code Validator}. |
|
284 |
* |
|
285 |
* @return The validation groups |
|
286 |
*/ |
|
287 |
public Class<?>[] getValidationGroups() { |
|
288 |
return validationGroups; |
|
289 |
} |
|
290 |
|
|
291 |
/** |
|
292 |
* Set the validation groups to be applied by the {@code Validator}. By |
|
293 |
* default all Level2 and Level3 will be checked. So if that is what you |
|
294 |
* want, you do not need to call this method before calling {@link #run()}. |
|
295 |
* |
|
296 |
* @param validationGroups |
|
297 |
* The validation groups |
|
298 |
*/ |
|
299 |
public void setValidationGroups(Class<?>... validationGroups) { |
|
300 |
this.validationGroups = validationGroups; |
|
301 |
} |
|
302 |
|
|
303 |
} |
|
1 |
// $Id$ |
|
2 |
/** |
|
3 |
* Copyright (C) 2015 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 |
package eu.etaxonomy.cdm.api.validation.batch; |
|
11 |
|
|
12 |
import java.util.List; |
|
13 |
import java.util.Set; |
|
14 |
|
|
15 |
import javax.validation.ConstraintViolation; |
|
16 |
import javax.validation.Validation; |
|
17 |
import javax.validation.Validator; |
|
18 |
import javax.validation.ValidatorFactory; |
|
19 |
|
|
20 |
import org.apache.log4j.Logger; |
|
21 |
import org.hibernate.validator.HibernateValidator; |
|
22 |
import org.hibernate.validator.HibernateValidatorConfiguration; |
|
23 |
import org.springframework.context.ApplicationContext; |
|
24 |
import org.springframework.context.ApplicationContextAware; |
|
25 |
import org.springframework.orm.hibernate5.HibernateTransactionManager; |
|
26 |
import org.springframework.stereotype.Component; |
|
27 |
import org.springframework.transaction.PlatformTransactionManager; |
|
28 |
import org.springframework.transaction.TransactionDefinition; |
|
29 |
import org.springframework.transaction.TransactionStatus; |
|
30 |
import org.springframework.transaction.support.DefaultTransactionDefinition; |
|
31 |
|
|
32 |
import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration; |
|
33 |
import eu.etaxonomy.cdm.api.service.ICommonService; |
|
34 |
import eu.etaxonomy.cdm.api.service.IEntityValidationService; |
|
35 |
import eu.etaxonomy.cdm.api.service.IService; |
|
36 |
import eu.etaxonomy.cdm.model.common.CdmBase; |
|
37 |
import eu.etaxonomy.cdm.model.common.ICdmBase; |
|
38 |
import eu.etaxonomy.cdm.model.validation.CRUDEventType; |
|
39 |
import eu.etaxonomy.cdm.persistence.dao.jdbc.validation.EntityValidationCrudJdbcImpl; |
|
40 |
import eu.etaxonomy.cdm.validation.Level2; |
|
41 |
import eu.etaxonomy.cdm.validation.Level3; |
|
42 |
|
|
43 |
/** |
|
44 |
* @author ayco_holleman |
|
45 |
* @author a.mueller |
|
46 |
* @date 27 jan. 2015 |
|
47 |
* |
|
48 |
*/ |
|
49 |
@Component("batchValidator") |
|
50 |
public class BatchValidator implements Runnable, ApplicationContextAware { |
|
51 |
|
|
52 |
static final Class<?>[] DEFAULT_VALIDATION_GROUPS = new Class<?>[] { Level2.class, Level3.class }; |
|
53 |
|
|
54 |
private static final Logger logger = Logger.getLogger(BatchValidator.class); |
|
55 |
|
|
56 |
|
|
57 |
private ICdmApplicationConfiguration repository; |
|
58 |
|
|
59 |
private ApplicationContext appContext; |
|
60 |
|
|
61 |
private Validator validator; |
|
62 |
private Class<?>[] validationGroups; |
|
63 |
|
|
64 |
|
|
65 |
@Override |
|
66 |
public void setApplicationContext(ApplicationContext appContext) { |
|
67 |
this.appContext = appContext; |
|
68 |
} |
|
69 |
|
|
70 |
@Override |
|
71 |
public void run() { |
|
72 |
Thread.currentThread().setPriority(1); |
|
73 |
initValidator(); |
|
74 |
validate(); |
|
75 |
} |
|
76 |
|
|
77 |
/** |
|
78 |
* |
|
79 |
*/ |
|
80 |
private void initValidator() { |
|
81 |
if (getValidator() == null){ |
|
82 |
HibernateValidatorConfiguration config = Validation.byProvider(HibernateValidator.class).configure(); |
|
83 |
ValidatorFactory factory = config.buildValidatorFactory(); |
|
84 |
setValidator(factory.getValidator()); |
|
85 |
} |
|
86 |
if (validationGroups == null) { |
|
87 |
validationGroups = DEFAULT_VALIDATION_GROUPS; |
|
88 |
} |
|
89 |
} |
|
90 |
|
|
91 |
|
|
92 |
|
|
93 |
private <T extends ICdmBase, S extends T> void validate() { |
|
94 |
logger.info("Starting batch validation"); |
|
95 |
|
|
96 |
// Get service for saving errors to database |
|
97 |
// IEntityValidationService validationResultService = context.getEntityValidationService(); |
|
98 |
IEntityValidationService entityValidationService = appContext.getBean(IEntityValidationService.class); |
|
99 |
|
|
100 |
EntityValidationCrudJdbcImpl jdbcPersister = appContext.getBean(EntityValidationCrudJdbcImpl.class); |
|
101 |
|
|
102 |
// Get all services dealing with "real" entities |
|
103 |
List<Class<CdmBase>> classesToValidate = BatchValidationUtil.getClassesToValidate(); |
|
104 |
|
|
105 |
for (Class<CdmBase> entityClass : classesToValidate) { |
|
106 |
//TODO currently this seems to work only on the exact class, we may move it down |
|
107 |
//to single entity validation again but cache the information for each class |
|
108 |
if (true || BatchValidationUtil.isConstrainedEntityClass(validator, entityClass)){ |
|
109 |
|
|
110 |
// ICommonService commonService = repository.getCommonService(); |
|
111 |
ICommonService commonService = appContext.getBean(ICommonService.class); |
|
112 |
logger.info("Loading entities of type " + entityClass.getName()); |
|
113 |
//false for saving validation results |
|
114 |
//TODO can we handle results in a different transaction? |
|
115 |
boolean readOnly = false; |
|
116 |
TransactionStatus txStatus = startTransaction(readOnly); |
|
117 |
handleSingleClass(commonService, entityClass, entityValidationService, jdbcPersister); |
|
118 |
commitTransaction(txStatus); |
|
119 |
} |
|
120 |
} |
|
121 |
|
|
122 |
logger.info("Batch validation complete"); |
|
123 |
} |
|
124 |
|
|
125 |
/** |
|
126 |
* @param txStatus |
|
127 |
*/ |
|
128 |
private void commitTransaction(TransactionStatus txStatus) { |
|
129 |
PlatformTransactionManager txManager = getTransactionManager(); |
|
130 |
txManager.commit(txStatus); |
|
131 |
|
|
132 |
} |
|
133 |
|
|
134 |
/** |
|
135 |
* @param readOnly |
|
136 |
* @return |
|
137 |
* |
|
138 |
*/ |
|
139 |
private TransactionStatus startTransaction(boolean readOnly) { |
|
140 |
PlatformTransactionManager txManager = getTransactionManager(); |
|
141 |
|
|
142 |
DefaultTransactionDefinition defaultTxDef = new DefaultTransactionDefinition(); |
|
143 |
defaultTxDef.setReadOnly(readOnly); |
|
144 |
TransactionDefinition txDef = defaultTxDef; |
|
145 |
TransactionStatus txStatus = txManager.getTransaction(txDef); |
|
146 |
return txStatus; |
|
147 |
} |
|
148 |
|
|
149 |
/** |
|
150 |
* @return |
|
151 |
*/ |
|
152 |
private PlatformTransactionManager getTransactionManager() { |
|
153 |
PlatformTransactionManager txManager = appContext.getBean(HibernateTransactionManager.class); |
|
154 |
return txManager; |
|
155 |
} |
|
156 |
|
|
157 |
private void handleSingleClass(ICommonService commonService, Class<CdmBase> entityClass, IEntityValidationService entityValidationService, EntityValidationCrudJdbcImpl jdbcPersister) { |
|
158 |
int n = commonService.count(entityClass); |
|
159 |
int pageSize = 1000; |
|
160 |
for (int page = 0; page < n ; page = page + pageSize ){ |
|
161 |
handlePage(commonService, entityClass, entityValidationService, jdbcPersister, |
|
162 |
page/pageSize, pageSize); |
|
163 |
} |
|
164 |
} |
|
165 |
|
|
166 |
|
|
167 |
/** |
|
168 |
* @param commonService |
|
169 |
* @param entityClass |
|
170 |
* @param entityValidationService |
|
171 |
* @param jdbcPersister |
|
172 |
* |
|
173 |
*/ |
|
174 |
private void handlePage(ICommonService commonService, Class<CdmBase> entityClass, IEntityValidationService entityValidationService, EntityValidationCrudJdbcImpl jdbcPersister, int start, int pageSize) { |
|
175 |
|
|
176 |
List<CdmBase> entities; |
|
177 |
|
|
178 |
try { |
|
179 |
// commonService.count() |
|
180 |
entities = commonService.list(entityClass, pageSize, 0, null, null); |
|
181 |
} catch (Throwable t) { |
|
182 |
//TODO handle exception |
|
183 |
logger.error("Failed to load entities", t); |
|
184 |
return; |
|
185 |
} |
|
186 |
for (CdmBase entity : entities) { |
|
187 |
try { |
|
188 |
Set<ConstraintViolation<CdmBase>> errors = getValidator().validate(entity, getValidationGroups()); |
|
189 |
if (errors.size() != 0) { |
|
190 |
if (logger.isInfoEnabled()){logger.info(errors.size() + " constraint violation(s) detected in entity " + entity.toString());} |
|
191 |
// entityValidationService.saveEntityValidation(entity, errors, CRUDEventType.NONE, |
|
192 |
// getValidationGroups()); |
|
193 |
|
|
194 |
jdbcPersister.saveEntityValidation(entity, errors, CRUDEventType.NONE, getValidationGroups()); |
|
195 |
} |
|
196 |
} catch (Exception e) { |
|
197 |
// TODO Exception handling |
|
198 |
e.printStackTrace(); |
|
199 |
} |
|
200 |
} |
|
201 |
|
|
202 |
} |
|
203 |
|
|
204 |
private <T extends ICdmBase, S extends T> void validate_old() { |
|
205 |
logger.info("Starting batch validation"); |
|
206 |
|
|
207 |
if (validationGroups == null) { |
|
208 |
validationGroups = DEFAULT_VALIDATION_GROUPS; |
|
209 |
} |
|
210 |
|
|
211 |
// Get service for saving errors to database |
|
212 |
IEntityValidationService validationResultService = repository.getEntityValidationService(); |
|
213 |
|
|
214 |
// Get all services dealing with "real" entities |
|
215 |
List<EntityValidationUnit<T, S>> validationUnits = BatchValidationUtil.getAvailableServices(repository); |
|
216 |
|
|
217 |
for (EntityValidationUnit<T, S> unit : validationUnits) { |
|
218 |
Class<S> entityClass = unit.getEntityClass(); |
|
219 |
IService<T> entityLoader = unit.getEntityLoader(); |
|
220 |
logger.info("Loading entities of type " + entityClass.getName()); |
|
221 |
List<S> entities; |
|
222 |
try { |
|
223 |
entities = entityLoader.list(entityClass, 0, 0, null, null); |
|
224 |
} catch (Throwable t) { |
|
225 |
logger.error("Failed to load entities", t); |
|
226 |
continue; |
|
227 |
} |
|
228 |
for (S entity : entities) { |
|
229 |
if (BatchValidationUtil.isConstrainedEntityClass(getValidator(), entity.getClass())) { |
|
230 |
Set<ConstraintViolation<S>> errors = getValidator().validate(entity, validationGroups); |
|
231 |
if (errors.size() != 0) { |
|
232 |
logger.warn(errors.size() + " error(s) detected in entity " + entity.toString()); |
|
233 |
validationResultService.saveEntityValidation(entity, errors, CRUDEventType.NONE, |
|
234 |
validationGroups); |
|
235 |
} |
|
236 |
} |
|
237 |
} |
|
238 |
} |
|
239 |
|
|
240 |
logger.info("Batch validation complete"); |
|
241 |
} |
|
242 |
|
|
243 |
/** |
|
244 |
* Get the application context that will provide the services that will, on |
|
245 |
* their turn, provide the entities to be validated. |
|
246 |
* |
|
247 |
* @return The application context |
|
248 |
*/ |
|
249 |
public ICdmApplicationConfiguration getAppController() { |
|
250 |
return repository; |
|
251 |
} |
|
252 |
|
|
253 |
/** |
|
254 |
* Set the application context. |
|
255 |
* |
|
256 |
* @param context |
|
257 |
* The application context |
|
258 |
*/ |
|
259 |
public void setAppController(ICdmApplicationConfiguration context) { |
|
260 |
this.repository = context; |
|
261 |
} |
|
262 |
|
|
263 |
/** |
|
264 |
* Get the {@code Validator} instance that will carry out the validations. |
|
265 |
* |
|
266 |
* @return The {@code Validator} |
|
267 |
*/ |
|
268 |
public Validator getValidator() { |
|
269 |
return validator; |
|
270 |
} |
|
271 |
|
|
272 |
/** |
|
273 |
* Set the {@code Validator} instance that will carry out the validations. |
|
274 |
* |
|
275 |
* @param validator |
|
276 |
* The {@code Validator} |
|
277 |
*/ |
|
278 |
public void setValidator(Validator validator) { |
|
279 |
this.validator = validator; |
|
280 |
} |
|
281 |
|
|
282 |
/** |
|
283 |
* Get the validation groups to be applied by the {@code Validator}. |
|
284 |
* |
|
285 |
* @return The validation groups |
|
286 |
*/ |
|
287 |
public Class<?>[] getValidationGroups() { |
|
288 |
return validationGroups; |
|
289 |
} |
|
290 |
|
|
291 |
/** |
|
292 |
* Set the validation groups to be applied by the {@code Validator}. By |
|
293 |
* default all Level2 and Level3 will be checked. So if that is what you |
|
294 |
* want, you do not need to call this method before calling {@link #run()}. |
|
295 |
* |
|
296 |
* @param validationGroups |
|
297 |
* The validation groups |
|
298 |
*/ |
|
299 |
public void setValidationGroups(Class<?>... validationGroups) { |
|
300 |
this.validationGroups = validationGroups; |
|
301 |
} |
|
302 |
|
|
303 |
} |
Also available in: Unified diff
Upgrade to hibernate 5 with persistence tests running #4716