merge validation commits r23146, r23162, r23163 into trunk
authorAndreas Müller <a.mueller@bgbm.org>
Tue, 24 Mar 2015 10:57:12 +0000 (10:57 +0000)
committerAndreas Müller <a.mueller@bgbm.org>
Tue, 24 Mar 2015 10:57:12 +0000 (10:57 +0000)
15 files changed:
.gitattributes
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImpl.java
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.java
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/validation/CheckCase.java
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/validation/CheckCaseValidator.java
cdmlib-persistence/src/test/java/eu/etaxonomy/cdm/persistence/validation/Employee.java
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testReplaceError-result.xml [new file with mode: 0644]
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testSave.xml [new file with mode: 0644]
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testSaveAlreadyExistingError-result.xml [new file with mode: 0644]
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testAllErrorsSolved-result.xml [new file with mode: 0644]
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testOneOldOneNewError-result.xml [new file with mode: 0644]
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testReplaceError-result.xml [new file with mode: 0644]
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSameErrorOtherEntity-result.xml [new file with mode: 0644]
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSave.xml [new file with mode: 0644]
cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSaveAlreadyExistingError-result.xml [new file with mode: 0644]

index bdbe6951ac4fa2161da6a27c00e6102df4a8b4d0..974dc35731789b8745f41c52a4b779706b9c66fd 100644 (file)
@@ -1739,10 +1739,19 @@ cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.testSortindexForJavassist.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.testSortindexForJavassist2-result.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonNodeDaoHibernateImplTest.xml -text
+cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testReplaceError-result.xml -text
+cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testSave.xml -text
+cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testSaveAlreadyExistingError-result.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationDaoHibernateImplTest.testDeleteValidationResult-result.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationDaoHibernateImplTest.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/view/AuditEventDaoTest.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/dataset.dtd -text
+cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testAllErrorsSolved-result.xml -text
+cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testOneOldOneNewError-result.xml -text
+cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testReplaceError-result.xml -text
+cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSameErrorOtherEntity-result.xml -text
+cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSave.xml -text
+cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSaveAlreadyExistingError-result.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.test_DeleteValidationResult-result.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.xml -text
 cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/hibernate/CacheStrategyGeneratorTest.testOnSaveOrUpdateAgents-result.xml -text
index bab47b28de4ad9c388dae591901eb5c02a46f804..6d65f40a0bfaaf3ca6793d8cd8c15fc1d2bdec74 100644 (file)
@@ -16,6 +16,7 @@ import java.sql.ResultSet;
 import java.sql.SQLException;\r
 import java.sql.Types;\r
 import java.util.HashSet;\r
+import java.util.Iterator;\r
 import java.util.Set;\r
 import java.util.UUID;\r
 \r
