From 5adab09c8041576abd3ff1fc984a195443036f15 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Thu, 26 Jul 2012 08:53:32 +0200
Subject: [PATCH] OO-291: add a view to collect membership information about an
 identity

---
 .../persistence/_spring/core_persistence.xml  |   1 +
 .../PersistingCourseGroupManager.java         |   4 +-
 .../olat/group/BusinessGroupMembership.java   |  46 +++++++
 .../org/olat/group/BusinessGroupService.java  |   5 +-
 .../olat/group/manager/BusinessGroupDAO.java  |  24 ++++
 .../manager/BusinessGroupRelationDAO.java     |  11 +-
 .../manager/BusinessGroupServiceImpl.java     |  13 +-
 .../org/olat/group/model/BGMembership.java    |  33 +++++
 .../model/BusinessGroupMembershipImpl.hbm.xml |  21 ++++
 .../model/BusinessGroupMembershipImpl.java    | 114 ++++++++++++++++++
 .../AbstractBusinessGroupListController.java  |  35 +++---
 .../org/olat/group/ui/main/BGMembership.java  |  14 ---
 .../group/ui/main/BGRoleCellRenderer.java     |   1 +
 .../org/olat/group/ui/main/BGTableItem.java   |   1 +
 .../ui/wizard/BGUserManagementController.java |   2 +-
 .../BGUserManagementGroupTableDataModel.java  |   2 +-
 .../database/mysql/alter_8_1_x_to_8_2_0.sql   |  16 ++-
 .../olat/group/test/BusinessGroupDAOTest.java |  37 ++++++
 .../test/BusinessGroupRelationDAOTest.java    |  31 ++---
 19 files changed, 337 insertions(+), 74 deletions(-)
 create mode 100644 src/main/java/org/olat/group/BusinessGroupMembership.java
 create mode 100644 src/main/java/org/olat/group/model/BGMembership.java
 create mode 100644 src/main/java/org/olat/group/model/BusinessGroupMembershipImpl.hbm.xml
 create mode 100644 src/main/java/org/olat/group/model/BusinessGroupMembershipImpl.java
 delete mode 100644 src/main/java/org/olat/group/ui/main/BGMembership.java

diff --git a/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml b/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml
index b6bedc60f2a..d4fa83101b5 100644
--- a/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml
+++ b/src/main/java/org/olat/core/commons/persistence/_spring/core_persistence.xml
@@ -23,6 +23,7 @@
 		<mapping-file>org/olat/group/context/BGContext2Resource.hbm.xml</mapping-file>
 		<mapping-file>org/olat/group/BusinessGroupImpl.hbm.xml</mapping-file>
 		<mapping-file>org/olat/group/model/BGResourceRelation.hbm.xml</mapping-file>
+		<mapping-file>org/olat/group/model/BusinessGroupMembershipImpl.hbm.xml</mapping-file>
 		<mapping-file>org/olat/resource/lock/pessimistic/PLockImpl.hbm.xml</mapping-file>
 		<mapping-file>org/olat/resource/references/ReferenceImpl.hbm.xml</mapping-file>
 		<mapping-file>org/olat/resource/OLATResourceImpl.hbm.xml</mapping-file>
diff --git a/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java b/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java
index cd9d80e28eb..04ca05dbb83 100644
--- a/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java
+++ b/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java
@@ -223,7 +223,7 @@ public class PersistingCourseGroupManager extends BasicManager implements Course
 
 		BaseSecurity secManager = BaseSecurityManager.getInstance();
 		boolean isParticipant = secManager.isIdentityPermittedOnResourceable(identity, Constants.PERMISSION_COACH, courseResource)
-				|| businessGroupService.isIdentityInBusinessGroup(identity, (String)null, true, false, courseResource);
+				|| businessGroupService.isIdentityInBusinessGroup(identity, true, false, courseResource);
 		return isParticipant;
 	}
 	
@@ -239,7 +239,7 @@ public class PersistingCourseGroupManager extends BasicManager implements Course
 		
 		BaseSecurity secManager = BaseSecurityManager.getInstance();
 		boolean isParticipant = secManager.isIdentityPermittedOnResourceable(identity, Constants.PERMISSION_PARTI, courseResource)
