1
|
/**
|
2
|
* Copyright (C) 2015 EDIT
|
3
|
* European Distributed Institute of Taxonomy
|
4
|
* http://www.e-taxonomy.eu
|
5
|
*
|
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.
|
8
|
*/
|
9
|
package eu.etaxonomy.cdm.persistence.dao.jdbc.validation;
|
10
|
|
11
|
import java.sql.Connection;
|
12
|
import java.sql.Date;
|
13
|
import java.sql.PreparedStatement;
|
14
|
import java.sql.ResultSet;
|
15
|
import java.sql.SQLException;
|
16
|
import java.sql.Types;
|
17
|
import java.util.HashSet;
|
18
|
import java.util.Iterator;
|
19
|
import java.util.Set;
|
20
|
import java.util.UUID;
|
21
|
|
22
|
import javax.sql.DataSource;
|
23
|
import javax.validation.ConstraintViolation;
|
24
|
|
25
|
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
|
26
|
import org.joda.time.DateTime;
|
27
|
import org.springframework.beans.factory.annotation.Autowired;
|
28
|
import org.springframework.stereotype.Repository;
|
29
|
|
30
|
import eu.etaxonomy.cdm.model.common.ICdmBase;
|
31
|
import eu.etaxonomy.cdm.model.validation.CRUDEventType;
|
32
|
import eu.etaxonomy.cdm.model.validation.EntityConstraintViolation;
|
33
|
import eu.etaxonomy.cdm.model.validation.EntityValidation;
|
34
|
import eu.etaxonomy.cdm.model.validation.EntityValidationStatus;
|
35
|
import eu.etaxonomy.cdm.model.validation.Severity;
|
36
|
import eu.etaxonomy.cdm.persistence.dao.jdbc.JdbcDaoUtils;
|
37
|
import eu.etaxonomy.cdm.persistence.dao.validation.IEntityValidationCrud;
|
38
|
|
39
|
/**
|
40
|
* @author ayco_holleman
|
41
|
* @since 16 jan. 2015
|
42
|
*/
|
43
|
@Repository
|
44
|
public class EntityValidationCrudJdbcImpl implements IEntityValidationCrud {
|
45
|
|
46
|
public static final Logger logger = LogManager.getLogger(EntityValidationCrudJdbcImpl.class);
|
47
|
|
48
|
private static final String SQL_INSERT_VALIDATION_RESULT = "INSERT INTO entityvalidation"
|
49
|
+ "(id, created, uuid, crudeventtype, validatedentityclass, validatedentityid,"
|
50
|
+ "validatedentityuuid, userfriendlydescription, userfriendlytypename, validationcount,"
|
51
|
+ "updated, status, createdby_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
52
|
|
53
|
private static final int vr_id = 1;
|
54
|
private static final int vr_created = 2;
|
55
|
private static final int vr_uuid = 3;
|
56
|
private static final int vr_crudeventtype = 4;
|
57
|
private static final int vr_validatedentityclass = 5;
|
58
|
private static final int vr_validatedentityid = 6;
|
59
|
private static final int vr_validatedentityuuid = 7;
|
60
|
private static final int vr_userfriendlydescription = 8;
|
61
|
private static final int vr_userfriendlytypename = 9;
|
62
|
private static final int vr_validationcount = 10;
|
63
|
private static final int vr_updated = 11;
|
64
|
private static final int vr_status = 12;
|
65
|
private static final int vr_createdby_id = 13;
|
66
|
|
67
|
private static final String SQL_INSERT_CONSTRAINT_VIOLATION = "INSERT INTO entityconstraintviolation"
|
68
|
+ "(id, created, uuid, invalidvalue, message, propertypath, userfriendlyfieldname, severity,"
|
69
|
+ "validator, validationgroup, createdby_id, entityvalidation_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
|
70
|
|
71
|
private static final int cv_id = 1;
|
72
|
private static final int cv_created = 2;
|
73
|
private static final int cv_uuid = 3;
|
74
|
private static final int cv_invalidvalue = 4;
|
75
|
private static final int cv_message = 5;
|
76
|
private static final int cv_propertypath = 6;
|
77
|
private static final int cv_userfriendlyfieldname = 7;
|
78
|
private static final int cv_severity = 8;
|
79
|
private static final int cv_validator = 9;
|
80
|
private static final int cv_validationgroup = 10;
|
81
|
private static final int cv_createdby_id = 11;
|
82
|
private static final int cv_entityvalidation_id = 12;
|
83
|
|
84
|
@Autowired
|
85
|
private DataSource datasource;
|
86
|
|
87
|
public EntityValidationCrudJdbcImpl() {
|
88
|
|
89
|
}
|
90
|
|
91
|
public EntityValidationCrudJdbcImpl(DataSource datasource) {
|
92
|
this.datasource = datasource;
|
93
|
}
|
94
|
|
95
|
public void setDatasource(DataSource datasource) {
|
96
|
this.datasource = datasource;
|
97
|
}
|
98
|
|
99
|
@Override
|
100
|
public <T extends ICdmBase> void saveEntityValidation(T validatedEntity, Set<ConstraintViolation<T>> errors,
|
101
|
CRUDEventType crudEventType, Class<?>[] validationGroups) {
|
102
|
saveEntityValidation(createEntityValidation(validatedEntity, errors, crudEventType), validationGroups);
|
103
|
}
|
104
|
|
105
|
// This is the method that's tested by the unit tests
|
106
|
// rather than the interface method above, because it
|
107
|
// is almost impossible to create a mock instance of
|
108
|
// ConstraintViolation<T>
|
109
|
void saveEntityValidation(EntityValidation newValidation, Class<?>[] validationGroups) {
|
110
|
Connection conn = null;
|
111
|
EntityValidation tmp = null;
|
112
|
try {
|
113
|
conn = datasource.getConnection();
|
114
|
JdbcDaoUtils.startTransaction(conn);
|
115
|
String entityClass = newValidation.getValidatedEntityClass();
|
116
|
int entityId = newValidation.getValidatedEntityId();
|
117
|
EntityValidation oldValidation = getEntityValidation(conn, entityClass, entityId);
|
118
|
if (oldValidation == null) {
|
119
|
tmp = newValidation;
|
120
|
/*
|
121
|
* The entity has never been validated before. We should now
|
122
|
* create an entityvalidation record whether or not the entity
|
123
|
* has errors, because the entity HAS been validated so its
|
124
|
* validationcount is now 1.
|
125
|
*/
|
126
|
saveEntityValidationRecord(conn, newValidation);
|
127
|
Set<EntityConstraintViolation> errors = newValidation.getEntityConstraintViolations();
|
128
|
if (errors != null && errors.size() != 0) {
|
129
|
saveErrorRecords(conn, newValidation);
|
130
|
}
|
131
|
|
132
|
} else {
|
133
|
tmp = oldValidation;
|
134
|
// Increase validation counter
|
135
|
increaseValidationCounter(conn, oldValidation);
|
136
|
|
137
|
// Delete obsolete errors, that is, errors from the previous
|
138
|
// validation that have disappeared from the new validation
|
139
|
// even though they belong to the same validation group
|
140
|
dontDeleteErrorsInOtherValidationGroups(oldValidation, validationGroups);
|
141
|
// Now all errors have been removed from the previous validation
|
142
|
// that don't belong to the validation group(s) applied by the
|
143
|
// current validation. Set them apart because we need them
|
144
|
HashSet<EntityConstraintViolation> oldErrors = new HashSet<EntityConstraintViolation>(
|
145
|
oldValidation.getEntityConstraintViolations());
|
146
|
oldValidation.getEntityConstraintViolations().removeAll(newValidation.getEntityConstraintViolations());
|
147
|
// Now we're left with previous errors that have disappeared
|
148
|
// from the current validation (they have become obsolete)
|
149
|
deleteObsoleteErrors(conn, oldValidation);
|
150
|
|
151
|
// From the new errors delete all that are identical to
|
152
|
// errors from a previous validation (identical as per the
|
153
|
// equals() method of EntityConstraintViolation). These
|
154
|
// errors will not replace the old ones in order to limit
|
155
|
// the number of INSERTs.
|
156
|
newValidation.getEntityConstraintViolations().removeAll(oldErrors);
|
157
|
saveErrorRecords(conn, newValidation);
|
158
|
}
|
159
|
conn.commit();
|
160
|
setStatus(conn, tmp, EntityValidationStatus.OK);
|
161
|
} catch (Throwable t) {
|
162
|
logger.error("Error while saving validation result:", t);
|
163
|
setStatus(conn, tmp, EntityValidationStatus.ERROR);
|
164
|
JdbcDaoUtils.rollback(conn);
|
165
|
} finally {
|
166
|
JdbcDaoUtils.close(conn);
|
167
|
}
|
168
|
}
|
169
|
|
170
|
@Override
|
171
|
public void deleteEntityValidation(String validatedEntityClass, int validatedEntityId) {
|
172
|
Connection conn = null;
|
173
|
try {
|
174
|
conn = datasource.getConnection();
|
175
|
JdbcDaoUtils.startTransaction(conn);
|
176
|
int validationResultId = getValidationResultId(conn, validatedEntityClass, validatedEntityId);
|
177
|
if (validationResultId == -1) {
|
178
|
return;
|
179
|
}
|
180
|
deleteValidationResultRecord(conn, validationResultId);
|
181
|
deletedErrorRecords(conn, validationResultId, null);
|
182
|
conn.commit();
|
183
|
} catch (Throwable t) {
|
184
|
JdbcDaoUtils.rollback(conn);
|
185
|
}
|
186
|
JdbcDaoUtils.close(conn);
|
187
|
}
|
188
|
|
189
|
private static <T extends ICdmBase> EntityValidation createEntityValidation(T validatedEntity,
|
190
|
Set<ConstraintViolation<T>> errors, CRUDEventType crudEventType) {
|
191
|
EntityValidation entityValidation = EntityValidation.newInstance(validatedEntity, crudEventType);
|
192
|
Set<EntityConstraintViolation> errorEntities = new HashSet<EntityConstraintViolation>(errors.size());
|
193
|
for (ConstraintViolation<T> error : errors) {
|
194
|
EntityConstraintViolation errorEntity = EntityConstraintViolation.newInstance(validatedEntity, error);
|
195
|
errorEntities.add(errorEntity);
|
196
|
}
|
197
|
entityValidation.setEntityConstraintViolations(errorEntities);
|
198
|
return entityValidation;
|
199
|
}
|
200
|
|
201
|
private static void deletedErrorRecords(Connection conn, int validationResultId, Class<?>[] validationGroups)
|
202
|
throws SQLException {
|
203
|
StringBuilder sql = new StringBuilder(127);
|
204
|
sql.append("DELETE FROM entityconstraintviolation WHERE entityvalidation_id = ?");
|
205
|
if (validationGroups != null && validationGroups.length != 0) {
|
206
|
sql.append(" AND (");
|
207
|
for (int i = 0; i < validationGroups.length; ++i) {
|
208
|
if (i != 0) {
|
209
|
sql.append(" OR ");
|
210
|
}
|
211
|
sql.append("validationgroup = ?");
|
212
|
}
|
213
|
sql.append(")");
|
214
|
}
|
215
|
PreparedStatement stmt = null;
|
216
|
try {
|
217
|
stmt = conn.prepareStatement(sql.toString());
|
218
|
stmt.setInt(1, validationResultId);
|
219
|
if (validationGroups != null && validationGroups.length != 0) {
|
220
|
for (int i = 0; i < validationGroups.length; ++i) {
|
221
|
stmt.setString(i + 2, validationGroups[i].getName());
|
222
|
}
|
223
|
}
|
224
|
stmt.executeUpdate();
|
225
|
} finally {
|
226
|
JdbcDaoUtils.close(stmt);
|
227
|
}
|
228
|
}
|
229
|
|
230
|
private static void deleteObsoleteErrors(Connection conn, EntityValidation previousValidation) throws SQLException {
|
231
|
Set<EntityConstraintViolation> obsoleteErrors = previousValidation.getEntityConstraintViolations();
|
232
|
if (obsoleteErrors == null || obsoleteErrors.size() == 0) {
|
233
|
return;
|
234
|
}
|
235
|
String sql = "DELETE FROM entityconstraintviolation WHERE id = ?";
|
236
|
PreparedStatement stmt = null;
|
237
|
try {
|
238
|
stmt = conn.prepareStatement(sql.toString());
|
239
|
for (EntityConstraintViolation error : obsoleteErrors) {
|
240
|
stmt.setInt(1, error.getId());
|
241
|
stmt.executeUpdate();
|
242
|
}
|
243
|
} finally {
|
244
|
JdbcDaoUtils.close(stmt);
|
245
|
}
|
246
|
}
|
247
|
|
248
|
// Save EntityValidation entity to database. As a side effect
|
249
|
// the database id assigned to the entity will be set on the
|
250
|
// EntityValidation instance
|
251
|
private static void saveEntityValidationRecord(Connection conn, EntityValidation newValidation) throws SQLException {
|
252
|
PreparedStatement stmt = null;
|
253
|
try {
|
254
|
stmt = conn.prepareStatement(SQL_INSERT_VALIDATION_RESULT);
|
255
|
if (newValidation.getId() <= 0) {
|
256
|
int id = 10 + JdbcDaoUtils.fetchInt(conn, "SELECT MAX(id) FROM entityvalidation");
|
257
|
newValidation.setId(id);
|
258
|
}
|
259
|
stmt.setInt(vr_id, newValidation.getId());
|
260
|
stmt.setDate(vr_created, new Date(newValidation.getCreated().getMillis()));
|
261
|
stmt.setString(vr_uuid, newValidation.getUuid().toString());
|
262
|
stmt.setString(vr_crudeventtype, newValidation.getCrudEventType().toString());
|
263
|
stmt.setString(vr_validatedentityclass, newValidation.getValidatedEntityClass());
|
264
|
stmt.setInt(vr_validatedentityid, newValidation.getValidatedEntityId());
|
265
|
stmt.setString(vr_validatedentityuuid, newValidation.getValidatedEntityUuid().toString());
|
266
|
stmt.setString(vr_userfriendlydescription, newValidation.getUserFriendlyDescription());
|
267
|
stmt.setString(vr_userfriendlytypename, newValidation.getUserFriendlyTypeName());
|
268
|
stmt.setInt(vr_validationcount, 1);
|
269
|
stmt.setDate(vr_updated, new Date(newValidation.getCreated().getMillis()));
|
270
|
stmt.setString(vr_status, EntityValidationStatus.IN_PROGRESS.toString());
|
271
|
if (newValidation.getCreatedBy() != null) {
|
272
|
stmt.setInt(vr_createdby_id, newValidation.getCreatedBy().getId());
|
273
|
} else {
|
274
|
stmt.setNull(vr_createdby_id, Types.INTEGER);
|
275
|
}
|
276
|
stmt.executeUpdate();
|
277
|
} finally {
|
278
|
JdbcDaoUtils.close(stmt);
|
279
|
}
|
280
|
}
|
281
|
|
282
|
private static void increaseValidationCounter(Connection conn, EntityValidation entityValidation)
|
283
|
throws SQLException {
|
284
|
String sql = "UPDATE entityvalidation SET crudeventtype=?, validationcount = validationcount + 1, "
|
285
|
+ "updated = ?, status = ? WHERE id=?";
|
286
|
PreparedStatement stmt = null;
|
287
|
try {
|
288
|
stmt = conn.prepareStatement(sql);
|
289
|
if (entityValidation.getCrudEventType() == null) {
|
290
|
stmt.setString(1, null);
|
291
|
} else {
|
292
|
stmt.setString(1, entityValidation.getCrudEventType().toString());
|
293
|
}
|
294
|
stmt.setDate(2, new Date(new java.util.Date().getTime()));
|
295
|
stmt.setString(3, EntityValidationStatus.IN_PROGRESS.toString());
|
296
|
stmt.setInt(4, entityValidation.getId());
|
297
|
stmt.executeUpdate();
|
298
|
} finally {
|
299
|
JdbcDaoUtils.close(stmt);
|
300
|
}
|
301
|
}
|
302
|
|
303
|
private static <T extends ICdmBase> void saveErrorRecords(Connection conn, EntityValidation entityValidation)
|
304
|
throws SQLException {
|
305
|
Set<EntityConstraintViolation> errors = entityValidation.getEntityConstraintViolations();
|
306
|
if (errors == null || errors.size() == 0) {
|
307
|
return;
|
308
|
}
|
309
|
PreparedStatement stmt = null;
|
310
|
try {
|
311
|
stmt = conn.prepareStatement(SQL_INSERT_CONSTRAINT_VIOLATION);
|
312
|
for (EntityConstraintViolation error : errors) {
|
313
|
if (error.getId() <= 0) {
|
314
|
int id = 10 + JdbcDaoUtils.fetchInt(conn, "SELECT MAX(id) FROM entityconstraintviolation");
|
315
|
error.setId(id);
|
316
|
}
|
317
|
stmt.setInt(cv_id, error.getId());
|
318
|
stmt.setDate(cv_created, new Date(error.getCreated().getMillis()));
|
319
|
stmt.setString(cv_uuid, error.getUuid().toString());
|
320
|
stmt.setString(cv_invalidvalue, error.getInvalidValue());
|
321
|
stmt.setString(cv_message, error.getMessage());
|
322
|
stmt.setString(cv_propertypath, error.getPropertyPath());
|
323
|
stmt.setString(cv_userfriendlyfieldname, error.getUserFriendlyFieldName());
|
324
|
stmt.setString(cv_severity, error.getSeverity().toString());
|
325
|
stmt.setString(cv_validator, error.getValidator());
|
326
|
stmt.setString(cv_validationgroup, error.getValidationGroup());
|
327
|
if (error.getCreatedBy() != null) {
|
328
|
stmt.setInt(cv_createdby_id, error.getCreatedBy().getId());
|
329
|
} else {
|
330
|
stmt.setNull(cv_createdby_id, Types.INTEGER);
|
331
|
}
|
332
|
stmt.setInt(cv_entityvalidation_id, entityValidation.getId());
|
333
|
stmt.executeUpdate();
|
334
|
}
|
335
|
} finally {
|
336
|
JdbcDaoUtils.close(stmt);
|
337
|
}
|
338
|
}
|
339
|
|
340
|
// Called by unit test
|
341
|
EntityValidation getEntityValidation(String validatedEntityClass, int validatedEntityId) {
|
342
|
Connection conn = null;
|
343
|
try {
|
344
|
conn = datasource.getConnection();
|
345
|
JdbcDaoUtils.startTransaction(conn);
|
346
|
EntityValidation result = getEntityValidation(conn, validatedEntityClass, validatedEntityId);
|
347
|
conn.commit();
|
348
|
return result;
|
349
|
} catch (Throwable t) {
|
350
|
logger.error("Error while retrieving validation result", t);
|
351
|
JdbcDaoUtils.rollback(conn);
|
352
|
return null;
|
353
|
}
|
354
|
}
|
355
|
|
356
|
private static EntityValidation getEntityValidation(Connection conn, String validatedEntityClass,
|
357
|
int validatedEntityId) throws SQLException {
|
358
|
EntityValidation entityValidation = getEntityValidationRecord(conn, validatedEntityClass, validatedEntityId);
|
359
|
if (entityValidation != null) {
|
360
|
entityValidation.setEntityConstraintViolations(getErrorRecords(conn, entityValidation.getId()));
|
361
|
}
|
362
|
return entityValidation;
|
363
|
}
|
364
|
|
365
|
private static void deleteValidationResultRecord(Connection conn, int validationResultId) throws SQLException {
|
366
|
String sql = "DELETE FROM entityvalidation WHERE id = ?";
|
367
|
PreparedStatement stmt = conn.prepareStatement(sql);
|
368
|
stmt.setInt(1, validationResultId);
|
369
|
stmt.executeUpdate();
|
370
|
}
|
371
|
|
372
|
private static void setStatus(Connection conn, EntityValidation entityValidation, EntityValidationStatus status) {
|
373
|
if (conn == null || entityValidation == null || entityValidation.getId() <= 0) {
|
374
|
logger.warn("Failed to save entity validation status to database");
|
375
|
return;
|
376
|
}
|
377
|
String sql = "UPDATE entityvalidation SET status = ? WHERE id = ?";
|
378
|
PreparedStatement stmt = null;
|
379
|
try {
|
380
|
JdbcDaoUtils.startTransaction(conn);
|
381
|
stmt = conn.prepareStatement(sql);
|
382
|
stmt.setString(1, status.toString());
|
383
|
stmt.setInt(2, entityValidation.getId());
|
384
|
stmt.executeUpdate();
|
385
|
conn.commit();
|
386
|
} catch (Throwable t) {
|
387
|
logger.error("Failed to set validation status", t);
|
388
|
} finally {
|
389
|
JdbcDaoUtils.close(stmt);
|
390
|
}
|
391
|
}
|
392
|
|
393
|
private static <T extends ICdmBase> EntityValidation getEntityValidationRecord(Connection conn,
|
394
|
String validatedEntityClass, int validatedEntityId) throws SQLException {
|
395
|
String sqlCount = "SELECT count(*) as n FROM entityvalidation";
|
396
|
PreparedStatement stmtCount = conn.prepareStatement(sqlCount);
|
397
|
ResultSet rsCount = stmtCount.executeQuery();
|
398
|
if (rsCount.next()) {
|
399
|
int n = rsCount.getInt("n");
|
400
|
System.out.println("count=" + n);
|
401
|
}
|
402
|
|
403
|
String sql = "SELECT * FROM entityvalidation WHERE validatedentityclass=? AND validatedentityid=?";
|
404
|
EntityValidation result = null;
|
405
|
PreparedStatement stmt = null;
|
406
|
try {
|
407
|
stmt = conn.prepareStatement(sql);
|
408
|
stmt.setString(1, validatedEntityClass);
|
409
|
stmt.setInt(2, validatedEntityId);
|
410
|
ResultSet rs = stmt.executeQuery();
|
411
|
if (rs.next()) {
|
412
|
result = EntityValidation.newInstance();
|
413
|
result.setId(rs.getInt("id"));
|
414
|
Date d = rs.getDate("created");
|
415
|
if (!rs.wasNull()) {
|
416
|
result.setCreated(new DateTime(d.getTime()));
|
417
|
}
|
418
|
String s = rs.getString("uuid");
|
419
|
if (!rs.wasNull()) {
|
420
|
result.setUuid(UUID.fromString(rs.getString("uuid")));
|
421
|
}
|
422
|
s = rs.getString("crudeventtype");
|
423
|
if (!rs.wasNull()) {
|
424
|
result.setCrudEventType(CRUDEventType.valueOf(s));
|
425
|
}
|
426
|
result.setValidatedEntityClass(rs.getString("validatedentityclass"));
|
427
|
result.setValidatedEntityId(rs.getInt("validatedentityid"));
|
428
|
s = rs.getString("validatedentityuuid");
|
429
|
if (!rs.wasNull()) {
|
430
|
result.setValidatedEntityUuid(UUID.fromString(s));
|
431
|
}
|
432
|
result.setUserFriendlyDescription(rs.getString("userfriendlydescription"));
|
433
|
result.setUserFriendlyTypeName(rs.getString("userfriendlytypename"));
|
434
|
}
|
435
|
rs.close();
|
436
|
return result;
|
437
|
} finally {
|
438
|
JdbcDaoUtils.close(stmt);
|
439
|
}
|
440
|
}
|
441
|
|
442
|
private static int getValidationResultId(Connection conn, String validatedEntityClass, int validatedEntityId)
|
443
|
throws SQLException {
|
444
|
String sql = "SELECT id FROM entityvalidation WHERE validatedentityclass = ? AND validatedentityid = ?";
|
445
|
PreparedStatement stmt = null;
|
446
|
int result = -1;
|
447
|
try {
|
448
|
stmt = conn.prepareStatement(sql);
|
449
|
stmt.setString(1, validatedEntityClass);
|
450
|
stmt.setInt(2, validatedEntityId);
|
451
|
ResultSet rs = stmt.executeQuery();
|
452
|
if (rs.next()) {
|
453
|
result = rs.getInt(1);
|
454
|
}
|
455
|
rs.close();
|
456
|
} finally {
|
457
|
JdbcDaoUtils.close(stmt);
|
458
|
}
|
459
|
return result;
|
460
|
}
|
461
|
|
462
|
private static Set<EntityConstraintViolation> getErrorRecords(Connection conn, int entityValidationId)
|
463
|
throws SQLException {
|
464
|
return getErrorRecordsForValidationGroup(conn, entityValidationId, null);
|
465
|
}
|
466
|
|
467
|
private static Set<EntityConstraintViolation> getErrorRecordsForValidationGroup(Connection conn,
|
468
|
int entityValidationId, Class<?>[] validationGroups) throws SQLException {
|
469
|
StringBuilder sql = new StringBuilder("SELECT * FROM entityconstraintviolation WHERE entityvalidation_id=?");
|
470
|
if (validationGroups != null && validationGroups.length != 0) {
|
471
|
sql.append(" AND (");
|
472
|
for (int i = 0; i < validationGroups.length; ++i) {
|
473
|
if (i != 0) {
|
474
|
sql.append(" OR ");
|
475
|
}
|
476
|
sql.append("validationgroup = ?");
|
477
|
}
|
478
|
sql.append(")");
|
479
|
}
|
480
|
PreparedStatement stmt = null;
|
481
|
Set<EntityConstraintViolation> errors = new HashSet<EntityConstraintViolation>();
|
482
|
try {
|
483
|
stmt = conn.prepareStatement(sql.toString());
|
484
|
stmt.setInt(1, entityValidationId);
|
485
|
if (validationGroups != null && validationGroups.length != 0) {
|
486
|
for (int i = 0; i < validationGroups.length; ++i) {
|
487
|
stmt.setString(i + 2, validationGroups[i].getName());
|
488
|
}
|
489
|
}
|
490
|
ResultSet rs = stmt.executeQuery();
|
491
|
while (rs.next()) {
|
492
|
EntityConstraintViolation error = EntityConstraintViolation.newInstance();
|
493
|
error.setId(rs.getInt("id"));
|
494
|
error.setCreated(new DateTime(rs.getDate("created").getTime()));
|
495
|
error.setUuid(UUID.fromString(rs.getString("uuid")));
|
496
|
error.setInvalidValue(rs.getString("invalidvalue"));
|
497
|
error.setMessage(rs.getString("message"));
|
498
|
error.setPropertyPath(rs.getString("propertypath"));
|
499
|
error.setUserFriendlyFieldName(rs.getString("userfriendlyfieldname"));
|
500
|
error.setSeverity(Severity.forName(rs.getString("severity")));
|
501
|
error.setValidator(rs.getString("validator"));
|
502
|
error.setValidationGroup(rs.getString("validationgroup"));
|
503
|
errors.add(error);
|
504
|
}
|
505
|
rs.close();
|
506
|
} finally {
|
507
|
JdbcDaoUtils.close(stmt);
|
508
|
}
|
509
|
return errors;
|
510
|
}
|
511
|
|
512
|
private static void dontDeleteErrorsInOtherValidationGroups(EntityValidation previousValidation,
|
513
|
Class<?>[] validationGroups) {
|
514
|
Set<String> classNames = new HashSet<>(validationGroups.length);
|
515
|
for (Class<?> c : validationGroups) {
|
516
|
classNames.add(c.getName());
|
517
|
}
|
518
|
Iterator<EntityConstraintViolation> iterator = previousValidation.getEntityConstraintViolations().iterator();
|
519
|
while (iterator.hasNext()) {
|
520
|
if (!classNames.contains(iterator.next().getValidationGroup())) {
|
521
|
iterator.remove();
|
522
|
}
|
523
|
}
|
524
|
}
|
525
|
}
|