@@ -44,398 +45,476 @@ import eu.etaxonomy.cdm.persistence.dao.validation.IEntityValidationCrud;
 @Repository\r
 public class EntityValidationCrudJdbcImpl implements IEntityValidationCrud {\r
 \r
-       public static final Logger logger = Logger.getLogger(EntityValidationCrudJdbcImpl.class);\r
-\r
-       private static final String SQL_INSERT_VALIDATION_RESULT = "INSERT INTO entityvalidation"\r
-                       + "(id, created, uuid,  crudeventtype, validatedentityclass, validatedentityid,"\r
-                       + "validatedentityuuid, userfriendlydescription, userfriendlytypename, validationcount,"\r
-                       + "updated, status, createdby_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)";\r
-\r
-       private static final int vr_id = 1;\r
-       private static final int vr_created = 2;\r
-       private static final int vr_uuid = 3;\r
-       private static final int vr_crudeventtype = 4;\r
-       private static final int vr_validatedentityclass = 5;\r
-       private static final int vr_validatedentityid = 6;\r
-       private static final int vr_validatedentityuuid = 7;\r
-       private static final int vr_userfriendlydescription = 8;\r
-       private static final int vr_userfriendlytypename = 9;\r
-       private static final int vr_validationcount = 10;\r
-       private static final int vr_updated = 11;\r
-       private static final int vr_status = 12;\r
-       private static final int vr_createdby_id = 13;\r
-\r
-       private static final String SQL_INSERT_CONSTRAINT_VIOLATION = "INSERT INTO entityconstraintviolation"\r
-                       + "(id, created, uuid,  invalidvalue, message, propertypath, userfriendlyfieldname, severity,"\r
-                       + "validator, validationgroup, createdby_id, entityvalidation_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";\r
-\r
-       private static final int cv_id = 1;\r
-       private static final int cv_created = 2;\r
-       private static final int cv_uuid = 3;\r
-       private static final int cv_invalidvalue = 4;\r
-       private static final int cv_message = 5;\r
-       private static final int cv_propertypath = 6;\r
-       private static final int cv_userfriendlyfieldname = 7;\r
-       private static final int cv_severity = 8;\r
-       private static final int cv_validator = 9;\r
-       private static final int cv_validationgroup = 10;\r
-       private static final int cv_createdby_id = 11;\r
-       private static final int cv_entityvalidation_id = 12;\r
-\r
-       @Autowired\r
-       private DataSource datasource;\r
-\r
-\r
-       public EntityValidationCrudJdbcImpl()\r
-       {\r
-\r
-       }\r
-\r
-\r
-       public EntityValidationCrudJdbcImpl(DataSource datasource)\r
-       {\r
-               this.datasource = datasource;\r
-       }\r
-\r
-\r
-       public void setDatasource(DataSource datasource)\r
-       {\r
-               this.datasource = datasource;\r
-       }\r
-\r
-\r
-       @Override\r
-       public <T extends ICdmBase> void saveEntityValidation(T validatedEntity, Set<ConstraintViolation<T>> errors, CRUDEventType crudEventType,\r
-                       Class<?>[] validationGroups)\r
-       {\r
-               Connection conn = null;\r
-               int entityValidationId = -1;\r
-               EntityValidationStatus status = EntityValidationStatus.OK;\r
-               try {\r
-                       conn = datasource.getConnection();\r
-                       JdbcDaoUtils.startTransaction(conn);\r
-                       String entityClass = validatedEntity.getClass().getName();\r
-                       int entityId = validatedEntity.getId();\r
-                       EntityValidation previousResult = getEntityValidationRecord(conn, entityClass, entityId);\r
-                       if (previousResult == null) {\r
-                               /*\r
-                                * The entity has never been validated before. We should now create an\r
-                                * entityvalidation record whether or not the entity has errors, because\r
-                                * the entity HAS been validated so its validationcount is now 1.\r
-                                */\r
-                               entityValidationId = saveValidationResultRecord(conn, validatedEntity, crudEventType);\r
-                               if (errors.size() != 0) {\r
-                                       saveErrorRecords(conn, entityValidationId, validatedEntity, errors);\r
-                               }\r
-                       }\r
-                       else {\r
-                               entityValidationId = previousResult.getId();\r
-                               deletedErrorRecords(conn, entityValidationId, validationGroups);\r
-                               if (errors.size() != 0) {\r
-                                       updateValidationResultRecord(conn, previousResult.getId(), crudEventType);\r
-                                       saveErrorRecords(conn, previousResult.getId(), validatedEntity, errors);\r
-                               }\r
-                       }\r
-                       conn.commit();\r
-               }\r
-               catch (Throwable t) {\r
-                       logger.error("Error while saving validation result:", t);\r
-                       status = EntityValidationStatus.ERROR;\r
-                       JdbcDaoUtils.rollback(conn);\r
-               }\r
-               setStatus(conn, entityValidationId, status);\r
-               JdbcDaoUtils.close(conn);\r
-       }\r
-\r
-\r
-       @Override\r
-       public void deleteEntityValidation(String validatedEntityClass, int validatedEntityId)\r
-       {\r
-               Connection conn = null;\r
-               try {\r
-                       conn = datasource.getConnection();\r
-                       JdbcDaoUtils.startTransaction(conn);\r
-                       int validationResultId = getValidationResultId(conn, validatedEntityClass, validatedEntityId);\r
-                       if (validationResultId == -1) {\r
-                               return;\r
-                       }\r
-                       deleteValidationResultRecord(conn, validationResultId);\r
-                       deletedErrorRecords(conn, validationResultId, null);\r
-                       conn.commit();\r
-               }\r
-               catch (Throwable t) {\r
-                       JdbcDaoUtils.rollback(conn);\r
-               }\r
-               JdbcDaoUtils.close(conn);\r
-       }\r
-\r
-\r
-       private static void deletedErrorRecords(Connection conn, int validationResultId, Class<?>[] validationGroups) throws SQLException\r
-       {\r
-               StringBuilder sql = new StringBuilder(127);\r
-               sql.append("DELETE FROM entityconstraintviolation WHERE entityvalidation_id = ?");\r
-               if (validationGroups != null && validationGroups.length != 0) {\r
-                       sql.append(" AND (");\r
-                       for (int i = 0; i < validationGroups.length; ++i) {\r
-                               if (i != 0) {\r
-                                       sql.append(" OR ");\r
-                               }\r
-                               sql.append("validationgroup = ?");\r
-                       }\r
-                       sql.append(")");\r
-               }\r
-               PreparedStatement stmt = null;\r
-               try {\r
-                       stmt = conn.prepareStatement(sql.toString());\r
-                       stmt.setInt(1, validationResultId);\r
-                       if (validationGroups != null && validationGroups.length != 0) {\r
-                               for (int i = 0; i < validationGroups.length; ++i) {\r
-                                       stmt.setString(i + 2, validationGroups[i].getName());\r
-                               }\r
-                       }\r
-                       stmt.executeUpdate();\r
-               }\r
-               finally {\r
-                       JdbcDaoUtils.close(stmt);\r
-               }\r
-       }\r
-\r
-\r
-       private static <T extends ICdmBase> int saveValidationResultRecord(Connection conn, T entity, CRUDEventType crudEventType) throws SQLException\r
-       {\r
-               PreparedStatement stmt = null;\r
-               int entityValidationId;\r
-               try {\r
-                       stmt = conn.prepareStatement(SQL_INSERT_VALIDATION_RESULT);\r
-                       entityValidationId = 10 + JdbcDaoUtils.fetchInt(conn, "SELECT MAX(id) FROM entityvalidation");\r
-                       EntityValidation validationResult = EntityValidation.newInstance(entity, crudEventType);\r
-                       stmt.setInt(vr_id, entityValidationId);\r
-                       stmt.setDate(vr_created, new Date(validationResult.getCreated().getMillis()));\r
-                       stmt.setString(vr_uuid, validationResult.getUuid().toString());\r
-                       stmt.setString(vr_crudeventtype, validationResult.getCrudEventType().toString());\r
-                       stmt.setString(vr_validatedentityclass, validationResult.getValidatedEntityClass());\r
-                       stmt.setInt(vr_validatedentityid, validationResult.getValidatedEntityId());\r
-                       stmt.setString(vr_validatedentityuuid, validationResult.getValidatedEntityUuid().toString());\r
-                       stmt.setString(vr_userfriendlydescription, validationResult.getUserFriendlyDescription());\r
-                       stmt.setString(vr_userfriendlytypename, validationResult.getUserFriendlyTypeName());\r
-                       stmt.setInt(vr_validationcount, 1);\r
-                       stmt.setDate(vr_updated, new Date(validationResult.getCreated().getMillis()));\r
-                       stmt.setString(vr_status, EntityValidationStatus.IN_PROGRESS.toString());\r
-                       if (validationResult.getCreatedBy() != null) {\r
-                               stmt.setInt(vr_createdby_id, validationResult.getCreatedBy().getId());\r
-                       }\r
-                       else {\r
-                               stmt.setNull(vr_createdby_id, Types.INTEGER);\r
-                       }\r
-                       stmt.executeUpdate();\r
-               }\r
-               finally {\r
-                       JdbcDaoUtils.close(stmt);\r
-               }\r
-               return entityValidationId;\r
-       }\r
-\r
-\r
-       private static void updateValidationResultRecord(Connection conn, int validationResultId, CRUDEventType crudEventType) throws SQLException\r
-       {\r
-               String sql = "UPDATE entityvalidation SET crudeventtype=?, validationcount = validationcount + 1, "\r
-                               + "updated = ?, status = ? WHERE id=?";\r
-               PreparedStatement stmt = null;\r
-               try {\r
-                       stmt = conn.prepareStatement(sql);\r
-                       stmt.setString(1, crudEventType.toString());\r
-                       stmt.setDate(2, new Date(new java.util.Date().getTime()));\r
-                       stmt.setString(3, EntityValidationStatus.IN_PROGRESS.toString());\r
-                       stmt.setInt(4, validationResultId);\r
-                       stmt.executeUpdate();\r
-               }\r
-               finally {\r
-                       JdbcDaoUtils.close(stmt);\r
-               }\r
-       }\r
-\r
-\r
-       private static void deleteValidationResultRecord(Connection conn, int validationResultId) throws SQLException\r
-       {\r
-               String sql = "DELETE FROM entityvalidation WHERE id = ?";\r
-               PreparedStatement stmt = conn.prepareStatement(sql);\r
-               stmt.setInt(1, validationResultId);\r
-               stmt.executeUpdate();\r
-       }\r
-\r
-\r
-       private static <T extends ICdmBase> void saveErrorRecords(Connection conn, int validationResultId, T entity, Set<ConstraintViolation<T>> errors)\r
-                       throws SQLException\r
-       {\r
-               PreparedStatement stmt = null;\r
-               try {\r
-                       stmt = conn.prepareStatement(SQL_INSERT_CONSTRAINT_VIOLATION);\r
-                       for (ConstraintViolation<T> error : errors) {\r
-                               EntityConstraintViolation ecv = EntityConstraintViolation.newInstance(entity, error);\r
-                               int maxId = JdbcDaoUtils.fetchInt(conn, "SELECT MAX(id) FROM entityconstraintviolation");\r
-                               stmt.setInt(cv_id, maxId + 1);\r
-                               stmt.setDate(cv_created, new Date(ecv.getCreated().getMillis()));\r
-                               stmt.setString(cv_uuid, ecv.getUuid().toString());\r
-                               stmt.setString(cv_invalidvalue, ecv.getInvalidValue());\r
-                               stmt.setString(cv_message, ecv.getMessage());\r
-                               stmt.setString(cv_propertypath, ecv.getPropertyPath());\r
-                               stmt.setString(cv_userfriendlyfieldname, ecv.getUserFriendlyFieldName());\r
-                               stmt.setString(cv_severity, ecv.getSeverity().toString());\r
-                               stmt.setString(cv_validator, ecv.getValidator());\r
-                               stmt.setString(cv_validationgroup, ecv.getValidationGroup());\r
-                               if (ecv.getCreatedBy() != null) {\r
-                                       stmt.setInt(cv_createdby_id, ecv.getCreatedBy().getId());\r
-                               }\r
-                               else {\r
-                                       stmt.setNull(cv_createdby_id, Types.INTEGER);\r
-                               }\r
-                               stmt.setInt(cv_entityvalidation_id, validationResultId);\r
-                               stmt.executeUpdate();\r
-                       }\r
-               }\r
-               finally {\r
-                       JdbcDaoUtils.close(stmt);\r
-               }\r
-       }\r
-\r
-\r
-       // Called by unit test\r
-       EntityValidation getValidationResult(String validatedEntityClass, int validatedEntityId)\r
-       {\r
-               Connection conn = null;\r
-               try {\r
-                       conn = datasource.getConnection();\r
-                       JdbcDaoUtils.startTransaction(conn);\r
-                       EntityValidation result = getEntityValidationRecord(conn, validatedEntityClass, validatedEntityId);\r
-                       if (result != null) {\r
-                               result.setEntityConstraintViolations(getErrorRecords(conn, result.getId()));\r
-                       }\r
-                       conn.commit();\r
-                       return result;\r
-               }\r
-               catch (Throwable t) {\r
-                       logger.error("Error while retrieving validation result", t);\r
-                       JdbcDaoUtils.rollback(conn);\r
-                       return null;\r
-               }\r
-       }\r
-\r
-\r
-       private static void setStatus(Connection conn, int entityValidationId, EntityValidationStatus status)\r
-       {\r
-               if (conn == null) {\r
-                       // Something has gone awfully wrong, but that's being dealt with on a higher level\r
-                       return;\r
-               }\r
-               if (entityValidationId <= 0) {\r
-                       // Something went wrong before we could insert a record into the entityvalidation\r
-                       // table or retrieve one using entityclass/entityid\r
-                       return;\r
-               }\r
-               String sql = "UPDATE entityvalidation SET status = ? WHERE id = ?";\r
-               PreparedStatement stmt = null;\r
-               try {\r
-                       JdbcDaoUtils.startTransaction(conn);\r
-                       stmt = conn.prepareStatement(sql);\r
-                       stmt.setString(1, status.toString());\r
-                       stmt.setInt(2, entityValidationId);\r
-                       stmt.executeUpdate();\r
-                       conn.commit();\r
-               }\r
-               catch (Throwable t) {\r
-                       logger.error("Failed to set validation status", t);\r
-               }\r
-               finally {\r
-                       JdbcDaoUtils.close(stmt);\r
-               }\r
-       }\r
-\r
-\r
-       private static <T extends ICdmBase> EntityValidation getEntityValidationRecord(Connection conn, String validatedEntityClass, int validatedEntityId)\r
-                       throws SQLException\r
-       {\r
-               String sql = "SELECT * FROM entityvalidation WHERE validatedentityclass=? AND validatedentityid=?";\r
-               EntityValidation result = null;\r
-               PreparedStatement stmt = null;\r
-               try {\r
-                       stmt = conn.prepareStatement(sql);\r
-                       stmt.setString(1, validatedEntityClass);\r
-                       stmt.setInt(2, validatedEntityId);\r
-                       ResultSet rs = stmt.executeQuery();\r
-                       if (rs.next()) {\r
-                               result = EntityValidation.newInstance();\r
-                               result.setId(rs.getInt("id"));\r
-                               result.setCreated(new DateTime(rs.getDate("created").getTime()));\r
-                               result.setUuid(UUID.fromString(rs.getString("uuid")));\r
-                               String s = rs.getString("crudeventtype");\r
-                               if (!rs.wasNull()) {\r
-                                       result.setCrudEventType(CRUDEventType.valueOf(s));\r
-                               }\r
-                               result.setValidatedEntityClass(rs.getString("validatedentityclass"));\r
-                               result.setValidatedEntityId(rs.getInt("validatedentityid"));\r
-                               result.setValidatedEntityUuid(UUID.fromString(rs.getString("validatedentityuuid")));\r
-                               result.setUserFriendlyDescription(rs.getString("userfriendlydescription"));\r
-                               result.setUserFriendlyTypeName(rs.getString("userfriendlytypename"));\r
-                       }\r
-                       rs.close();\r
-                       return result;\r
-               }\r
-               finally {\r
-                       JdbcDaoUtils.close(stmt);\r
-               }\r
-       }\r
-\r
-\r
-       private static int getValidationResultId(Connection conn, String validatedEntityClass, int validatedEntityId) throws SQLException\r
-       {\r
-               String sql = "SELECT id FROM entityvalidation WHERE validatedentityclass = ? AND validatedentityid = ?";\r
-               PreparedStatement stmt = null;\r
-               int result = -1;\r
-               try {\r
-                       stmt = conn.prepareStatement(sql);\r
-                       stmt.setString(1, validatedEntityClass);\r
-                       stmt.setInt(2, validatedEntityId);\r
-                       ResultSet rs = stmt.executeQuery();\r
-                       if (rs.next()) {\r
-                               result = rs.getInt(1);\r
-                       }\r
-                       rs.close();\r
-               }\r
-               finally {\r
-                       JdbcDaoUtils.close(stmt);\r
-               }\r
-               return result;\r
-       }\r
-\r
-\r
-       private static Set<EntityConstraintViolation> getErrorRecords(Connection conn, int validationResultId) throws SQLException\r
-       {\r
-               String sql = "SELECT * FROM entityconstraintviolation WHERE entityvalidation_id=?";\r
-               PreparedStatement stmt = null;\r
-               Set<EntityConstraintViolation> errors = new HashSet<EntityConstraintViolation>();\r
-               try {\r
-                       stmt = conn.prepareStatement(sql);\r
-                       stmt.setInt(1, validationResultId);\r
-                       ResultSet rs = stmt.executeQuery();\r
-                       while (rs.next()) {\r
-                               EntityConstraintViolation error = EntityConstraintViolation.newInstance();\r
-                               error.setId(rs.getInt("id"));\r
-                               error.setCreated(new DateTime(rs.getDate("created").getTime()));\r
-                               error.setUuid(UUID.fromString(rs.getString("uuid")));\r
-                               error.setInvalidValue(rs.getString("invalidvalue"));\r
-                               error.setMessage(rs.getString("message"));\r
-                               error.setPropertyPath(rs.getString("propertypath"));\r
-                               error.setUserFriendlyFieldName(rs.getString("userfriendlyfieldname"));\r
-                               error.setSeverity(Severity.forName(rs.getString("severity")));\r
-                               error.setValidator(rs.getString("validator"));\r
-                               error.setValidationGroup(rs.getString("validationgroup"));\r
-                               errors.add(error);\r
-                       }\r
-                       rs.close();\r
-               }\r
-               finally {\r
-                       JdbcDaoUtils.close(stmt);\r
-               }\r
-               return errors;\r
-       }\r
+    public static final Logger logger = Logger.getLogger(EntityValidationCrudJdbcImpl.class);\r
+\r
+    private static final String SQL_INSERT_VALIDATION_RESULT = "INSERT INTO entityvalidation"\r
+            + "(id, created, uuid,  crudeventtype, validatedentityclass, validatedentityid,"\r
+            + "validatedentityuuid, userfriendlydescription, userfriendlytypename, validationcount,"\r
+            + "updated, status, createdby_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)";\r
+\r
+    private static final int vr_id = 1;\r
+    private static final int vr_created = 2;\r
+    private static final int vr_uuid = 3;\r
+    private static final int vr_crudeventtype = 4;\r
+    private static final int vr_validatedentityclass = 5;\r
+    private static final int vr_validatedentityid = 6;\r
+    private static final int vr_validatedentityuuid = 7;\r
+    private static final int vr_userfriendlydescription = 8;\r
+    private static final int vr_userfriendlytypename = 9;\r
+    private static final int vr_validationcount = 10;\r
+    private static final int vr_updated = 11;\r
+    private static final int vr_status = 12;\r
+    private static final int vr_createdby_id = 13;\r
+\r
+    private static final String SQL_INSERT_CONSTRAINT_VIOLATION = "INSERT INTO entityconstraintviolation"\r
+            + "(id, created, uuid,  invalidvalue, message, propertypath, userfriendlyfieldname, severity,"\r
+            + "validator, validationgroup, createdby_id, entityvalidation_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";\r
+\r
+    private static final int cv_id = 1;\r
+    private static final int cv_created = 2;\r
+    private static final int cv_uuid = 3;\r
+    private static final int cv_invalidvalue = 4;\r
+    private static final int cv_message = 5;\r
+    private static final int cv_propertypath = 6;\r
+    private static final int cv_userfriendlyfieldname = 7;\r
+    private static final int cv_severity = 8;\r
+    private static final int cv_validator = 9;\r
+    private static final int cv_validationgroup = 10;\r
+    private static final int cv_createdby_id = 11;\r
+    private static final int cv_entityvalidation_id = 12;\r
+\r
+    @Autowired\r
+    private DataSource datasource;\r
+\r
+    public EntityValidationCrudJdbcImpl() {\r
+\r
+    }\r
+\r
+    public EntityValidationCrudJdbcImpl(DataSource datasource) {\r
+        this.datasource = datasource;\r
+    }\r
+\r
+    public void setDatasource(DataSource datasource) {\r
+        this.datasource = datasource;\r
+    }\r
+\r
+    @Override\r
+    public <T extends ICdmBase> void saveEntityValidation(T validatedEntity, Set<ConstraintViolation<T>> errors,\r
+            CRUDEventType crudEventType, Class<?>[] validationGroups) {\r
+        saveEntityValidation(createEntityValidation(validatedEntity, errors, crudEventType), validationGroups);\r
+    }\r
+\r
+    // This is the method that's tested by the unit tests\r
+    // rather than the interface method above, because it\r
+    // is almost impossible to create a mock instance of\r
+    // ConstraintViolation<T>\r
+    void saveEntityValidation(EntityValidation newValidation, Class<?>[] validationGroups) {\r
+        Connection conn = null;\r
+        EntityValidation tmp = null;\r
+        try {\r
+            conn = datasource.getConnection();\r
+            JdbcDaoUtils.startTransaction(conn);\r
+            String entityClass = newValidation.getValidatedEntityClass();\r
+            int entityId = newValidation.getValidatedEntityId();\r
+            EntityValidation oldValidation = getEntityValidation(conn, entityClass, entityId);\r
+            if (oldValidation == null) {\r
+                tmp = newValidation;\r
+                /*\r
+                 * The entity has never been validated before. We should now\r
+                 * create an entityvalidation record whether or not the entity\r
+                 * has errors, because the entity HAS been validated so its\r
+                 * validationcount is now 1.\r
+                 */\r
+                saveEntityValidationRecord(conn, newValidation);\r
+                Set<EntityConstraintViolation> errors = newValidation.getEntityConstraintViolations();\r
+                if (errors != null && errors.size() != 0) {\r
+                    saveErrorRecords(conn, newValidation);\r
+                }\r
+\r
+            } else {\r
+                tmp = oldValidation;\r
+                // Increase validation counter\r
+                increaseValidationCounter(conn, oldValidation);\r
+\r
+                // Delete obsolete errors, that is, errors from the previous\r
+                // validation that have disappeared from the new validation\r
+                // even though they belong to the same validation group\r
+                dontDeleteErrorsInOtherValidationGroups(oldValidation, validationGroups);\r
+                // Now all errors have been removed from the previous validation\r
+                // that don't belong to the validation group(s) applied by the\r
+                // current validation. Set them apart because we need them\r
+                HashSet<EntityConstraintViolation> oldErrors = new HashSet<EntityConstraintViolation>(\r
+                        oldValidation.getEntityConstraintViolations());\r
+                oldValidation.getEntityConstraintViolations().removeAll(newValidation.getEntityConstraintViolations());\r
+                // Now we're left with previous errors that have disappeared\r
+                // from the current validation (they have become obsolete)\r
+                deleteObsoleteErrors(conn, oldValidation);\r
+\r
+                // From the new errors delete all that are identical to\r
+                // errors from a previous validation (identical as per the\r
+                // equals() method of EntityConstraintViolation). These\r
+                // errors will not replace the old ones in order to limit\r
+                // the number of INSERTs.\r
+                newValidation.getEntityConstraintViolations().removeAll(oldErrors);\r
+                saveErrorRecords(conn, newValidation);\r
+            }\r
+            conn.commit();\r
+            setStatus(conn, tmp, EntityValidationStatus.OK);\r
+        } catch (Throwable t) {\r
+            logger.error("Error while saving validation result:", t);\r
+            setStatus(conn, tmp, EntityValidationStatus.ERROR);\r
+            JdbcDaoUtils.rollback(conn);\r
+        } finally {\r
+            JdbcDaoUtils.close(conn);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void deleteEntityValidation(String validatedEntityClass, int validatedEntityId) {\r
+        Connection conn = null;\r
+        try {\r
+            conn = datasource.getConnection();\r
+            JdbcDaoUtils.startTransaction(conn);\r
+            int validationResultId = getValidationResultId(conn, validatedEntityClass, validatedEntityId);\r
+            if (validationResultId == -1) {\r
+                return;\r
+            }\r
+            deleteValidationResultRecord(conn, validationResultId);\r
+            deletedErrorRecords(conn, validationResultId, null);\r
+            conn.commit();\r
+        } catch (Throwable t) {\r
+            JdbcDaoUtils.rollback(conn);\r
+        }\r
+        JdbcDaoUtils.close(conn);\r
+    }\r
+\r
+    private static <T extends ICdmBase> EntityValidation createEntityValidation(T validatedEntity,\r
+            Set<ConstraintViolation<T>> errors, CRUDEventType crudEventType) {\r
+        EntityValidation entityValidation = EntityValidation.newInstance(validatedEntity, crudEventType);\r
+        Set<EntityConstraintViolation> errorEntities = new HashSet<EntityConstraintViolation>(errors.size());\r
+        for (ConstraintViolation<T> error : errors) {\r
+            EntityConstraintViolation errorEntity = EntityConstraintViolation.newInstance(validatedEntity, error);\r
+            errorEntities.add(errorEntity);\r
+        }\r
+        entityValidation.setEntityConstraintViolations(errorEntities);\r
+        return entityValidation;\r
+    }\r
+\r
+    private static void deletedErrorRecords(Connection conn, int validationResultId, Class<?>[] validationGroups)\r
+            throws SQLException {\r
+        StringBuilder sql = new StringBuilder(127);\r
+        sql.append("DELETE FROM entityconstraintviolation WHERE entityvalidation_id = ?");\r
+        if (validationGroups != null && validationGroups.length != 0) {\r
+            sql.append(" AND (");\r
+            for (int i = 0; i < validationGroups.length; ++i) {\r
+                if (i != 0) {\r
+                    sql.append(" OR ");\r
+                }\r
+                sql.append("validationgroup = ?");\r
+            }\r
+            sql.append(")");\r
+        }\r
+        PreparedStatement stmt = null;\r
+        try {\r
+            stmt = conn.prepareStatement(sql.toString());\r
+            stmt.setInt(1, validationResultId);\r
+            if (validationGroups != null && validationGroups.length != 0) {\r
+                for (int i = 0; i < validationGroups.length; ++i) {\r
+                    stmt.setString(i + 2, validationGroups[i].getName());\r
+                }\r
+            }\r
+            stmt.executeUpdate();\r
+        } finally {\r
+            JdbcDaoUtils.close(stmt);\r
+        }\r
+    }\r
+\r
+    private static void deleteObsoleteErrors(Connection conn, EntityValidation previousValidation) throws SQLException {\r
+        Set<EntityConstraintViolation> obsoleteErrors = previousValidation.getEntityConstraintViolations();\r
+        if (obsoleteErrors == null || obsoleteErrors.size() == 0) {\r
+            return;\r
+        }\r
+        String sql = "DELETE FROM entityconstraintviolation WHERE id = ?";\r
+        PreparedStatement stmt = null;\r
+        try {\r
+            stmt = conn.prepareStatement(sql.toString());\r
+            for (EntityConstraintViolation error : obsoleteErrors) {\r
+                stmt.setInt(1, error.getId());\r
+                stmt.executeUpdate();\r
+            }\r
+        } finally {\r
+            JdbcDaoUtils.close(stmt);\r
+        }\r
+    }\r
+\r
+    // Save EntityValidation entity to database. As a side effect\r
+    // the database id assigned to the entity will be set on the\r
+    // EntityValidation instance\r
+    private static void saveEntityValidationRecord(Connection conn, EntityValidation newValidation) throws SQLException {\r
+        PreparedStatement stmt = null;\r
+        try {\r
+            stmt = conn.prepareStatement(SQL_INSERT_VALIDATION_RESULT);\r
+            if (newValidation.getId() <= 0) {\r
+                int id = 10 + JdbcDaoUtils.fetchInt(conn, "SELECT MAX(id) FROM entityvalidation");\r
+                newValidation.setId(id);\r
+            }\r
+            stmt.setInt(vr_id, newValidation.getId());\r
+            stmt.setDate(vr_created, new Date(newValidation.getCreated().getMillis()));\r
+            stmt.setString(vr_uuid, newValidation.getUuid().toString());\r
+            stmt.setString(vr_crudeventtype, newValidation.getCrudEventType().toString());\r
+            stmt.setString(vr_validatedentityclass, newValidation.getValidatedEntityClass());\r
+            stmt.setInt(vr_validatedentityid, newValidation.getValidatedEntityId());\r
+            stmt.setString(vr_validatedentityuuid, newValidation.getValidatedEntityUuid().toString());\r
+            stmt.setString(vr_userfriendlydescription, newValidation.getUserFriendlyDescription());\r
+            stmt.setString(vr_userfriendlytypename, newValidation.getUserFriendlyTypeName());\r
+            stmt.setInt(vr_validationcount, 1);\r
+            stmt.setDate(vr_updated, new Date(newValidation.getCreated().getMillis()));\r
+            stmt.setString(vr_status, EntityValidationStatus.IN_PROGRESS.toString());\r
+            if (newValidation.getCreatedBy() != null) {\r
+                stmt.setInt(vr_createdby_id, newValidation.getCreatedBy().getId());\r
+            } else {\r
+                stmt.setNull(vr_createdby_id, Types.INTEGER);\r
+            }\r
+            stmt.executeUpdate();\r
+        } finally {\r
+            JdbcDaoUtils.close(stmt);\r
+        }\r
+    }\r
+\r
+    private static void increaseValidationCounter(Connection conn, EntityValidation entityValidation)\r
+            throws SQLException {\r
+        String sql = "UPDATE entityvalidation SET crudeventtype=?, validationcount = validationcount + 1, "\r
+                + "updated = ?, status = ? WHERE id=?";\r
+        PreparedStatement stmt = null;\r
+        try {\r
+            stmt = conn.prepareStatement(sql);\r
+            if (entityValidation.getCrudEventType() == null) {\r
+                stmt.setString(1, null);\r
+            } else {\r
+                stmt.setString(1, entityValidation.getCrudEventType().toString());\r
+            }\r
+            stmt.setDate(2, new Date(new java.util.Date().getTime()));\r
+            stmt.setString(3, EntityValidationStatus.IN_PROGRESS.toString());\r
+            stmt.setInt(4, entityValidation.getId());\r
+            stmt.executeUpdate();\r
+        } finally {\r
+            JdbcDaoUtils.close(stmt);\r
+        }\r
+    }\r
+\r
+    private static <T extends ICdmBase> void saveErrorRecords(Connection conn, EntityValidation entityValidation)\r
+            throws SQLException {\r
+        Set<EntityConstraintViolation> errors = entityValidation.getEntityConstraintViolations();\r
+        if (errors == null || errors.size() == 0) {\r
+            return;\r
+        }\r
+        PreparedStatement stmt = null;\r
+        try {\r
+            stmt = conn.prepareStatement(SQL_INSERT_CONSTRAINT_VIOLATION);\r
+            for (EntityConstraintViolation error : errors) {\r
+                if (error.getId() <= 0) {\r
+                    int id = 10 + JdbcDaoUtils.fetchInt(conn, "SELECT MAX(id) FROM entityconstraintviolation");\r
+                    error.setId(id);\r
+                }\r
+                stmt.setInt(cv_id, error.getId());\r
+                stmt.setDate(cv_created, new Date(error.getCreated().getMillis()));\r
+                stmt.setString(cv_uuid, error.getUuid().toString());\r
+                stmt.setString(cv_invalidvalue, error.getInvalidValue());\r
+                stmt.setString(cv_message, error.getMessage());\r
+                stmt.setString(cv_propertypath, error.getPropertyPath());\r
+                stmt.setString(cv_userfriendlyfieldname, error.getUserFriendlyFieldName());\r
+                stmt.setString(cv_severity, error.getSeverity().toString());\r
+                stmt.setString(cv_validator, error.getValidator());\r
+                stmt.setString(cv_validationgroup, error.getValidationGroup());\r
+                if (error.getCreatedBy() != null) {\r
+                    stmt.setInt(cv_createdby_id, error.getCreatedBy().getId());\r
+                } else {\r
+                    stmt.setNull(cv_createdby_id, Types.INTEGER);\r
+                }\r
+                stmt.setInt(cv_entityvalidation_id, entityValidation.getId());\r
+                stmt.executeUpdate();\r
+            }\r
+        } finally {\r
+            JdbcDaoUtils.close(stmt);\r
+        }\r
+    }\r
+\r
+    // Called by unit test\r
+    EntityValidation getEntityValidation(String validatedEntityClass, int validatedEntityId) {\r
+        Connection conn = null;\r
+        try {\r
+            conn = datasource.getConnection();\r
+            JdbcDaoUtils.startTransaction(conn);\r
+            EntityValidation result = getEntityValidation(conn, validatedEntityClass, validatedEntityId);\r
+            conn.commit();\r
+            return result;\r
+        } catch (Throwable t) {\r
+            logger.error("Error while retrieving validation result", t);\r
+            JdbcDaoUtils.rollback(conn);\r
+            return null;\r
+        }\r
+    }\r
+\r
+    private static EntityValidation getEntityValidation(Connection conn, String validatedEntityClass,\r
+            int validatedEntityId) throws SQLException {\r
+        EntityValidation entityValidation = getEntityValidationRecord(conn, validatedEntityClass, validatedEntityId);\r
+        if (entityValidation != null) {\r
+            entityValidation.setEntityConstraintViolations(getErrorRecords(conn, entityValidation.getId()));\r
+        }\r
+        return entityValidation;\r
+    }\r
+\r
+    private static void deleteValidationResultRecord(Connection conn, int validationResultId) throws SQLException {\r
+        String sql = "DELETE FROM entityvalidation WHERE id = ?";\r
+        PreparedStatement stmt = conn.prepareStatement(sql);\r
+        stmt.setInt(1, validationResultId);\r
+        stmt.executeUpdate();\r
+    }\r
+\r
+    private static void setStatus(Connection conn, EntityValidation entityValidation, EntityValidationStatus status) {\r
+        if (conn == null || entityValidation == null || entityValidation.getId() <= 0) {\r
+            logger.warn("Failed to save entity validation status to database");\r
+            return;\r
+        }\r
+        String sql = "UPDATE entityvalidation SET status = ? WHERE id = ?";\r
+        PreparedStatement stmt = null;\r
+        try {\r
+            JdbcDaoUtils.startTransaction(conn);\r
+            stmt = conn.prepareStatement(sql);\r
+            stmt.setString(1, status.toString());\r
+            stmt.setInt(2, entityValidation.getId());\r
+            stmt.executeUpdate();\r
+            conn.commit();\r
+        } catch (Throwable t) {\r
+            logger.error("Failed to set validation status", t);\r
+        } finally {\r
+            JdbcDaoUtils.close(stmt);\r
+        }\r
+    }\r
+\r
+    private static <T extends ICdmBase> EntityValidation getEntityValidationRecord(Connection conn,\r
+            String validatedEntityClass, int validatedEntityId) throws SQLException {\r
+        String sql = "SELECT * FROM entityvalidation WHERE validatedentityclass=? AND validatedentityid=?";\r
+        EntityValidation result = null;\r
+        PreparedStatement stmt = null;\r
+        try {\r
+            stmt = conn.prepareStatement(sql);\r
+            stmt.setString(1, validatedEntityClass);\r
+            stmt.setInt(2, validatedEntityId);\r
+            ResultSet rs = stmt.executeQuery();\r
+            if (rs.next()) {\r
+                result = EntityValidation.newInstance();\r
+                result.setId(rs.getInt("id"));\r
+                Date d = rs.getDate("created");\r
+                if (!rs.wasNull()) {\r
+                    result.setCreated(new DateTime(d.getTime()));\r
+                }\r
+                String s = rs.getString("uuid");\r
+                if (!rs.wasNull()) {\r
+                    result.setUuid(UUID.fromString(rs.getString("uuid")));\r
+                }\r
+                s = rs.getString("crudeventtype");\r
+                if (!rs.wasNull()) {\r
+                    result.setCrudEventType(CRUDEventType.valueOf(s));\r
+                }\r
+                result.setValidatedEntityClass(rs.getString("validatedentityclass"));\r
+                result.setValidatedEntityId(rs.getInt("validatedentityid"));\r
+                s = rs.getString("validatedentityuuid");\r
+                if (!rs.wasNull()) {\r
+                    result.setValidatedEntityUuid(UUID.fromString(s));\r
+                }\r
+                result.setUserFriendlyDescription(rs.getString("userfriendlydescription"));\r
+                result.setUserFriendlyTypeName(rs.getString("userfriendlytypename"));\r
+            }\r
+            rs.close();\r
+            return result;\r
+        } finally {\r
+            JdbcDaoUtils.close(stmt);\r
+        }\r
+    }\r
+\r
+    private static int getValidationResultId(Connection conn, String validatedEntityClass, int validatedEntityId)\r
+            throws SQLException {\r
+        String sql = "SELECT id FROM entityvalidation WHERE validatedentityclass = ? AND validatedentityid = ?";\r
+        PreparedStatement stmt = null;\r
+        int result = -1;\r
+        try {\r
+            stmt = conn.prepareStatement(sql);\r
+            stmt.setString(1, validatedEntityClass);\r
+            stmt.setInt(2, validatedEntityId);\r
+            ResultSet rs = stmt.executeQuery();\r
+            if (rs.next()) {\r
+                result = rs.getInt(1);\r
+            }\r
+            rs.close();\r
+        } finally {\r
+            JdbcDaoUtils.close(stmt);\r
+        }\r
+        return result;\r
+    }\r
+\r
+    private static Set<EntityConstraintViolation> getErrorRecords(Connection conn, int entityValidationId)\r
+            throws SQLException {\r
+        return getErrorRecordsForValidationGroup(conn, entityValidationId, null);\r
+    }\r
+\r
+    private static Set<EntityConstraintViolation> getErrorRecordsForValidationGroup(Connection conn,\r
+            int entityValidationId, Class<?>[] validationGroups) throws SQLException {\r
+        StringBuilder sql = new StringBuilder("SELECT * FROM entityconstraintviolation WHERE entityvalidation_id=?");\r
+        if (validationGroups != null && validationGroups.length != 0) {\r
+            sql.append(" AND (");\r
+            for (int i = 0; i < validationGroups.length; ++i) {\r
+                if (i != 0) {\r
+                    sql.append(" OR ");\r
+                }\r
+                sql.append("validationgroup = ?");\r
+            }\r
+            sql.append(")");\r
+        }\r
+        PreparedStatement stmt = null;\r
+        Set<EntityConstraintViolation> errors = new HashSet<EntityConstraintViolation>();\r
+        try {\r
+            stmt = conn.prepareStatement(sql.toString());\r
+            stmt.setInt(1, entityValidationId);\r
+            if (validationGroups != null && validationGroups.length != 0) {\r
+                for (int i = 0; i < validationGroups.length; ++i) {\r
+                    stmt.setString(i + 2, validationGroups[i].getName());\r
+                }\r
+            }\r
+            ResultSet rs = stmt.executeQuery();\r
+            while (rs.next()) {\r
+                EntityConstraintViolation error = EntityConstraintViolation.newInstance();\r
+                error.setId(rs.getInt("id"));\r
+                error.setCreated(new DateTime(rs.getDate("created").getTime()));\r
+                error.setUuid(UUID.fromString(rs.getString("uuid")));\r
+                error.setInvalidValue(rs.getString("invalidvalue"));\r
+                error.setMessage(rs.getString("message"));\r
+                error.setPropertyPath(rs.getString("propertypath"));\r
+                error.setUserFriendlyFieldName(rs.getString("userfriendlyfieldname"));\r
+                error.setSeverity(Severity.forName(rs.getString("severity")));\r
+                error.setValidator(rs.getString("validator"));\r
+                error.setValidationGroup(rs.getString("validationgroup"));\r
+                errors.add(error);\r
+            }\r
+            rs.close();\r
+        } finally {\r
+            JdbcDaoUtils.close(stmt);\r
+        }\r
+        return errors;\r
+    }\r
+\r
+    private static void dontDeleteErrorsInOtherValidationGroups(EntityValidation previousValidation,\r
+            Class<?>[] validationGroups) {\r
+        Set<String> classNames = new HashSet<String>(validationGroups.length);\r
+        for (Class<?> c : validationGroups) {\r
+            classNames.add(c.getName());\r
+        }\r
+        Iterator<EntityConstraintViolation> iterator = previousValidation.getEntityConstraintViolations().iterator();\r
+        while (iterator.hasNext()) {\r
+            if (!classNames.contains(iterator.next().getValidationGroup())) {\r
+                iterator.remove();\r
+            }\r
+        }\r
+    }\r
+\r
 }\r
index 5ad9cda2093ee41c8881e12a42325b17f6dc31ff..c35cbc560abb66968d21b5b7743cc0a7c8912412 100644 (file)
@@ -18,6 +18,7 @@ import java.io.FileNotFoundException;
 import java.util.ArrayList;\r
 import java.util.Collections;\r
 import java.util.Comparator;\r
+import java.util.HashSet;\r
 import java.util.List;\r
 import java.util.Set;\r
 import java.util.UUID;\r
@@ -28,6 +29,7 @@ import javax.validation.ValidatorFactory;
 \r
 import org.hibernate.validator.HibernateValidator;\r
 import org.hibernate.validator.HibernateValidatorConfiguration;\r
+import org.joda.time.DateTime;\r
 import org.junit.Before;\r
 import org.junit.Test;\r
 import org.unitils.dbunit.annotation.DataSet;\r
@@ -36,6 +38,7 @@ import org.unitils.dbunit.annotation.ExpectedDataSet;
 import eu.etaxonomy.cdm.model.validation.CRUDEventType;\r
 import eu.etaxonomy.cdm.model.validation.EntityConstraintViolation;\r
 import eu.etaxonomy.cdm.model.validation.EntityValidation;\r
+import eu.etaxonomy.cdm.model.validation.Severity;\r
 import eu.etaxonomy.cdm.persistence.validation.Company;\r
 import eu.etaxonomy.cdm.persistence.validation.Employee;\r
 import eu.etaxonomy.cdm.test.integration.CdmIntegrationTest;\r
@@ -46,7 +49,6 @@ import eu.etaxonomy.cdm.validation.Level2;
  * @date 20 jan. 2015\r
  *\r
  */\r
-@DataSet\r
 public class EntityValidationCrudJdbcImplTest extends CdmIntegrationTest {\r
 \r
     private static final String MEDIA = "eu.etaxonomy.cdm.model.media.Media";\r
@@ -60,7 +62,6 @@ public class EntityValidationCrudJdbcImplTest extends CdmIntegrationTest {
     public void setUp() throws Exception {\r
     }\r
 \r
-\r
     /**\r
      * Test method for\r
      * {@link eu.etaxonomy.cdm.persistence.dao.jdbc.validation.EntityValidationCrudJdbcImpl#EntityValidationCrudJdbcImpl()}\r
@@ -89,6 +90,7 @@ public class EntityValidationCrudJdbcImplTest extends CdmIntegrationTest {
      * .\r
      */\r
     @Test\r
+    @DataSet\r
     public void test_SaveValidationResult_Set_T_CRUDEventType() {\r
         HibernateValidatorConfiguration config = Validation.byProvider(HibernateValidator.class).configure();\r
         ValidatorFactory factory = config.buildValidatorFactory();\r
@@ -115,7 +117,7 @@ public class EntityValidationCrudJdbcImplTest extends CdmIntegrationTest {
         EntityValidationCrudJdbcImpl dao = new EntityValidationCrudJdbcImpl(dataSource);\r
         dao.saveEntityValidation(emp, errors, CRUDEventType.NONE, null);\r
 \r
-        EntityValidation result = dao.getValidationResult(emp.getClass().getName(), emp.getId());\r
+        EntityValidation result = dao.getEntityValidation(emp.getClass().getName(), emp.getId());\r
         assertNotNull(result);\r
         assertEquals("Unexpected UUID", result.getValidatedEntityUuid(), uuid);\r
         assertEquals("Unexpected number of constraint violations", 2, result.getEntityConstraintViolations().size());\r
@@ -132,52 +134,284 @@ public class EntityValidationCrudJdbcImplTest extends CdmIntegrationTest {
 \r
     }\r
 \r
+    @Test\r
+    @DataSet("EntityValidationCrudJdbcImplTest.testSave.xml")\r
+    @ExpectedDataSet("EntityValidationCrudJdbcImplTest.testSaveAlreadyExistingError-result.xml")\r
+    // Test proving that if an exactly identical\r
+    // EntityConstraintViolation (as per equals() method)\r
+    // is already in database, the only thing that happens\r
+    // is an increment of the validation counter.\r
+    public void testSaveAlreadyExistingError() {\r
+\r
+        // All same as in @DataSet:\r
+\r
+        DateTime created = new DateTime(2014, 1, 1, 0, 0);\r
+\r
+        Employee emp = new Employee();\r
+        emp.setId(100);\r
+        emp.setUuid(UUID.fromString("f8de74c6-aa56-4de3-931e-87b61da0218c"));\r
+        // Other properties not relevant for this test\r
+\r
+        EntityValidation entityValidation = EntityValidation.newInstance();\r
+        entityValidation.setValidatedEntity(emp);\r
+        entityValidation.setId(1);\r
+        entityValidation.setUuid(UUID.fromString("dae5b090-30e8-45bc-9460-2eb2028d3c18"));\r
+        entityValidation.setCreated(created);\r
+        entityValidation.setCrudEventType(CRUDEventType.INSERT);\r
+        entityValidation.setValidationCount(5);\r
+\r
+        EntityConstraintViolation error = EntityConstraintViolation.newInstance();\r
+\r
+        // Actually not same as in @DataSet to force\r
+        // EntityConstraintViolation.equals() method to take\r
+        // other properties into account (e.g. propertyPath,\r
+        // invalidValue, etc.)\r
+        error.setId(Integer.MIN_VALUE);\r
+\r
+        error.setCreated(created);\r
+        error.setUuid(UUID.fromString("358da71f-b646-4b79-b00e-dcb68b6425ba"));\r
+        error.setSeverity(Severity.ERROR);\r
+        error.setPropertyPath("firstName");\r
+        error.setInvalidValue("Foo");\r
+        error.setMessage("Garbage In Garbage Out");\r
+        error.setValidationGroup("eu.etaxonomy.cdm.validation.Level2");\r
+        error.setValidator("eu.etaxonomy.cdm.persistence.validation.GarbageValidator");\r
+        Set<EntityConstraintViolation> errors = new HashSet<EntityConstraintViolation>(1);\r
+        errors.add(error);\r
+\r
+        entityValidation.addEntityConstraintViolation(error);\r
+\r
+        EntityValidationCrudJdbcImpl dao = new EntityValidationCrudJdbcImpl(dataSource);\r
+        dao.saveEntityValidation(entityValidation, new Class[] { Level2.class });\r
+    }\r
+\r
+    @Test\r
+    @DataSet("EntityValidationCrudJdbcImplTest.testSave.xml")\r
+    @ExpectedDataSet("EntityValidationCrudJdbcImplTest.testReplaceError-result.xml")\r
+    // Test proving that if an entity has been validated,\r
+    // yielding 1 error (as in @DataSet), and a subsequent\r
+    // validation also yields 1 error, but a different one,\r
+    // then validation count is increased, the old error is\r
+    // removed and the new error is inserted.\r
+    public void testReplaceError() {\r
+\r
+        // All identical to @DataSet:\r
+\r
+        DateTime created = new DateTime(2014, 1, 1, 0, 0);\r
+\r
+        Employee emp = new Employee();\r
+        emp.setId(100);\r
+        emp.setUuid(UUID.fromString("f8de74c6-aa56-4de3-931e-87b61da0218c"));\r
+\r
+        EntityValidation entityValidation = EntityValidation.newInstance();\r
+        entityValidation.setValidatedEntity(emp);\r
+        entityValidation.setId(1);\r
+        entityValidation.setUuid(UUID.fromString("dae5b090-30e8-45bc-9460-2eb2028d3c18"));\r
+        entityValidation.setCreated(created);\r
+        entityValidation.setCrudEventType(CRUDEventType.INSERT);\r
+        entityValidation.setValidationCount(5);\r
+\r
+        EntityConstraintViolation error = EntityConstraintViolation.newInstance();\r
+        error.setId(38);\r
+        error.setCreated(created);\r
+        error.setUuid(UUID.fromString("358da71f-b646-4b79-b00e-dcb68b6425ba"));\r
+        error.setSeverity(Severity.ERROR);\r
+        error.setPropertyPath("firstName");\r
+\r
+        // Except for:\r
+        error.setInvalidValue("Bar");\r
+\r
+        error.setMessage("Garbage In Garbage Out");\r
+        error.setValidationGroup("eu.etaxonomy.cdm.validation.Level2");\r
+        error.setValidator("eu.etaxonomy.cdm.persistence.validation.GarbageValidator");\r
+        Set<EntityConstraintViolation> errors = new HashSet<EntityConstraintViolation>(1);\r
+        errors.add(error);\r
+\r
+        entityValidation.addEntityConstraintViolation(error);\r
+\r
+        EntityValidationCrudJdbcImpl dao = new EntityValidationCrudJdbcImpl(dataSource);\r
+        dao.saveEntityValidation(entityValidation, new Class[] { Level2.class });\r
+    }\r
+\r
+    @Test\r
+    @DataSet("EntityValidationCrudJdbcImplTest.testSave.xml")\r
+    @ExpectedDataSet("EntityValidationCrudJdbcImplTest.testSameErrorOtherEntity-result.xml")\r
+    // Test proving that if an entity has been validated,\r
+    // yielding 1 error (as in @DataSet), and _another_\r
+    // entity is now validated yielding an equals() error,\r
+    // things behave as expected (2 entityvalidations, each\r
+    // having 1 entityconstraintviolation)\r
+    public void testSameErrorOtherEntity() {\r
+\r
+        DateTime created = new DateTime(2014, 1, 1, 0, 0);\r
+\r
+        // Not in @DataSet\r
+        Employee emp = new Employee();\r
+        emp.setId(200);\r
+        emp.setUuid(UUID.fromString("f8de74c6-aa56-4de3-931e-87b61da0218d"));\r
+\r
+        EntityValidation entityValidation = EntityValidation.newInstance();\r
+        entityValidation.setValidatedEntity(emp);\r
+        entityValidation.setId(2);\r
+        entityValidation.setUuid(UUID.fromString("dae5b090-30e8-45bc-9460-2eb2028d3c19"));\r
+        entityValidation.setCreated(created);\r
+        entityValidation.setCrudEventType(CRUDEventType.INSERT);\r
+        entityValidation.setValidationCount(1);\r
+\r
+        // equals() error in @DataSet\r
+        EntityConstraintViolation error = EntityConstraintViolation.newInstance();\r
+        error.setId(2);\r
+        error.setCreated(created);\r
+        error.setUuid(UUID.fromString("358da71f-b646-4b79-b00e-dcb68b6425bb"));\r
+        error.setSeverity(Severity.ERROR);\r
+        error.setPropertyPath("firstName");\r
+        error.setInvalidValue("Foo");\r
+\r
+        error.setMessage("Garbage In Garbage Out");\r
+        error.setValidationGroup("eu.etaxonomy.cdm.validation.Level2");\r
+        error.setValidator("eu.etaxonomy.cdm.persistence.validation.GarbageValidator");\r
+        Set<EntityConstraintViolation> errors = new HashSet<EntityConstraintViolation>(1);\r
+        errors.add(error);\r
+\r
+        entityValidation.addEntityConstraintViolation(error);\r
+\r
+        EntityValidationCrudJdbcImpl dao = new EntityValidationCrudJdbcImpl(dataSource);\r
+        dao.saveEntityValidation(entityValidation, new Class[] { Level2.class });\r
+    }\r
+    @Test\r
+    @DataSet("EntityValidationCrudJdbcImplTest.testSave.xml")\r
+    @ExpectedDataSet("EntityValidationCrudJdbcImplTest.testOneOldOneNewError-result.xml")\r
+    // Test proving that if an entity has been validated,\r
+    // yielding 1 error (as in @DataSet), and _another_\r
+    // entity is now validated yielding an equals() error,\r
+    // things behave as expected (2 entityvalidations, each\r
+    // having 1 entityconstraintviolation)\r
+    public void testOneOldOneNewError() {\r
+\r
+        DateTime created = new DateTime(2014, 1, 1, 0, 0);\r
+\r
+        // Same entity as in @DataSet\r
+        Employee emp = new Employee();\r
+        emp.setId(100);\r
+        emp.setUuid(UUID.fromString("f8de74c6-aa56-4de3-931e-87b61da0218c"));\r
+        // Other properties not relevant for this test\r
+\r
+        EntityValidation entityValidation = EntityValidation.newInstance();\r
+        entityValidation.setValidatedEntity(emp);\r
+        entityValidation.setId(1);\r
+        entityValidation.setUuid(UUID.fromString("dae5b090-30e8-45bc-9460-2eb2028d3c18"));\r
+        entityValidation.setCreated(created);\r
+        entityValidation.setCrudEventType(CRUDEventType.INSERT);\r
+\r
+\r
+        // Old error (in @DataSet)\r
+        EntityConstraintViolation error = EntityConstraintViolation.newInstance();\r
+        error.setId(Integer.MIN_VALUE);\r
+        error.setCreated(created);\r
+        error.setUuid(UUID.fromString("358da71f-b646-4b79-b00e-dcb68b6425ba"));\r
+        error.setSeverity(Severity.ERROR);\r
+        error.setPropertyPath("firstName");\r
+        error.setInvalidValue("Foo");\r
+        error.setMessage("Garbage In Garbage Out");\r
+        error.setValidationGroup("eu.etaxonomy.cdm.validation.Level2");\r
+        error.setValidator("eu.etaxonomy.cdm.persistence.validation.GarbageValidator");\r
+        entityValidation.addEntityConstraintViolation(error);\r
+\r
+        // New error (not in @DataSet)\r
+        error = EntityConstraintViolation.newInstance();\r
+        // Don't leave ID generation to chance; we want it to be same as in\r
+        // @ExpectedDataSet\r
+        error.setId(2);\r
+        error.setCreated(created);\r
+        error.setUuid(UUID.fromString("358da71f-b646-4b79-b00e-dcb68b6425bb"));\r
+        error.setSeverity(Severity.ERROR);\r
+        error.setPropertyPath("lastName");\r
+        error.setInvalidValue("Bar");\r
+        error.setMessage("Garbage In Garbage Out");\r
+        error.setValidationGroup("eu.etaxonomy.cdm.validation.Level2");\r
+        error.setValidator("eu.etaxonomy.cdm.persistence.validation.LastNameValidator");\r
+        entityValidation.addEntityConstraintViolation(error);\r
+\r
+        EntityValidationCrudJdbcImpl dao = new EntityValidationCrudJdbcImpl(dataSource);\r
+        dao.saveEntityValidation(entityValidation, new Class[] { Level2.class });\r
+    }\r
+\r
+\r
+\r
+    @Test\r
+    @DataSet("EntityValidationCrudJdbcImplTest.testSave.xml")\r
+    @ExpectedDataSet("EntityValidationCrudJdbcImplTest.testAllErrorsSolved-result.xml")\r
+    // Test proving that if an entity has been validated,\r
+    // yielding 1 error (as in @DataSet), and a subsequent\r
+    // validation yields 0 errors, all that remains is an\r
+    // EntityValidation record with its validation counter\r
+    // increased.\r
+    public void testAllErrorsSolved() {\r
+\r
+        DateTime created = new DateTime(2014, 1, 1, 0, 0);\r
+\r
+        Employee emp = new Employee();\r
+        emp.setId(100);\r
+        emp.setUuid(UUID.fromString("f8de74c6-aa56-4de3-931e-87b61da0218c"));\r
+\r
+        EntityValidation entityValidation = EntityValidation.newInstance();\r
+        entityValidation.setValidatedEntity(emp);\r
+        entityValidation.setId(1);\r
+        entityValidation.setUuid(UUID.fromString("dae5b090-30e8-45bc-9460-2eb2028d3c18"));\r
+        entityValidation.setCreated(created);\r
+        entityValidation.setCrudEventType(CRUDEventType.INSERT);\r
+        entityValidation.setValidationCount(5);\r
+\r
+        EntityValidationCrudJdbcImpl dao = new EntityValidationCrudJdbcImpl(dataSource);\r
+        dao.saveEntityValidation(entityValidation, new Class[] { Level2.class });\r
+    }\r
+\r
     /**\r
      * Test method for\r
      * {@link eu.etaxonomy.cdm.persistence.dao.jdbc.validation.EntityValidationCrudJdbcImpl#deleteEntityValidation (java.lang.String, int)}\r
      * .\r
      */\r
     @Test\r
+    @DataSet\r
     @ExpectedDataSet\r
     public void test_DeleteValidationResult() {\r
         EntityValidationCrudJdbcImpl dao = new EntityValidationCrudJdbcImpl(dataSource);\r
         dao.deleteEntityValidation(SYNONYM_RELATIONSHIP, 200);\r
-        EntityValidation result = dao.getValidationResult(SYNONYM_RELATIONSHIP, 200);\r
+        EntityValidation result = dao.getEntityValidation(SYNONYM_RELATIONSHIP, 200);\r
         assertTrue(result == null);\r
     }\r
 \r
     @Test\r
+    @DataSet\r
     public void testGetEntityValidation() {\r
         EntityValidationCrudJdbcImpl dao = new EntityValidationCrudJdbcImpl(dataSource);\r
         EntityValidation result;\r
 \r
-        result = dao.getValidationResult(MEDIA, 100);\r
+        result = dao.getEntityValidation(MEDIA, 100);\r
         assertNotNull(result);\r
         assertEquals("Unexpected entity id", 1, result.getId());\r
         assertEquals("Unexpected number of constraint violations", 1, result.getEntityConstraintViolations().size());\r
 \r
-        result = dao.getValidationResult(SYNONYM_RELATIONSHIP, 200);\r
+        result = dao.getEntityValidation(SYNONYM_RELATIONSHIP, 200);\r
         assertNotNull(result);\r
         assertEquals("Unexpected entity id", 2, result.getId());\r
         assertEquals("Unexpected number of constraint violations", 2, result.getEntityConstraintViolations().size());\r
 \r
-        result = dao.getValidationResult(GATHERING_EVENT, 300);\r
+        result = dao.getEntityValidation(GATHERING_EVENT, 300);\r
         assertNotNull(result);\r
         assertEquals("Unexpected entity id", 3, result.getId());\r
         assertEquals("Unexpected number of constraint violations", 3, result.getEntityConstraintViolations().size());\r
 \r
-        result = dao.getValidationResult(GATHERING_EVENT, 301);\r
+        result = dao.getEntityValidation(GATHERING_EVENT, 301);\r
         assertNotNull(result);\r
         assertEquals("Unexpected entity id", 4, result.getId());\r
         assertEquals("Unexpected number of constraint violations", 1, result.getEntityConstraintViolations().size());\r
 \r
         // Test we get a null back\r
-        result = dao.getValidationResult("Foo Bar", 100);\r
+        result = dao.getEntityValidation("Foo Bar", 100);\r
         assertNull(result);\r
     }\r
 \r
-\r
-\r
     /**\r
      * Test method for\r
      * {@link eu.etaxonomy.cdm.persistence.dao.jdbc.validation.EntityValidationCrudJdbcImpl#setDatasource (eu.etaxonomy.cdm.database.ICdmDataSource)}\r
index a100d0469be26f43e807e9018c4a1bb16fe212ca..868317d907088c66ac830ae7dbdd9611feca442b 100644 (file)
@@ -1,11 +1,11 @@
 /**\r
-* Copyright (C) 2009 EDIT\r
-* European Distributed Institute of Taxonomy\r
-* http://www.e-taxonomy.eu\r
-*\r
-* The contents of this file are subject to the Mozilla Public License Version 1.1\r
-* See LICENSE.TXT at the top of this package for the full license terms.\r
-*/\r
+ * Copyright (C) 2009 EDIT\r
+ * European Distributed Institute of Taxonomy\r
+ * http://www.e-taxonomy.eu\r
+ *\r
+ * The contents of this file are subject to the Mozilla Public License Version 1.1\r
+ * See LICENSE.TXT at the top of this package for the full license terms.\r
+ */\r
 package eu.etaxonomy.cdm.persistence.validation;\r
 \r
 import static java.lang.annotation.ElementType.ANNOTATION_TYPE;\r
@@ -20,19 +20,25 @@ import java.lang.annotation.Target;
 import javax.validation.Constraint;\r
 import javax.validation.Payload;\r
 \r
+/**\r
+ * A Mock class for testing entity validation tasks. DO NOT MODIFY UNLESS YOU\r
+ * ALSO MODIFY THE UNIT TESTS MAKING USE OF THIS CLASS!\r
+ *\r
+ * @author ayco_holleman\r
+ *\r
+ */\r
 @Target({ METHOD, FIELD, ANNOTATION_TYPE })\r
 @Retention(RUNTIME)\r
 @Constraint(validatedBy = CheckCaseValidator.class)\r
 @Documented\r
 public @interface CheckCase {\r
-       String message() default "Casing is wrong";\r
-\r
-\r
-       Class<?>[] groups() default {};\r
-\r
+    // Do not modify message. Unit tests depend on it\r
+    String message() default "Casing is wrong";\r
 \r
-       Class<? extends Payload>[] payload() default {};\r
+    Class<?>[] groups() default {};\r
 \r
+    // Do not modify severity. Unit tests depend on it\r
+    Class<? extends Payload>[] payload() default {};\r
 \r
-       CaseMode value();\r
+    CaseMode value();\r
 }\r
index 11e34381dd2117b148d956e255028fc7e3cff496..bd2396f94216a4239950d0f307dcc7c5dc1094cd 100644 (file)
@@ -11,21 +11,32 @@ package eu.etaxonomy.cdm.persistence.validation;
 import javax.validation.ConstraintValidator;\r
 import javax.validation.ConstraintValidatorContext;\r
 \r
+/**\r
+ * A Mock class for testing entity validation tasks. DO NOT MODIFY UNLESS YOU\r
+ * ALSO MODIFY THE UNIT TESTS MAKING USE OF THIS CLASS!\r
+ *\r
+ * @author ayco_holleman\r
+ *\r
+ */\r
 public class CheckCaseValidator implements ConstraintValidator<CheckCase, String> {\r
        private CaseMode caseMode;\r
 \r
 \r
-       public void initialize(CheckCase constraintAnnotation){\r
+       @Override\r
+    public void initialize(CheckCase constraintAnnotation){\r
                this.caseMode = constraintAnnotation.value();\r
        }\r
 \r
 \r
-       public boolean isValid(String object, ConstraintValidatorContext constraintContext){\r
-               if (object == null)\r
-                       return true;\r
-               if (caseMode == CaseMode.UPPER)\r
-                       return object.equals(object.toUpperCase());\r
-               else\r
-                       return object.equals(object.toLowerCase());\r
+       @Override\r
+    public boolean isValid(String object, ConstraintValidatorContext constraintContext){\r
+               if (object == null) {\r
+            return true;\r
+        }\r
+               if (caseMode == CaseMode.UPPER) {\r
+            return object.equals(object.toUpperCase());\r
+        } else {\r
+            return object.equals(object.toLowerCase());\r
+        }\r
        }\r
 }\r
index 76565828143f680171a11e9998a11c549f5a71c8..5a4232a8490dc8c4ecbd8fd06cf85e6d09766b6e 100644 (file)
@@ -1,11 +1,11 @@
 /**\r
-* Copyright (C) 2009 EDIT\r
-* European Distributed Institute of Taxonomy\r
-* http://www.e-taxonomy.eu\r
-*\r
-* The contents of this file are subject to the Mozilla Public License Version 1.1\r
-* See LICENSE.TXT at the top of this package for the full license terms.\r
-*/\r
+ * Copyright (C) 2009 EDIT\r
+ * European Distributed Institute of Taxonomy\r
+ * http://www.e-taxonomy.eu\r
+ *\r
+ * The contents of this file are subject to the Mozilla Public License Version 1.1\r
+ * See LICENSE.TXT at the top of this package for the full license terms.\r
+ */\r
 package eu.etaxonomy.cdm.persistence.validation;\r
 \r
 import java.util.List;\r
@@ -17,80 +17,77 @@ import eu.etaxonomy.cdm.validation.Level2;
 import eu.etaxonomy.cdm.validation.Level3;\r
 \r
 /**\r
- * A Mock class for testing entity validation tasks. DO NOT MODIFY UNLESS YOU ALSO MODIFY\r
- * THE UNIT TESTS MAKING USE OF THIS CLASS!\r
- * \r
+ * A Mock class for testing entity validation tasks. DO NOT MODIFY UNLESS YOU\r
+ * ALSO MODIFY THE UNIT TESTS MAKING USE OF THIS CLASS!\r
+ *\r
  * @author ayco_holleman\r
- * \r
+ *\r
  */\r
 @SuppressWarnings("serial")\r
 public class Employee extends CdmBase {\r
 \r
-       @CheckCase(value = CaseMode.UPPER, groups = { Level2.class })\r
-       private String firstName;\r
-       @CheckCase(value = CaseMode.UPPER, groups = { Level3.class })\r
-       private String lastName;\r
-       @Valid\r
-       private Company company;\r
-       @Valid\r
-       private List<Address> addresses;\r
-\r
-\r
-       public Employee(){\r
-       }\r
-\r
-\r
-       public String getFirstName(){\r
-               return firstName;\r
-       }\r
-\r
-\r
-       public void setFirstName(String firstName){\r
-               this.firstName = firstName;\r
-       }\r
-\r
-\r
-       public String getLastName(){\r
-               return lastName;\r
-       }\r
-       public void setLastName(String lastName){\r
-               this.lastName = lastName;\r
-       }\r
-\r
-\r
-       public Company getCompany(){\r
-               return company;\r
-       }\r
-       public void setCompany(Company company){\r
-               this.company = company;\r
-       }\r
-\r
-\r
-       public List<Address> getAddresses(){\r
-               return addresses;\r
-       }\r
-       public void setAddresses(List<Address> addresses){\r
-               this.addresses = addresses;\r
-       }\r
-\r
-\r
-       public boolean equals(Object obj){\r
-               if (this == obj) {\r
-                       return true;\r
-               }\r
-               if (obj == null) {\r
-                       return false;\r
-               }\r
-               Employee emp = (Employee) obj;\r
-               return firstName.equals(emp.firstName) && lastName.equals(emp.lastName);\r
-       }\r
-\r
-\r
-       public int hashCode(){\r
-               int hash = 17;\r
-               hash = (hash * 31) + firstName.hashCode();\r
-               hash = (hash * 31) + lastName.hashCode();\r
-               return hash;\r
-       }\r
+    @CheckCase(value = CaseMode.UPPER, groups = { Level2.class })\r
+    private String firstName;\r
+    @CheckCase(value = CaseMode.UPPER, groups = { Level3.class })\r
+    private String lastName;\r
+    @Valid\r
+    private Company company;\r
+    @Valid\r
+    private List<Address> addresses;\r
+\r
+    public Employee() {\r
+    }\r
+\r
+    public String getFirstName() {\r
+        return firstName;\r
+    }\r
+\r
+    public void setFirstName(String firstName) {\r
+        this.firstName = firstName;\r
+    }\r
+\r
+    public String getLastName() {\r
+        return lastName;\r
+    }\r
+\r
+    public void setLastName(String lastName) {\r
+        this.lastName = lastName;\r
+    }\r
+\r
+    public Company getCompany() {\r
+        return company;\r
+    }\r
+\r
+    public void setCompany(Company company) {\r
+        this.company = company;\r
+    }\r
+\r
+    public List<Address> getAddresses() {\r
+        return addresses;\r
+    }\r
+\r
+    public void setAddresses(List<Address> addresses) {\r
+        this.addresses = addresses;\r
+    }\r
+\r
+    @Override\r
+    public boolean equals(Object obj) {\r
+        if (this == obj) {\r
+            return true;\r
+        }\r
+        if (obj == null) {\r
+            return false;\r
+        }\r
+        Employee emp = (Employee) obj;\r
+        return firstName.equals(emp.firstName) && lastName.equals(emp.lastName);\r
+    }\r
+\r
+    @Override\r
+    public int hashCode() {\r
+        int hash = 17;\r
+        hash = (hash * 31) + (firstName == null ? 0 : firstName.hashCode());\r
+        hash = (hash * 31) + (lastName == null ? 0 : lastName.hashCode());\r
+        return hash;\r
+    }\r
 \r
 }\r
diff --git a/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testReplaceError-result.xml b/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testReplaceError-result.xml
new file mode 100644 (file)
index 0000000..ccbd807
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='UTF-8'?>\r
+<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xsi:noNamespaceSchemaLocation="../dataset.xsd">\r
+\r
+  <!-- ********************* -->\r
+  <!-- Validation results    -->\r
+  <!-- ********************* -->\r
+  <ENTITYVALIDATION ID="1" CREATED="2014-01-01 00:00:00.0"\r
+    UUID="dae5b090-30e8-45bc-9460-2eb2028d3c18" VALIDATEDENTITYID="100"\r
+    VALIDATEDENTITYUUID="f8de74c6-aa56-4de3-931e-87b61da0218c"\r
+    VALIDATEDENTITYCLASS="eu.etaxonomy.cdm.persistence.validation.Employee"\r
+    VALIDATIONCOUNT="6"\r
+   />\r
+\r
+  <!-- ********************* -->\r
+  <!-- Constraint violations -->\r
+  <!-- ********************* -->\r
+  <ENTITYCONSTRAINTVIOLATION ID="38"\r
+    CREATED="2014-01-01 00:00:00.0" UUID="358da71f-b646-4b79-b00e-dcb68b6425ba"\r
+    ENTITYVALIDATION_ID="1" PROPERTYPATH="firstName" INVALIDVALUE="Bar"\r
+    SEVERITY="Error" MESSAGE="Garbage In Garbage Out"\r
+    VALIDATIONGROUP="eu.etaxonomy.cdm.validation.Level2"\r
+    VALIDATOR="eu.etaxonomy.cdm.persistence.validation.GarbageValidator" />\r
+\r
+</dataset>
\ No newline at end of file
diff --git a/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testSave.xml b/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testSave.xml
new file mode 100644 (file)
index 0000000..659cf59
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='UTF-8'?>\r
+<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xsi:noNamespaceSchemaLocation="../dataset.xsd">\r
+\r
+  <!-- ********************* -->\r
+  <!-- Validation results    -->\r
+  <!-- ********************* -->\r
+  <ENTITYVALIDATION ID="1" CREATED="2014-01-01 00:00:00.0"\r
+    UUID="dae5b090-30e8-45bc-9460-2eb2028d3c18" VALIDATEDENTITYID="100"\r
+    VALIDATEDENTITYUUID="f8de74c6-aa56-4de3-931e-87b61da0218c"\r
+    VALIDATEDENTITYCLASS="eu.etaxonomy.cdm.persistence.validation.Employee"\r
+    VALIDATIONCOUNT="5"\r
+   />\r
+\r
+  <!-- ********************* -->\r
+  <!-- Constraint violations -->\r
+  <!-- ********************* -->\r
+  <ENTITYCONSTRAINTVIOLATION ID="1"\r
+    CREATED="2014-01-01 00:00:00.0" UUID="358da71f-b646-4b79-b00e-dcb68b6425ba"\r
+    ENTITYVALIDATION_ID="1" PROPERTYPATH="firstName" INVALIDVALUE="Foo"\r
+    SEVERITY="Error" MESSAGE="Garbage In Garbage Out"\r
+    VALIDATIONGROUP="eu.etaxonomy.cdm.validation.Level2"\r
+    VALIDATOR="eu.etaxonomy.cdm.persistence.validation.GarbageValidator" />\r
+\r
+</dataset>
\ No newline at end of file
diff --git a/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testSaveAlreadyExistingError-result.xml b/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/hibernate/validation/EntityValidationCrudJdbcImplTest.testSaveAlreadyExistingError-result.xml
new file mode 100644 (file)
index 0000000..95ba757
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='UTF-8'?>\r
+<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xsi:noNamespaceSchemaLocation="../dataset.xsd">\r
+\r
+  <!-- ********************* -->\r
+  <!-- Validation results    -->\r
+  <!-- ********************* -->\r
+  <ENTITYVALIDATION ID="1" CREATED="2014-01-01 00:00:00.0"\r
+    UUID="dae5b090-30e8-45bc-9460-2eb2028d3c18" VALIDATEDENTITYID="100"\r
+    VALIDATEDENTITYUUID="f8de74c6-aa56-4de3-931e-87b61da0218c"\r
+    VALIDATEDENTITYCLASS="eu.etaxonomy.cdm.persistence.validation.Employee"\r
+    VALIDATIONCOUNT="6"\r
+   />\r
+\r
+  <!-- ********************* -->\r
+  <!-- Constraint violations -->\r
+  <!-- ********************* -->\r
+  <ENTITYCONSTRAINTVIOLATION ID="1"\r
+    CREATED="2014-01-01 00:00:00.0" UUID="358da71f-b646-4b79-b00e-dcb68b6425ba"\r
+    ENTITYVALIDATION_ID="1" PROPERTYPATH="firstName" INVALIDVALUE="Foo"\r
+    SEVERITY="Error" MESSAGE="Garbage In Garbage Out"\r
+    VALIDATIONGROUP="eu.etaxonomy.cdm.validation.Level2"\r
+    VALIDATOR="eu.etaxonomy.cdm.persistence.validation.GarbageValidator" />\r
+\r
+</dataset>
\ No newline at end of file
diff --git a/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testAllErrorsSolved-result.xml b/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testAllErrorsSolved-result.xml
new file mode 100644 (file)
index 0000000..d06b66d
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version='1.0' encoding='UTF-8'?>\r
+<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xsi:noNamespaceSchemaLocation="../dataset.xsd">\r
+\r
+  <!-- ********************* -->\r
+  <!-- Validation results    -->\r
+  <!-- ********************* -->\r
+  <ENTITYVALIDATION ID="1" CREATED="2014-01-01 00:00:00.0"\r
+    UUID="dae5b090-30e8-45bc-9460-2eb2028d3c18" VALIDATEDENTITYID="100"\r
+    VALIDATEDENTITYUUID="f8de74c6-aa56-4de3-931e-87b61da0218c"\r
+    VALIDATEDENTITYCLASS="eu.etaxonomy.cdm.persistence.validation.Employee"\r
+    VALIDATIONCOUNT="6"\r
+   />\r
+\r
+</dataset>
\ No newline at end of file
diff --git a/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testOneOldOneNewError-result.xml b/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testOneOldOneNewError-result.xml
new file mode 100644 (file)
index 0000000..2653264
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version='1.0' encoding='UTF-8'?>\r
+<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xsi:noNamespaceSchemaLocation="../dataset.xsd">\r
+\r
+  <!-- ********************* -->\r
+  <!-- Validation results    -->\r
+  <!-- ********************* -->\r
+  <ENTITYVALIDATION ID="1" CREATED="2014-01-01 00:00:00.0"\r
+    UUID="dae5b090-30e8-45bc-9460-2eb2028d3c18" VALIDATEDENTITYID="100"\r
+    VALIDATEDENTITYUUID="f8de74c6-aa56-4de3-931e-87b61da0218c"\r
+    VALIDATEDENTITYCLASS="eu.etaxonomy.cdm.persistence.validation.Employee"\r
+    VALIDATIONCOUNT="6"\r
+   />\r
+\r
+  <!-- ********************* -->\r
+  <!-- Constraint violations -->\r
+  <!-- ********************* -->\r
+  <ENTITYCONSTRAINTVIOLATION ID="1"\r
+    CREATED="2014-01-01 00:00:00.0" UUID="358da71f-b646-4b79-b00e-dcb68b6425ba"\r
+    ENTITYVALIDATION_ID="1" PROPERTYPATH="firstName" INVALIDVALUE="Foo"\r
+    SEVERITY="Error" MESSAGE="Garbage In Garbage Out"\r
+    VALIDATIONGROUP="eu.etaxonomy.cdm.validation.Level2"\r
+    VALIDATOR="eu.etaxonomy.cdm.persistence.validation.GarbageValidator" />\r
+\r
+  <ENTITYCONSTRAINTVIOLATION ID="2"\r
+    CREATED="2014-01-01 00:00:00.0" UUID="358da71f-b646-4b79-b00e-dcb68b6425bb"\r
+    ENTITYVALIDATION_ID="1" PROPERTYPATH="lastName" INVALIDVALUE="Bar"\r
+    SEVERITY="Error" MESSAGE="Garbage In Garbage Out"\r
+    VALIDATIONGROUP="eu.etaxonomy.cdm.validation.Level2"\r
+    VALIDATOR="eu.etaxonomy.cdm.persistence.validation.LastNameValidator" />\r
+\r
+</dataset>
\ No newline at end of file
diff --git a/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testReplaceError-result.xml b/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testReplaceError-result.xml
new file mode 100644 (file)
index 0000000..ccbd807
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='UTF-8'?>\r
+<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xsi:noNamespaceSchemaLocation="../dataset.xsd">\r
+\r
+  <!-- ********************* -->\r
+  <!-- Validation results    -->\r
+  <!-- ********************* -->\r
+  <ENTITYVALIDATION ID="1" CREATED="2014-01-01 00:00:00.0"\r
+    UUID="dae5b090-30e8-45bc-9460-2eb2028d3c18" VALIDATEDENTITYID="100"\r
+    VALIDATEDENTITYUUID="f8de74c6-aa56-4de3-931e-87b61da0218c"\r
+    VALIDATEDENTITYCLASS="eu.etaxonomy.cdm.persistence.validation.Employee"\r
+    VALIDATIONCOUNT="6"\r
+   />\r
+\r
+  <!-- ********************* -->\r
+  <!-- Constraint violations -->\r
+  <!-- ********************* -->\r
+  <ENTITYCONSTRAINTVIOLATION ID="38"\r
+    CREATED="2014-01-01 00:00:00.0" UUID="358da71f-b646-4b79-b00e-dcb68b6425ba"\r
+    ENTITYVALIDATION_ID="1" PROPERTYPATH="firstName" INVALIDVALUE="Bar"\r
+    SEVERITY="Error" MESSAGE="Garbage In Garbage Out"\r
+    VALIDATIONGROUP="eu.etaxonomy.cdm.validation.Level2"\r
+    VALIDATOR="eu.etaxonomy.cdm.persistence.validation.GarbageValidator" />\r
+\r
+</dataset>
\ No newline at end of file
diff --git a/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSameErrorOtherEntity-result.xml b/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSameErrorOtherEntity-result.xml
new file mode 100644 (file)
index 0000000..0ae00ff
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version='1.0' encoding='UTF-8'?>\r
+<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xsi:noNamespaceSchemaLocation="../dataset.xsd">\r
+\r
+  <!-- ********************* -->\r
+  <!-- Validation results    -->\r
+  <!-- ********************* -->\r
+  <ENTITYVALIDATION ID="1" CREATED="2014-01-01 00:00:00.0"\r
+    UUID="dae5b090-30e8-45bc-9460-2eb2028d3c18" VALIDATEDENTITYID="100"\r
+    VALIDATEDENTITYUUID="f8de74c6-aa56-4de3-931e-87b61da0218c"\r
+    VALIDATEDENTITYCLASS="eu.etaxonomy.cdm.persistence.validation.Employee"\r
+    VALIDATIONCOUNT="5"\r
+   />\r
+   \r
+  <ENTITYVALIDATION ID="2" CREATED="2014-01-01 00:00:00.0"\r
+    UUID="dae5b090-30e8-45bc-9460-2eb2028d3c19" VALIDATEDENTITYID="200"\r
+    VALIDATEDENTITYUUID="f8de74c6-aa56-4de3-931e-87b61da0218d"\r
+    VALIDATEDENTITYCLASS="eu.etaxonomy.cdm.persistence.validation.Employee"\r
+    VALIDATIONCOUNT="1"\r
+   />\r
+\r
+  <!-- ********************* -->\r
+  <!-- Constraint violations -->\r
+  <!-- ********************* -->\r
+  <ENTITYCONSTRAINTVIOLATION ID="1"\r
+    CREATED="2014-01-01 00:00:00.0" UUID="358da71f-b646-4b79-b00e-dcb68b6425ba"\r
+    ENTITYVALIDATION_ID="1" PROPERTYPATH="firstName" INVALIDVALUE="Foo"\r
+    SEVERITY="Error" MESSAGE="Garbage In Garbage Out"\r
+    VALIDATIONGROUP="eu.etaxonomy.cdm.validation.Level2"\r
+    VALIDATOR="eu.etaxonomy.cdm.persistence.validation.GarbageValidator" />\r
+    \r
+  <ENTITYCONSTRAINTVIOLATION ID="2"\r
+    CREATED="2014-01-01 00:00:00.0" UUID="358da71f-b646-4b79-b00e-dcb68b6425bb"\r
+    ENTITYVALIDATION_ID="2" PROPERTYPATH="firstName" INVALIDVALUE="Foo"\r
+    SEVERITY="Error" MESSAGE="Garbage In Garbage Out"\r
+    VALIDATIONGROUP="eu.etaxonomy.cdm.validation.Level2"\r
+    VALIDATOR="eu.etaxonomy.cdm.persistence.validation.GarbageValidator" />\r
+\r
+</dataset>
\ No newline at end of file
diff --git a/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSave.xml b/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSave.xml
new file mode 100644 (file)
index 0000000..659cf59
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='UTF-8'?>\r
+<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xsi:noNamespaceSchemaLocation="../dataset.xsd">\r
+\r
+  <!-- ********************* -->\r
+  <!-- Validation results    -->\r
+  <!-- ********************* -->\r
+  <ENTITYVALIDATION ID="1" CREATED="2014-01-01 00:00:00.0"\r
+    UUID="dae5b090-30e8-45bc-9460-2eb2028d3c18" VALIDATEDENTITYID="100"\r
+    VALIDATEDENTITYUUID="f8de74c6-aa56-4de3-931e-87b61da0218c"\r
+    VALIDATEDENTITYCLASS="eu.etaxonomy.cdm.persistence.validation.Employee"\r
+    VALIDATIONCOUNT="5"\r
+   />\r
+\r
+  <!-- ********************* -->\r
+  <!-- Constraint violations -->\r
+  <!-- ********************* -->\r
+  <ENTITYCONSTRAINTVIOLATION ID="1"\r
+    CREATED="2014-01-01 00:00:00.0" UUID="358da71f-b646-4b79-b00e-dcb68b6425ba"\r
+    ENTITYVALIDATION_ID="1" PROPERTYPATH="firstName" INVALIDVALUE="Foo"\r
+    SEVERITY="Error" MESSAGE="Garbage In Garbage Out"\r
+    VALIDATIONGROUP="eu.etaxonomy.cdm.validation.Level2"\r
+    VALIDATOR="eu.etaxonomy.cdm.persistence.validation.GarbageValidator" />\r
+\r
+</dataset>
\ No newline at end of file
diff --git a/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSaveAlreadyExistingError-result.xml b/cdmlib-persistence/src/test/resources/eu/etaxonomy/cdm/persistence/dao/jdbc/validation/EntityValidationCrudJdbcImplTest.testSaveAlreadyExistingError-result.xml
new file mode 100644 (file)
index 0000000..95ba757
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version='1.0' encoding='UTF-8'?>\r
+<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xsi:noNamespaceSchemaLocation="../dataset.xsd">\r
+\r
+  <!-- ********************* -->\r
+  <!-- Validation results    -->\r
+  <!-- ********************* -->\r
+  <ENTITYVALIDATION ID="1" CREATED="2014-01-01 00:00:00.0"\r
+    UUID="dae5b090-30e8-45bc-9460-2eb2028d3c18" VALIDATEDENTITYID="100"\r
+    VALIDATEDENTITYUUID="f8de74c6-aa56-4de3-931e-87b61da0218c"\r
+    VALIDATEDENTITYCLASS="eu.etaxonomy.cdm.persistence.validation.Employee"\r
+    VALIDATIONCOUNT="6"\r
+   />\r
+\r
+  <!-- ********************* -->\r
+  <!-- Constraint violations -->\r
+  <!-- ********************* -->\r
+  <ENTITYCONSTRAINTVIOLATION ID="1"\r
+    CREATED="2014-01-01 00:00:00.0" UUID="358da71f-b646-4b79-b00e-dcb68b6425ba"\r
+    ENTITYVALIDATION_ID="1" PROPERTYPATH="firstName" INVALIDVALUE="Foo"\r
+    SEVERITY="Error" MESSAGE="Garbage In Garbage Out"\r
+    VALIDATIONGROUP="eu.etaxonomy.cdm.validation.Level2"\r
+    VALIDATOR="eu.etaxonomy.cdm.persistence.validation.GarbageValidator" />\r
+\r
+</dataset>
\ No newline at end of file