-				|| businessGroupService.isIdentityInBusinessGroup(identity, (String)null, false, true, courseResource);
+				|| businessGroupService.isIdentityInBusinessGroup(identity, false, true, courseResource);
 		return isParticipant;
 	}
 
diff --git a/src/main/java/org/olat/group/BusinessGroupMembership.java b/src/main/java/org/olat/group/BusinessGroupMembership.java
new file mode 100644
index 00000000000..17147eac47f
--- /dev/null
+++ b/src/main/java/org/olat/group/BusinessGroupMembership.java
@@ -0,0 +1,46 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.group;
+
+import java.util.Date;
+
+import org.olat.core.id.ModifiedInfo;
+import org.olat.group.model.BGMembership;
+
+/**
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ */
+public interface BusinessGroupMembership extends ModifiedInfo {
+
+
+	public Long getIdentityKey();
+
+	public Date getLastModified();
+
+	public Long getOwnerGroupKey();
+
+	public Long getParticipantGroupKey();
+
+	public Long getWaitingGroupKey();
+	
+	public BGMembership getMembership();
+
+}
diff --git a/src/main/java/org/olat/group/BusinessGroupService.java b/src/main/java/org/olat/group/BusinessGroupService.java
index 59ee2c3e24b..f49ed23001d 100644
--- a/src/main/java/org/olat/group/BusinessGroupService.java
+++ b/src/main/java/org/olat/group/BusinessGroupService.java
@@ -457,8 +457,7 @@ public interface BusinessGroupService {
 	 * @param businessGroups
 	 * @return The list of group keys where the identity is either participant or owner
 	 */
-	public List<Long> isIdentityInBusinessGroups(Identity identity, boolean owner, boolean attendee, boolean waiting,
-			List<BusinessGroup> businessGroups);
+	public List<BusinessGroupMembership> getBusinessGroupMembership(Identity identity, List<BusinessGroup> businessGroups);
 
 	/**
 	 * Checks if an identity is in a business group with a specific name (exact match), either as owner or
@@ -470,7 +469,7 @@ public interface BusinessGroupService {
 	 * @param resource
 	 * @return
 	 */
-	public boolean isIdentityInBusinessGroup(Identity identity, String groupName, boolean ownedById, boolean attendedById, OLATResource resource);
+	public boolean isIdentityInBusinessGroup(Identity identity, boolean ownedById, boolean attendedById, OLATResource resource);
 
 	/**
 	 * Checks if an identity is in a business group with a specific key, either as owner or
diff --git a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
index c686158616c..071f7bf5677 100644
--- a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
+++ b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java
@@ -46,10 +46,12 @@ import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupImpl;
+import org.olat.group.BusinessGroupMembership;
 import org.olat.group.BusinessGroupService;
 import org.olat.group.BusinessGroupShort;
 import org.olat.group.model.BGRepositoryEntryRelation;
 import org.olat.group.model.BGResourceRelation;
+import org.olat.group.model.BusinessGroupMembershipImpl;
 import org.olat.group.model.BusinessGroupShortImpl;
 import org.olat.group.model.SearchBusinessGroupParams;
 import org.olat.properties.Property;
@@ -283,6 +285,28 @@ public class BusinessGroupDAO {
 		return group;
 	}
 	
+	public List<BusinessGroupMembership> getMembershipInfoInBusinessGroups(Identity identity, List<BusinessGroup> groups) {
+		if(groups == null || groups.isEmpty()) {
+			return Collections.emptyList();
+		}
+
+		StringBuilder sb = new StringBuilder(); 
+		sb.append("select membership from ").append(BusinessGroupMembershipImpl.class.getName()).append(" as membership ")
+		  .append(" where membership.identityKey=:identId ")
+		  .append(" and (membership.ownerGroupKey in (:groupKeys) or membership.participantGroupKey in (:groupKeys) or membership.waitingGroupKey in (:groupKeys))");
+
+		List<Long> groupKeys = new ArrayList<Long>();
+		for(BusinessGroup group:groups) {
+			groupKeys.add(group.getKey());
+		}
+		List<BusinessGroupMembership> res = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), BusinessGroupMembership.class)
+				.setParameter("groupKeys", groupKeys)
+				.setParameter("identId", identity.getKey())
+				.setHint("org.hibernate.cacheable", Boolean.TRUE)
+				.getResultList();
+		return res;
+		
+	}
 
 	public List<Long> isIdentityInBusinessGroups(Identity identity, boolean owner, boolean attendee, boolean waiting, List<BusinessGroup> groups) {
 		if(groups == null || groups.isEmpty() || (!owner && !attendee && !waiting)) {
diff --git a/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java
index fd91eca1f1f..4fcff301285 100644
--- a/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java
+++ b/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java
@@ -30,7 +30,6 @@ import javax.persistence.TypedQuery;
 import org.olat.basesecurity.SecurityGroupMembershipImpl;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
-import org.olat.core.util.StringHelper;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupImpl;
 import org.olat.group.model.BGRepositoryEntryRelation;
@@ -89,14 +88,10 @@ public class BusinessGroupRelationDAO {
 		}
 	}
 
-	public boolean isIdentityInBusinessGroup(Identity identity, String name, Long groupKey, OLATResource resource) {
+	public boolean isIdentityInBusinessGroup(Identity identity, Long groupKey, OLATResource resource) {
 		StringBuilder sb = new StringBuilder();
 		sb.append("select count(bgi) from ").append(BusinessGroupImpl.class.getName()).append(" bgi");
 		boolean and = false;
-		if(StringHelper.containsNonWhitespace(name)) {
-			and = and(sb, and);
-			sb.append(" bgi.name=:name");
-		}
 		if(groupKey != null) {
 			and = and(sb, and);
 			sb.append(" bgi.key=:groupKey");
@@ -120,10 +115,6 @@ public class BusinessGroupRelationDAO {
 		TypedQuery<Number> query = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), Number.class)
 				.setParameter("identityKey", identity.getKey())
 				.setParameter("resourceKey", resource.getKey());
-
-		if(StringHelper.containsNonWhitespace(name)) {
-			query.setParameter("name", name);
-		}
 		if(groupKey != null) {
 			query.setParameter("groupKey", groupKey);
 		}
diff --git a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
index 2dd805f9916..897e85281c6 100644
--- a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
+++ b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java
@@ -67,6 +67,7 @@ import org.olat.core.util.resource.OLATResourceableJustBeforeDeletedEvent;
 import org.olat.course.nodes.projectbroker.service.ProjectBrokerManagerFactory;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupAddResponse;
+import org.olat.group.BusinessGroupMembership;
 import org.olat.group.BusinessGroupService;
 import org.olat.group.BusinessGroupShort;
 import org.olat.group.DeletableGroupData;
@@ -1252,23 +1253,21 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD
 
 	@Override
 	@Transactional(readOnly=true)
-	public List<Long> isIdentityInBusinessGroups(Identity identity, boolean owner, boolean attendee, boolean waiting,
-			List<BusinessGroup> groups) {
-		return businessGroupDAO.isIdentityInBusinessGroups(identity, owner, attendee, waiting, groups);
+	public List<BusinessGroupMembership> getBusinessGroupMembership(Identity identity, List<BusinessGroup> businessGroups) {
+		return businessGroupDAO.getMembershipInfoInBusinessGroups(identity, businessGroups);
 	}
 
 	@Override
 	@Transactional(readOnly=true)
-	public boolean isIdentityInBusinessGroup(Identity identity, String groupName,
-			boolean ownedById, boolean attendedById, OLATResource resource) {
-		return businessGroupRelationDAO.isIdentityInBusinessGroup(identity, groupName, null, resource);
+	public boolean isIdentityInBusinessGroup(Identity identity, boolean ownedById, boolean attendedById, OLATResource resource) {
+		return businessGroupRelationDAO.isIdentityInBusinessGroup(identity, null, resource);
 	}
 	
 	@Override
 	@Transactional(readOnly=true)
 	public boolean isIdentityInBusinessGroup(Identity identity, Long groupKey,
 			boolean ownedById, boolean attendedById, OLATResource resource) {
-		return businessGroupRelationDAO.isIdentityInBusinessGroup(identity, null, groupKey, resource);
+		return businessGroupRelationDAO.isIdentityInBusinessGroup(identity, groupKey, resource);
 	}
 	
 	@Override
diff --git a/src/main/java/org/olat/group/model/BGMembership.java b/src/main/java/org/olat/group/model/BGMembership.java
new file mode 100644
index 00000000000..feecb7a585f
--- /dev/null
+++ b/src/main/java/org/olat/group/model/BGMembership.java
@@ -0,0 +1,33 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.group.model;
+
+/**
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ */
+public enum BGMembership {
+	
+	owner,
+	participant,
+	waiting
+	
+
+}
diff --git a/src/main/java/org/olat/group/model/BusinessGroupMembershipImpl.hbm.xml b/src/main/java/org/olat/group/model/BusinessGroupMembershipImpl.hbm.xml
new file mode 100644
index 00000000000..41d388d8237
--- /dev/null
+++ b/src/main/java/org/olat/group/model/BusinessGroupMembershipImpl.hbm.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+	"-//Hibernate/Hibernate Mapping DTD//EN"
+	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
+<hibernate-mapping default-lazy="false">
+	<class name="org.olat.group.model.BusinessGroupMembershipImpl" table="o_bs_gp_membership_v" mutable="false">
+		<cache usage="read-write" />
+		<id name="key" 
+			type="long" 
+			column="membership_id" 
+			unsaved-value="null">
+			<generator class="hilo"/>
+		</id>
+		<property  name="lastModified" column="lastmodified" type="timestamp" />
+		<property  name="creationDate" column="creationdate" type="timestamp" />
+  		<property name="identityKey" column="identity_id" type="long" />
+		<property name="ownerGroupKey" column="owned_gp_id" type="long"/>
+		<property name="participantGroupKey" column="participant_gp_id" type="long"/>
+		<property name="waitingGroupKey" column="waiting_gp_id" type="long"/>
+	</class>
+</hibernate-mapping>
\ No newline at end of file
diff --git a/src/main/java/org/olat/group/model/BusinessGroupMembershipImpl.java b/src/main/java/org/olat/group/model/BusinessGroupMembershipImpl.java
new file mode 100644
index 00000000000..84f62881448
--- /dev/null
+++ b/src/main/java/org/olat/group/model/BusinessGroupMembershipImpl.java
@@ -0,0 +1,114 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.group.model;
+
+import java.util.Date;
+
+import org.olat.core.commons.persistence.PersistentObject;
+import org.olat.group.BusinessGroupMembership;
+
+/**
+ * 
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ */
+public class BusinessGroupMembershipImpl extends PersistentObject implements BusinessGroupMembership {
+
+	private static final long serialVersionUID = -5404538852842562897L;
+	
+	private Long identityKey;
+	private Date lastModified;
+	private Long ownerGroupKey;
+	private Long participantGroupKey;
+	private Long waitingGroupKey;
+
+	public Long getIdentityKey() {
+		return identityKey;
+	}
+
+	public void setIdentityKey(Long identityKey) {
+		this.identityKey = identityKey;
+	}
+
+	public Date getLastModified() {
+		return lastModified;
+	}
+
+	public void setLastModified(Date lastModified) {
+		this.lastModified = lastModified;
+	}
+
+	public Long getOwnerGroupKey() {
+		return ownerGroupKey;
+	}
+
+	public void setOwnerGroupKey(Long ownerGroupKey) {
+		this.ownerGroupKey = ownerGroupKey;
+	}
+
+	public Long getParticipantGroupKey() {
+		return participantGroupKey;
+	}
+
+	public void setParticipantGroupKey(Long participantGroupKey) {
+		this.participantGroupKey = participantGroupKey;
+	}
+
+	public Long getWaitingGroupKey() {
+		return waitingGroupKey;
+	}
+
+	public void setWaitingGroupKey(Long waitingGroupKey) {
+		this.waitingGroupKey = waitingGroupKey;
+	}
+
+	@Override
+	public BGMembership getMembership() {
+		if(ownerGroupKey != null) {
+			return BGMembership.owner;
+		}
+		if(participantGroupKey != null) {
+			return BGMembership.participant;
+		}
+		if(waitingGroupKey != null) {
+			return BGMembership.waiting;
+		}
+		return null;
+	}
+
+	@Override
+	public int hashCode() {
+		return getKey() == null ? 2901 : getKey().hashCode();
+	}
+
+	/**
+	 * Compares the keys.
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(Object obj) {
+		if(this == obj) {
+			return true;
+		} else if (obj instanceof BusinessGroupMembershipImpl) {
+			BusinessGroupMembershipImpl bg = (BusinessGroupMembershipImpl)obj;
+			return getKey() != null && getKey().equals(bg.getKey());
+		}
+		return false;
+	}
+}
diff --git a/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java b/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java
index ce947646899..20495855315 100644
--- a/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java
+++ b/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java
@@ -22,8 +22,10 @@ package org.olat.group.ui.main;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.olat.NewControllerFactory;
@@ -62,9 +64,11 @@ import org.olat.core.util.mail.MailNotificationEditController;
 import org.olat.core.util.mail.MailTemplate;
 import org.olat.core.util.vfs.Quota;
 import org.olat.group.BusinessGroup;
+import org.olat.group.BusinessGroupMembership;
 import org.olat.group.BusinessGroupModule;
 import org.olat.group.BusinessGroupService;
 import org.olat.group.GroupLoggingAction;
+import org.olat.group.model.BGMembership;
 import org.olat.group.model.BGRepositoryEntryRelation;
 import org.olat.group.model.MembershipModification;
 import org.olat.group.model.SearchBusinessGroupParams;
@@ -657,12 +661,20 @@ abstract class AbstractBusinessGroupListController extends BasicController {
 		}
 		lastSearchParams = params;
 
-		List<Long> groupsAsOwner = businessGroupService.isIdentityInBusinessGroups(getIdentity(), true, false, false, groups);
-		List<Long> groupsAsParticipant = businessGroupService.isIdentityInBusinessGroups(getIdentity(), false, true, false, groups);
-		List<Long> groupsAsWaiter = businessGroupService.isIdentityInBusinessGroups(getIdentity(), false, false, true, groups);
+		List<BusinessGroupMembership> groupsAsOwner = businessGroupService.getBusinessGroupMembership(getIdentity(), groups);
 
-		Set<Long> memberships = new HashSet<Long>(groupsAsOwner);
-		memberships.addAll(groupsAsParticipant);
+		Map<Long, BusinessGroupMembership> memberships = new HashMap<Long, BusinessGroupMembership>();
+		for(BusinessGroupMembership membership: groupsAsOwner) {
+			if(membership.getOwnerGroupKey() != null) {
+				memberships.put(membership.getOwnerGroupKey(), membership);
+			}
+			if(membership.getParticipantGroupKey() != null) {
+				memberships.put(membership.getParticipantGroupKey(), membership);
+			}
+			if(membership.getWaitingGroupKey() != null) {
+				memberships.put(membership.getWaitingGroupKey(), membership);
+			}
+		}
 
 		List<Long> resourceKeys = new ArrayList<Long>(groups.size());
 		for(BusinessGroup group:groups) {
@@ -690,17 +702,10 @@ abstract class AbstractBusinessGroupListController extends BasicController {
 				}
 			}
 			
-			Boolean allowLeave =  memberships.contains(group.getKey()) ? Boolean.TRUE : null;
+			BusinessGroupMembership membership =  memberships.get(group.getKey());
+			Boolean allowLeave =  membership != null;
 			Boolean allowDelete = admin ? Boolean.TRUE : null;
-			
-			BGMembership member = null;
-			if(groupsAsOwner.contains(group.getKey())) {
-				member = BGMembership.owner;
-			} else if (groupsAsParticipant.contains(group.getKey())) {
-				member = BGMembership.participant;
-			} else if (groupsAsWaiter.contains(group.getKey())) {
-				member = BGMembership.waiting;
-			}
+			BGMembership member = membership == null ? null : membership.getMembership();
 			boolean marked = markedResources.contains(group.getResource().getResourceableId());
 			BGTableItem tableItem = new BGTableItem(group, marked, member, allowLeave, allowDelete, accessMethods);
 			tableItem.setUnfilteredRelations(resources);
diff --git a/src/main/java/org/olat/group/ui/main/BGMembership.java b/src/main/java/org/olat/group/ui/main/BGMembership.java
deleted file mode 100644
index 56bc07e84b2..00000000000
--- a/src/main/java/org/olat/group/ui/main/BGMembership.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.olat.group.ui.main;
-
-/**
- * 
- * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
- */
-public enum BGMembership {
-	
-	owner,
-	participant,
-	waiting
-	
-
-}
diff --git a/src/main/java/org/olat/group/ui/main/BGRoleCellRenderer.java b/src/main/java/org/olat/group/ui/main/BGRoleCellRenderer.java
index ddfdc423a0b..a12794723bf 100644
--- a/src/main/java/org/olat/group/ui/main/BGRoleCellRenderer.java
+++ b/src/main/java/org/olat/group/ui/main/BGRoleCellRenderer.java
@@ -26,6 +26,7 @@ import org.olat.core.gui.render.Renderer;
 import org.olat.core.gui.render.StringOutput;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.util.Util;
+import org.olat.group.model.BGMembership;
 
 /**
  * 
diff --git a/src/main/java/org/olat/group/ui/main/BGTableItem.java b/src/main/java/org/olat/group/ui/main/BGTableItem.java
index fb4472580c4..e089530a22a 100644
--- a/src/main/java/org/olat/group/ui/main/BGTableItem.java
+++ b/src/main/java/org/olat/group/ui/main/BGTableItem.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.olat.group.BusinessGroup;
+import org.olat.group.model.BGMembership;
 import org.olat.group.model.BGRepositoryEntryRelation;
 import org.olat.repository.RepositoryEntry;
 import org.olat.resource.accesscontrol.model.PriceMethodBundle;
diff --git a/src/main/java/org/olat/group/ui/wizard/BGUserManagementController.java b/src/main/java/org/olat/group/ui/wizard/BGUserManagementController.java
index d802f470842..a3e52ad413f 100644
--- a/src/main/java/org/olat/group/ui/wizard/BGUserManagementController.java
+++ b/src/main/java/org/olat/group/ui/wizard/BGUserManagementController.java
@@ -50,8 +50,8 @@ import org.olat.core.gui.control.generic.closablewrapper.CloseableModalControlle
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
 import org.olat.group.BusinessGroup;
+import org.olat.group.model.BGMembership;
 import org.olat.group.model.MembershipModification;
-import org.olat.group.ui.main.BGMembership;
 import org.olat.group.ui.main.BGRoleCellRenderer;
 import org.olat.user.UserManager;
 import org.olat.user.propertyhandlers.UserPropertyHandler;
diff --git a/src/main/java/org/olat/group/ui/wizard/BGUserManagementGroupTableDataModel.java b/src/main/java/org/olat/group/ui/wizard/BGUserManagementGroupTableDataModel.java
index 1e80b76564a..ad94031824a 100644
--- a/src/main/java/org/olat/group/ui/wizard/BGUserManagementGroupTableDataModel.java
+++ b/src/main/java/org/olat/group/ui/wizard/BGUserManagementGroupTableDataModel.java
@@ -25,7 +25,7 @@ import java.util.Locale;
 
 import org.olat.core.gui.components.table.DefaultTableDataModel;
 import org.olat.core.id.Identity;
-import org.olat.group.ui.main.BGMembership;
+import org.olat.group.model.BGMembership;
 import org.olat.user.propertyhandlers.UserPropertyHandler;
 
 /**
diff --git a/src/main/resources/database/mysql/alter_8_1_x_to_8_2_0.sql b/src/main/resources/database/mysql/alter_8_1_x_to_8_2_0.sql
index 8690e967e72..ba1d7f45244 100644
--- a/src/main/resources/database/mysql/alter_8_1_x_to_8_2_0.sql
+++ b/src/main/resources/database/mysql/alter_8_1_x_to_8_2_0.sql
@@ -99,7 +99,21 @@ create or replace view o_re_strict_tutor_v as (
    where re.membersonly=1 and re.accesscode=1
 );
 
-
+create or replace view o_bs_gp_membership_v as (
+   select
+      membership.id as membership_id,
+      membership.identity_id as identity_id,
+      membership.lastmodified as lastmodified,
+      membership.creationdate as creationdate,
+      owned_gp.group_id as owned_gp_id,
+      participant_gp.group_id as participant_gp_id,
+      waiting_gp.group_id as waiting_gp_id
+   from o_bs_membership as membership
+   left join o_gp_business as owned_gp on (membership.secgroup_id = owned_gp.fk_ownergroup)
+   left join o_gp_business as participant_gp on (membership.secgroup_id = participant_gp.fk_partipiciantgroup)
+   left join o_gp_business as waiting_gp on (membership.secgroup_id = waiting_gp.fk_waitinggroup)
+   where (owned_gp.group_id is not null or participant_gp.group_id is not null or waiting_gp.group_id is not null)
+);
 
 
 
diff --git a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
index 38cceaf968b..e11db019699 100644
--- a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
+++ b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java
@@ -828,4 +828,41 @@ public class BusinessGroupDAOTest extends OlatTestCase {
 		Assert.assertEquals(1, groupKeysC.size());
 		Assert.assertTrue(groupKeysC.contains(group2.getKey()));
 	}
+	
+	@Test
+	public void getMembershipInfoInBusinessGroups() {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("is-in-grp-" + UUID.randomUUID().toString());
+		BusinessGroup group1 = businessGroupDao.createAndPersist(id, "is-in-grp-1", "is-in-grp-1-desc", 0, 5, true, false, true, false, false);
+		BusinessGroup group2 = businessGroupDao.createAndPersist(null, "is-in-grp-2", "is-in-grp-2-desc", 0, 5, true, false, true, false, false);
+		BusinessGroup group3 = businessGroupDao.createAndPersist(null, "is-in-grp-3", "is-in-grp-3-desc", 0, 5, true, false, true, false, false);
+		dbInstance.commitAndCloseSession();
+
+		securityManager.addIdentityToSecurityGroup(id, group2.getPartipiciantGroup());
+		securityManager.addIdentityToSecurityGroup(id, group3.getWaitingGroup());
+		dbInstance.commitAndCloseSession();
+		
+		List<BusinessGroup> groups = new ArrayList<BusinessGroup>();
+		groups.add(group1);
+		groups.add(group2);
+		groups.add(group3);
+
+		//check owner + attendee
+		List<Long> groupKeysA = businessGroupDao.isIdentityInBusinessGroups(id, true, true, false, groups);
+		Assert.assertNotNull(groupKeysA);
+		Assert.assertEquals(2, groupKeysA.size());
+		Assert.assertTrue(groupKeysA.contains(group1.getKey()));
+		Assert.assertTrue(groupKeysA.contains(group2.getKey()));
+		
+		//check owner 
+		List<Long> groupKeysB = businessGroupDao.isIdentityInBusinessGroups(id, true, false, false, groups);
+		Assert.assertNotNull(groupKeysB);
+		Assert.assertEquals(1, groupKeysB.size());
+		Assert.assertTrue(groupKeysB.contains(group1.getKey()));
+
+		//check attendee 
+		List<Long> groupKeysC = businessGroupDao.isIdentityInBusinessGroups(id, false, true, false, groups);
+		Assert.assertNotNull(groupKeysC);
+		Assert.assertEquals(1, groupKeysC.size());
+		Assert.assertTrue(groupKeysC.contains(group2.getKey()));
+	}
 }
diff --git a/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java b/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java
index 8f4922ba69a..aea323946a3 100644
--- a/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java
+++ b/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java
@@ -232,19 +232,16 @@ public class BusinessGroupRelationDAOTest extends OlatTestCase {
 		dbInstance.commitAndCloseSession();
 		
 		//check
-		boolean test1 = businessGroupRelationDao.isIdentityInBusinessGroup(id, "rel-bgis-1", null, resource1); 
+		boolean test1 = businessGroupRelationDao.isIdentityInBusinessGroup(id, null, resource1); 
 		Assert.assertTrue(test1);
 		//name doesn't exist 
-		boolean test2 = businessGroupRelationDao.isIdentityInBusinessGroup(id, "rel-bgis-2", null, resource1); 
+		boolean test2 = businessGroupRelationDao.isIdentityInBusinessGroup(id, 1l, resource1); 
 		Assert.assertFalse(test2);
-		//case insensitive (different between mysql and postgresql)
-		//boolean test3 = businessGroupRelationDao.isIdentityInBusinessGroup(id, "rel-bgis-1".toUpperCase(), resource1); 
-		//Assert.assertTrue(test3);
 		//wrong resource
-		boolean test4 = businessGroupRelationDao.isIdentityInBusinessGroup(id, "rel-bgis-1", null, resource3); 
+		boolean test4 = businessGroupRelationDao.isIdentityInBusinessGroup(id, null, resource3); 
 		Assert.assertFalse(test4);
 		//check null
-		boolean test5 = businessGroupRelationDao.isIdentityInBusinessGroup(id, null, null, resource1); 
+		boolean test5 = businessGroupRelationDao.isIdentityInBusinessGroup(id, null, resource1); 
 		Assert.assertTrue(test5);
 	}
 	
@@ -263,15 +260,15 @@ public class BusinessGroupRelationDAOTest extends OlatTestCase {
 		dbInstance.commitAndCloseSession();
 		
 		//check
-		boolean test1 = businessGroupRelationDao.isIdentityInBusinessGroup(id, null, group1.getKey(), resource1); 
+		boolean test1 = businessGroupRelationDao.isIdentityInBusinessGroup(id, group1.getKey(), resource1); 
 		Assert.assertTrue(test1);
-		//name doesn't exist 
-		boolean test2 = businessGroupRelationDao.isIdentityInBusinessGroup(id, null, 1l, resource1); 
+		//key doesn't exist 
+		boolean test2 = businessGroupRelationDao.isIdentityInBusinessGroup(id, 1l, resource1); 
 		Assert.assertFalse(test2);
-		boolean test3 = businessGroupRelationDao.isIdentityInBusinessGroup(id, null, group1.getKey(), resource3); 
+		boolean test3 = businessGroupRelationDao.isIdentityInBusinessGroup(id, group1.getKey(), resource3); 
 		Assert.assertFalse(test3);
 		//check null
-		boolean test5 = businessGroupRelationDao.isIdentityInBusinessGroup(id, null, null, resource1); 
+		boolean test5 = businessGroupRelationDao.isIdentityInBusinessGroup(id, null, resource1); 
 		Assert.assertTrue(test5);
 	}
 	
@@ -290,16 +287,10 @@ public class BusinessGroupRelationDAOTest extends OlatTestCase {
 		dbInstance.commitAndCloseSession();
 		
 		//check
-		boolean test1 = businessGroupRelationDao.isIdentityInBusinessGroup(id, "rel-bg-part-1", null, resource1); 
+		boolean test1 = businessGroupRelationDao.isIdentityInBusinessGroup(id, null, resource1); 
 		Assert.assertTrue(test1);
-		//name doesn't exist 
-		boolean test2 = businessGroupRelationDao.isIdentityInBusinessGroup(id, "rel-bg-part-2", null, resource1); 
-		Assert.assertFalse(test2);
-		//case insensitive (different between mysql and postgresql)
-		//boolean test3 = businessGroupRelationDao.isIdentityInBusinessGroup(id, "rel-bg-part-1".toUpperCase(), resource1); 
-		//Assert.assertTrue(test3);
 		//wrong resource
-		boolean test4 = businessGroupRelationDao.isIdentityInBusinessGroup(id, "rel-bg-part-1", null, resource3); 
+		boolean test4 = businessGroupRelationDao.isIdentityInBusinessGroup(id, null, resource3); 
 		Assert.assertFalse(test4);
 	}
 
-- 
GitLab