diff --git a/ccm-core/pom.xml b/ccm-core/pom.xml
index eb582216e..75d1c93d3 100644
--- a/ccm-core/pom.xml
+++ b/ccm-core/pom.xml
@@ -47,6 +47,10 @@
org.hibernate
hibernate-validator
+
+ org.hibernate
+ hibernate-validator-cdi
+
diff --git a/ccm-core/src/main/java/com/arsdigita/util/Assert.java b/ccm-core/src/main/java/com/arsdigita/util/Assert.java
index 648ab6b32..42fb09525 100644
--- a/ccm-core/src/main/java/com/arsdigita/util/Assert.java
+++ b/ccm-core/src/main/java/com/arsdigita/util/Assert.java
@@ -614,7 +614,8 @@ public class Assert {
* @param actualLabel Label for second (generally actual) value.
* @throws java.lang.IllegalStateException condition was false
*/
- public static final void assertEquals(Object expected, Object actual,
+ public static final void assertEquals(Object expected,
+ Object actual,
String expectedLabel,
String actualLabel) {
if (isEnabled()) {
diff --git a/ccm-core/src/main/java/com/arsdigita/util/StringUtils.java b/ccm-core/src/main/java/com/arsdigita/util/StringUtils.java
index db4354d5e..e887b5ed2 100644
--- a/ccm-core/src/main/java/com/arsdigita/util/StringUtils.java
+++ b/ccm-core/src/main/java/com/arsdigita/util/StringUtils.java
@@ -391,6 +391,7 @@ public class StringUtils {
m_hash = hash;
}
+ @Override
public void appendSubstitution(StringBuffer appendBuffer,
MatchResult match,
int substitutionCount,
@@ -401,7 +402,7 @@ public class StringUtils {
String link = match.group(2);
s_log.debug("Link: " + link);
- Integer i = new Integer(m_hash.size());
+ Integer i = m_hash.size();
s_log.debug("Key: " + i);
m_hash.put(i, link);
String dst = "@" + title + "(\u0002" + i.toString() + "\u0002)";
@@ -429,7 +430,7 @@ public class StringUtils {
String link = match.group(1);
s_log.debug("Link: " + link);
- Integer i = new Integer(m_hash.size());
+ Integer i = m_hash.size();
s_log.debug("Key: " + i);
m_hash.put(i, link);
String dst = "@\u0002" + i.toString() + "\u0002(\u0002" +
@@ -458,7 +459,7 @@ public class StringUtils {
String s = match.group(1);
s_log.debug("Key: " + s);
- Integer i = new Integer(s);
+ Integer i = Integer.valueOf(s);
appendBuffer.append((String)m_hash.get(i));
s_log.debug("Link: " + m_hash.get(i));
}
diff --git a/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java b/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java
index 382f4e685..b61e05236 100644
--- a/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java
+++ b/ccm-core/src/main/java/org/libreccm/core/AbstractEntityRepository.java
@@ -18,6 +18,8 @@
*/
package org.libreccm.core;
+import org.hibernate.validator.cdi.HibernateValidator;
+
import java.util.List;
import javax.inject.Inject;
@@ -26,6 +28,7 @@ import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
+import javax.validation.Validator;
/**
* A base class providing common method needed by every repository.
@@ -42,6 +45,10 @@ public abstract class AbstractEntityRepository {
*/
@Inject
private transient EntityManager entityManager;
+
+ @Inject
+ @HibernateValidator
+ private Validator validator;
/**
* Getter method for retrieving the injected {@link EntityManager}.
diff --git a/ccm-core/src/main/java/org/libreccm/core/Subject.java b/ccm-core/src/main/java/org/libreccm/core/Subject.java
index d9c8125d0..71936a996 100644
--- a/ccm-core/src/main/java/org/libreccm/core/Subject.java
+++ b/ccm-core/src/main/java/org/libreccm/core/Subject.java
@@ -34,6 +34,8 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@@ -49,6 +51,7 @@ import javax.xml.bind.annotation.XmlRootElement;
*/
@Entity
@Table(name = "subjects")
+@Inheritance(strategy = InheritanceType.JOINED)
@XmlRootElement(name = "subject", namespace = CORE_XML_NS)
public class Subject implements Serializable {
diff --git a/ccm-core/src/test/java/org/libreccm/core/CcmObjectRepositoryTest.java b/ccm-core/src/test/java/org/libreccm/core/CcmObjectRepositoryTest.java
index 148b25794..424aba5d3 100644
--- a/ccm-core/src/test/java/org/libreccm/core/CcmObjectRepositoryTest.java
+++ b/ccm-core/src/test/java/org/libreccm/core/CcmObjectRepositoryTest.java
@@ -46,7 +46,6 @@ import org.libreccm.tests.categories.IntegrationTest;
import java.io.File;
import java.util.List;
-import javax.ejb.EJBTransactionRolledbackException;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
diff --git a/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java b/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java
index 471685b90..c9a6a01c1 100644
--- a/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java
+++ b/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java
@@ -45,7 +45,11 @@ public class DatasetsTest extends DatasetsVerifier {
"/datasets/org/libreccm/core/CcmObjectRepositoryTest/data.json",
"/datasets/org/libreccm/core/CcmObjectRepositoryTest/after-delete.json",
"/datasets/org/libreccm/core/CcmObjectRepositoryTest/after-save-changed.json",
- "/datasets/org/libreccm/core/CcmObjectRepositoryTest/after-save-new.json"
+ "/datasets/org/libreccm/core/CcmObjectRepositoryTest/after-save-new.json",
+ "/datasets/org/libreccm/core/UserRepositoryTest/data.json",
+ "/datasets/org/libreccm/core/UserRepositoryTest/after-delete.json",
+ "/datasets/org/libreccm/core/UserRepositoryTest/after-save-changed.json",
+ "/datasets/org/libreccm/core/UserRepositoryTest/after-save-new.json"
});
}
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/after-delete.json b/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/after-delete.json
new file mode 100644
index 000000000..f2105ff0b
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/after-delete.json
@@ -0,0 +1,63 @@
+{
+ "subjects":
+ [
+ {
+ "subject_id": -10
+ },
+ {
+ "subject_id": -30
+ }
+ ],
+ "subject_email_addresses":
+ [
+ {
+ "subject_id": -10,
+ "email_address": "john.doe@example.com",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "subject_id": -30,
+ "email_address": "joe.public@example.com",
+ "bouncing": true,
+ "verified": false
+ }
+ ],
+ "ccm_users":
+ [
+ {
+ "banned": false,
+ "hash_algorithm": "MD5",
+ "family_name": "Doe",
+ "given_name": "John",
+ "middle_name": null,
+ "title_post": null,
+ "title_pre": null,
+ "password": "604622dc8a888eb093454ebd77ca1675",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "axg8ira8fa",
+ "screen_name": "jdoe",
+ "sso_login": null,
+ "subject_id": -10
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Public",
+ "given_name": "Joe",
+ "middle_name": null,
+ "title_post": null,
+ "title_pre": null,
+ "password": "e9db883a56149f7521a00713c4d7b0c967ae42cc3f0dfcf96ccd0180c498abf57209a90db9cb5df3a7d23d4111e87578e09ea610e9c1d95c4695710e28c5ab02",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "axg8ira8fa",
+ "screen_name": "joe",
+ "sso_login": null,
+ "subject_id": -30
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/after-save-changed.json b/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/after-save-changed.json
new file mode 100644
index 000000000..1a48c5dd4
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/after-save-changed.json
@@ -0,0 +1,95 @@
+{
+ "subjects":
+ [
+ {
+ "subject_id": -10
+ },
+ {
+ "subject_id": -20
+ },
+ {
+ "subject_id": -30
+ }
+ ],
+ "subject_email_addresses":
+ [
+ {
+ "subject_id": -10,
+ "email_address": "john.doe@example.com",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "subject_id": -20,
+ "email_address": "max.mustermann@example.org",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "subject_id": -20,
+ "email_address": "mm@example.com",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "subject_id": -30,
+ "email_address": "joe.public@example.com",
+ "bouncing": true,
+ "verified": false
+ }
+ ],
+ "ccm_users":
+ [
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Doe",
+ "given_name": "John",
+ "middle_name": null,
+ "title_post": null,
+ "title_pre": null,
+ "password": "19f69a0f8eab3e6124d1b40ca2ae1fc3ece311cf86dde4e9560521e881fb8f063817cf1da1234144825f40fc9b9acd1563cafcb35fb8533544a1b6c3615160e3",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "fafjiaddfja0a",
+ "screen_name": "jdoe",
+ "sso_login": null,
+ "subject_id": -10
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Mustermann",
+ "given_name": "Max",
+ "middle_name": null,
+ "title_post": null,
+ "title_pre": null,
+ "password": "3428dfa9bb199f3372eb73c5feb038aef5bcbbfd4fada24c44026a25c883a9f2af8b84410a3b2684430d359f78400ad92ff8c71634f2c9bf437f0cd56c5d90c3",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "fjiajhigafgapoa",
+ "screen_name": "mmuster",
+ "sso_login": null,
+ "subject_id": -20
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Public",
+ "given_name": "Joe",
+ "middle_name": null,
+ "title_post": null,
+ "title_pre": null,
+ "password": "e9db883a56149f7521a00713c4d7b0c967ae42cc3f0dfcf96ccd0180c498abf57209a90db9cb5df3a7d23d4111e87578e09ea610e9c1d95c4695710e28c5ab02",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "axg8ira8fa",
+ "screen_name": "joe",
+ "sso_login": null,
+ "subject_id": -30
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/after-save-new.json b/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/after-save-new.json
new file mode 100644
index 000000000..8749220ed
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/after-save-new.json
@@ -0,0 +1,121 @@
+{
+ "subjects":
+ [
+ {
+ "subject_id": -10
+ },
+ {
+ "subject_id": -20
+ },
+ {
+ "subject_id": -30
+ },
+ {
+ "subject_id": -40
+ }
+ ],
+ "subject_email_addresses":
+ [
+ {
+ "subject_id": -10,
+ "email_address": "john.doe@example.com",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "subject_id": -20,
+ "email_address": "max.mustermann@example.org",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "subject_id": -20,
+ "email_address": "mm@example.com",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "subject_id": -30,
+ "email_address": "joe.public@example.com",
+ "bouncing": true,
+ "verified": false
+ },
+ {
+ "subject_id": -40,
+ "email_address": "jane.doe@example.org",
+ "bouncing": false,
+ "verified": false
+ }
+ ],
+ "ccm_users":
+ [
+ {
+ "banned": false,
+ "hash_algorithm": "MD5",
+ "family_name": "Doe",
+ "given_name": "John",
+ "middle_name": null,
+ "title_post": null,
+ "title_pre": null,
+ "password": "604622dc8a888eb093454ebd77ca1675",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "axg8ira8fa",
+ "screen_name": "jdoe",
+ "sso_login": null,
+ "subject_id": -10
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Mustermann",
+ "given_name": "Max",
+ "middle_name": null,
+ "title_post": null,
+ "title_pre": null,
+ "password": "3428dfa9bb199f3372eb73c5feb038aef5bcbbfd4fada24c44026a25c883a9f2af8b84410a3b2684430d359f78400ad92ff8c71634f2c9bf437f0cd56c5d90c3",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "fjiajhigafgapoa",
+ "screen_name": "mmuster",
+ "sso_login": null,
+ "subject_id": -20
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Public",
+ "given_name": "Joe",
+ "middle_name": null,
+ "title_post": null,
+ "title_pre": null,
+ "password": "e9db883a56149f7521a00713c4d7b0c967ae42cc3f0dfcf96ccd0180c498abf57209a90db9cb5df3a7d23d4111e87578e09ea610e9c1d95c4695710e28c5ab02",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "axg8ira8fa",
+ "screen_name": "joe",
+ "sso_login": null,
+ "subject_id": -30
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Doe",
+ "given_name": "Jane",
+ "middle_name": "Anna",
+ "title_post": null,
+ "title_pre": "Dr.",
+ "password": "9f8ec7f4bcd376d1736ae9f5250412e15bed1783219fd5a03491cddf167ab2582763392a29ed1859a4e3bce81da65a6d861eda80b96fa0dcb88336c33f432183",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "maifgaoapafga9",
+ "screen_name": "jane",
+ "sso_login": null,
+ "subject_id": -40
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/data.json b/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/data.json
new file mode 100644
index 000000000..f46bdd38f
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/data.json
@@ -0,0 +1,95 @@
+{
+ "subjects":
+ [
+ {
+ "subject_id": -10
+ },
+ {
+ "subject_id": -20
+ },
+ {
+ "subject_id": -30
+ }
+ ],
+ "subject_email_addresses":
+ [
+ {
+ "subject_id": -10,
+ "email_address": "john.doe@example.com",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "subject_id": -20,
+ "email_address": "max.mustermann@example.org",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "subject_id": -20,
+ "email_address": "mm@example.com",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "subject_id": -30,
+ "email_address": "joe.public@example.com",
+ "bouncing": true,
+ "verified": false
+ }
+ ],
+ "ccm_users":
+ [
+ {
+ "banned": false,
+ "hash_algorithm": "MD5",
+ "family_name": "Doe",
+ "given_name": "John",
+ "middle_name": null,
+ "title_post": null,
+ "title_pre": null,
+ "password": "604622dc8a888eb093454ebd77ca1675",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "axg8ira8fa",
+ "screen_name": "jdoe",
+ "sso_login": null,
+ "subject_id": -10
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Mustermann",
+ "given_name": "Max",
+ "middle_name": null,
+ "title_post": null,
+ "title_pre": null,
+ "password": "3428dfa9bb199f3372eb73c5feb038aef5bcbbfd4fada24c44026a25c883a9f2af8b84410a3b2684430d359f78400ad92ff8c71634f2c9bf437f0cd56c5d90c3",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "fjiajhigafgapoa",
+ "screen_name": "mmuster",
+ "sso_login": null,
+ "subject_id": -20
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Public",
+ "given_name": "Joe",
+ "middle_name": null,
+ "title_post": null,
+ "title_pre": null,
+ "password": "e9db883a56149f7521a00713c4d7b0c967ae42cc3f0dfcf96ccd0180c498abf57209a90db9cb5df3a7d23d4111e87578e09ea610e9c1d95c4695710e28c5ab02",
+ "password_answer": null,
+ "password_question": null,
+ "password_reset_required": false,
+ "salt": "axg8ira8fa",
+ "screen_name": "joe",
+ "sso_login": null,
+ "subject_id": -30
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/passwords.txt b/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/passwords.txt
new file mode 100644
index 000000000..5f3767e1e
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/UserRepositoryTest/passwords.txt
@@ -0,0 +1,3 @@
+after-save-changed:
+
+John Doe: Een5vuwa
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index bc9077fb0..9ceb933f4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -247,6 +247,11 @@
hibernate-validator
5.1.3.Final
+
+ org.hibernate
+ hibernate-validator-cdi
+ 5.1.3.Final
+