Added DAO methods regarding user groups.

Change-Id: Idd5a0be378e777b39dd4e7583c10016154219226
diff --git a/core/src/main/java/de/ids_mannheim/korap/utils/ParameterChecker.java b/core/src/main/java/de/ids_mannheim/korap/utils/ParameterChecker.java
new file mode 100644
index 0000000..f3bd3a1
--- /dev/null
+++ b/core/src/main/java/de/ids_mannheim/korap/utils/ParameterChecker.java
@@ -0,0 +1,31 @@
+package de.ids_mannheim.korap.utils;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+
+public class ParameterChecker {
+
+    public static void checkObjectValue (Object obj, String name)
+            throws KustvaktException {
+        if (obj == null) {
+            throw new KustvaktException(StatusCodes.INVALID_ARGUMENT, name,
+                    "null");
+        }
+    }
+    
+    public static void checkStringValue (String string, String name)
+            throws KustvaktException {
+        if (string == null || string.isEmpty()) {
+            throw new KustvaktException(StatusCodes.INVALID_ARGUMENT, name,
+                    string);
+        }
+    }
+
+    public static void checkIntegerValue (int integer, String name) throws KustvaktException {
+        if (integer == 0) {
+            throw new KustvaktException(StatusCodes.INVALID_ARGUMENT, name,
+                    "0");
+        }
+    }
+
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/constants/PrivilegeType.java b/full/src/main/java/de/ids_mannheim/korap/constants/PrivilegeType.java
new file mode 100644
index 0000000..3b8b701
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/constants/PrivilegeType.java
@@ -0,0 +1,5 @@
+package de.ids_mannheim.korap.constants;
+
+public enum PrivilegeType {
+    READ, WRITE, DELETE;
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
new file mode 100644
index 0000000..900e062
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupDao.java
@@ -0,0 +1,79 @@
+package de.ids_mannheim.korap.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import de.ids_mannheim.korap.constants.UserGroupStatus;
+import de.ids_mannheim.korap.constants.VirtualCorpusAccessStatus;
+import de.ids_mannheim.korap.entity.UserGroup;
+import de.ids_mannheim.korap.entity.UserGroupMember;
+import de.ids_mannheim.korap.entity.VirtualCorpus;
+import de.ids_mannheim.korap.entity.VirtualCorpusAccessGroup;
+
+@Transactional
+@Component
+public class UserGroupDao {
+
+    @PersistenceContext
+    private EntityManager entityManager;
+
+    public void createGroup (String name, String createdBy,
+            List<UserGroupMember> members, UserGroupStatus status) {
+        UserGroup group = new UserGroup();
+        group.setName(name);
+        group.setStatus(status);
+        group.setCreatedBy(createdBy);
+        group.setMembers(members);
+        entityManager.persist(group);
+    }
+
+    public void deleteGroup (int groupId, String deletedBy,
+            boolean isSoftDelete) {
+        UserGroup group = retrieveGroupById(groupId);
+        if (isSoftDelete) {
+            group.setStatus(UserGroupStatus.DELETED);
+            group.setDeletedBy(deletedBy);
+            entityManager.persist(group);
+        }
+        else {
+            entityManager.remove(group);
+        }
+    }
+
+    public UserGroup retrieveGroupById (int groupId) {
+        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
+        CriteriaQuery<UserGroup> query =
+                criteriaBuilder.createQuery(UserGroup.class);
+
+        Root<UserGroup> root = query.from(UserGroup.class);
+        query.select(root);
+        query.where(criteriaBuilder.equal(root.get("id"), groupId));
+        Query q = entityManager.createQuery(query);
+        return (UserGroup) q.getSingleResult();
+    }
+
+    public void addVCToGroup (List<VirtualCorpus> virtualCorpora,
+            String createdBy, UserGroup group) {
+        // check role
+        
+        VirtualCorpusAccessGroup accessGroup;
+        for (VirtualCorpus vc : virtualCorpora) {
+            accessGroup = new VirtualCorpusAccessGroup();
+            accessGroup.setCreatedBy(createdBy);
+            accessGroup.setStatus(VirtualCorpusAccessStatus.ACTIVE);
+            accessGroup.setUserGroup(group);
+            accessGroup.setVirtualCorpus(vc);
+            entityManager.persist(accessGroup);
+        }
+    }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java
new file mode 100644
index 0000000..5404c02
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/UserGroupMemberDao.java
@@ -0,0 +1,95 @@
+package de.ids_mannheim.korap.dao;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import de.ids_mannheim.korap.constants.GroupMemberStatus;
+import de.ids_mannheim.korap.entity.UserGroup;
+import de.ids_mannheim.korap.entity.UserGroupMember;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.utils.ParameterChecker;
+
+@Transactional
+@Component
+public class UserGroupMemberDao {
+
+    @PersistenceContext
+    private EntityManager entityManager;
+
+    public void addMember (UserGroupMember member, UserGroup userGroup)
+            throws KustvaktException {
+        ParameterChecker.checkObjectValue(member, "userGroupMember");
+        ParameterChecker.checkObjectValue(userGroup, "userGroup");
+
+        List<UserGroupMember> members = userGroup.getMembers();
+        members.add(member);
+        entityManager.persist(userGroup);
+    }
+    
+    public void addMembers (List<UserGroupMember> newMembers, UserGroup userGroup)
+            throws KustvaktException {
+        ParameterChecker.checkObjectValue(newMembers, "List<UserGroupMember>");
+        ParameterChecker.checkObjectValue(userGroup, "userGroup");
+
+        List<UserGroupMember> members = userGroup.getMembers();
+        members.addAll(newMembers);
+        entityManager.persist(userGroup);
+    }
+    
+    public void approveMember (String userId, int groupId)
+            throws KustvaktException {
+        ParameterChecker.checkStringValue(userId, "userId");
+        ParameterChecker.checkIntegerValue(groupId, "groupId");
+
+        UserGroupMember member = retrieveMemberById(userId, groupId);
+        member.setStatus(GroupMemberStatus.ACTIVE);
+        entityManager.persist(member);
+    }
+
+    public void deleteMember (String userId, int groupId, boolean isSoftDelete)
+            throws KustvaktException {
+        ParameterChecker.checkStringValue(userId, "userId");
+        ParameterChecker.checkIntegerValue(groupId, "groupId");
+
+        UserGroupMember m = retrieveMemberById(userId, groupId);
+        if (isSoftDelete) {
+            m.setStatus(GroupMemberStatus.DELETED);
+            entityManager.persist(m);
+        }
+        else {
+            entityManager.remove(m);
+        }
+    }
+
+    public UserGroupMember retrieveMemberById (String userId, int groupId)
+            throws KustvaktException {
+        ParameterChecker.checkStringValue(userId, "userId");
+        ParameterChecker.checkIntegerValue(groupId, "groupId");
+
+        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
+        CriteriaQuery<UserGroupMember> query =
+                criteriaBuilder.createQuery(UserGroupMember.class);
+
+        Root<UserGroupMember> root = query.from(UserGroupMember.class);
+
+        Predicate predicate = criteriaBuilder.and(
+                criteriaBuilder.equal(root.get("groupId"), groupId),
+                criteriaBuilder.equal(root.get("userId"), userId));
+
+        query.select(root);
+        query.where(predicate);
+        Query q = entityManager.createQuery(query);
+        return (UserGroupMember) q.getSingleResult();
+    }
+
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
index 69eb5ef..22042a7 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/VirtualCorpusDao.java
@@ -39,7 +39,7 @@
 
     @PersistenceContext
     private EntityManager entityManager;
-    
+
     public void storeVirtualCorpus (VirtualCorpus virtualCorpus) {
         entityManager.persist(virtualCorpus);
     }
@@ -127,15 +127,21 @@
         Join<VirtualCorpus, VirtualCorpusAccessGroup> accessGroup =
                 virtualCorpus.join("accessGroup");
 
-        Predicate corpusStatus = builder.notEqual(accessGroup.get("status"),
-                VirtualCorpusAccessStatus.HIDDEN);
+        Predicate corpusStatus = builder.and(
+                builder.notEqual(accessGroup.get("status"),
+                        VirtualCorpusAccessStatus.HIDDEN),
+                builder.notEqual(accessGroup.get("status"),
+                        VirtualCorpusAccessStatus.DELETED));
+        
         Predicate userGroupStatus =
                 builder.notEqual(accessGroup.get("userGroup").get("status"),
                         UserGroupStatus.DELETED);
         Join<VirtualCorpusAccessGroup, UserGroup> userGroupMembers =
                 accessGroup.join("userGroup").join("members");
+        
         Predicate memberStatus = builder.equal(userGroupMembers.get("status"),
                 GroupMemberStatus.ACTIVE);
+        
         Predicate user = builder.equal(userGroupMembers.get("userId"), userId);
 
         query.select(virtualCorpus);
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/Privilege.java b/full/src/main/java/de/ids_mannheim/korap/entity/Privilege.java
index dd9fbd1..3d41d34 100644
--- a/full/src/main/java/de/ids_mannheim/korap/entity/Privilege.java
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/Privilege.java
@@ -1,12 +1,33 @@
 package de.ids_mannheim.korap.entity;
 
-/** Simple definitions of privileges.
- *  When needed can be adopted into a database table. 
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+
+import de.ids_mannheim.korap.constants.PrivilegeType;
+
+/**  
  * 
  * @author margaretha
  *
  */
-public enum Privilege {
+@Entity
+@Table
+public class Privilege {
     
-    READ, WRITE, DELETE;
+    @Id
+    @Enumerated(EnumType.STRING)
+    private PrivilegeType id;
+    
+    @ManyToOne
+    @JoinColumn
+    private Role role;
+    
+    public String toString () {
+        return "id=" + id + ", role="+ role;
+    }
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/Role.java b/full/src/main/java/de/ids_mannheim/korap/entity/Role.java
index 7461fda..8ba2e7d 100644
--- a/full/src/main/java/de/ids_mannheim/korap/entity/Role.java
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/Role.java
@@ -2,11 +2,14 @@
 
 import java.util.List;
 
-import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
 import javax.persistence.Id;
+import javax.persistence.JoinColumn;
 import javax.persistence.ManyToMany;
+import javax.persistence.OneToMany;
 import javax.persistence.Table;
 
 import lombok.Getter;
@@ -24,14 +27,17 @@
 @Table(name = "role")
 public class Role {
     @Id
-    @Column(unique = true)
-    private String id;
-    private String privilege;
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private int id;
+    private String name;
 
     @ManyToMany(mappedBy = "roles", fetch = FetchType.LAZY)
     private List<UserGroupMember> userGroupMembers;
 
+    @OneToMany(mappedBy = "role")
+    private List<Privilege> privileges;
+
     public String toString () {
-        return "id=" + id + ", privilege= " + privilege;
+        return "id=" + id + "name=" + name + ", privileges=" + privileges;
     }
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/UserGroup.java b/full/src/main/java/de/ids_mannheim/korap/entity/UserGroup.java
index f6c2d81..0e4a26b 100644
--- a/full/src/main/java/de/ids_mannheim/korap/entity/UserGroup.java
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/UserGroup.java
@@ -42,6 +42,8 @@
     private String name;
     @Column(name = "created_by")
     private String createdBy;
+    @Column(name = "deleted_by")
+    private String deletedBy;
     
     @Enumerated(EnumType.STRING)
     private UserGroupStatus status;
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/UserGroupMember.java b/full/src/main/java/de/ids_mannheim/korap/entity/UserGroupMember.java
index db705c4..75e2e54 100644
--- a/full/src/main/java/de/ids_mannheim/korap/entity/UserGroupMember.java
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/UserGroupMember.java
@@ -19,6 +19,7 @@
 import javax.persistence.UniqueConstraint;
 
 import de.ids_mannheim.korap.constants.GroupMemberStatus;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -63,6 +64,20 @@
     private Set<Role> roles;
 
 
+    public UserGroupMember createMember (String userId, String createdBy,
+            UserGroup userGroup, Set<Role> roles) throws KustvaktException {
+//        checkStringValue(userId, "userId");
+//        checkStringValue(createdBy, "createdBy");
+        
+        UserGroupMember member = new UserGroupMember();
+        member.setUserId(userId);
+        member.setCreatedBy(createdBy);
+        member.setGroup(userGroup);
+        member.setStatus(GroupMemberStatus.PENDING);
+        member.setRoles(roles);
+        return member;
+    }
+    
     @Override
     public String toString () {
         return "id=" + id + ", group= " + group + ", userId= " + userId
diff --git a/full/src/main/resources/db/new-mysql/V1.1__create_virtual_corpus_tables.sql b/full/src/main/resources/db/new-mysql/V1.1__create_virtual_corpus_tables.sql
index 44b49e3..a69ef64 100644
--- a/full/src/main/resources/db/new-mysql/V1.1__create_virtual_corpus_tables.sql
+++ b/full/src/main/resources/db/new-mysql/V1.1__create_virtual_corpus_tables.sql
@@ -3,6 +3,7 @@
   name varchar(100) NOT NULL,
   status varchar(100) NOT NULL,
   created_by varchar(100) NOT NULL,
+  deleted_by varchar(100) DEFAULT NULL,
   INDEX status_index(status)
 );
 
@@ -21,8 +22,17 @@
 ); 
 
 CREATE TABLE IF NOT EXISTS role (
-  id varchar(100) PRIMARY KEY NOT NULL,
-  privilege varchar(100) NOT NULL
+  id INTEGER PRIMARY KEY AUTO_INCREMENT,
+  name varchar(100) NOT NULL,
+  privilege varchar(20) NOT NULL,
+  UNIQUE INDEX unique_index (name,privilege),
+  FOREIGN KEY (privilege) 
+  	REFERENCES privilege (id)
+  	ON DELETE CASCADE
+);
+
+CREATE TABLE IF NOT EXISTS privilege (
+  id varchar(20) PRIMARY KEY NOT NULL
 );
 
 CREATE TABLE IF NOT EXISTS group_member_role (