diff --git a/src/main/java/org/olat/NewControllerFactory.java b/src/main/java/org/olat/NewControllerFactory.java index d5c8aa14617136cb0cf1474e92b225a76504bc44..ad23f07a04ae4b0422881d11148c5cf13f9c500c 100644 --- a/src/main/java/org/olat/NewControllerFactory.java +++ b/src/main/java/org/olat/NewControllerFactory.java @@ -124,6 +124,18 @@ public class NewControllerFactory extends LogDelegator { } return false; } + + /** + * Launch a controller in a tab or a site with the business path + * @param businessPath + * @param ureq + * @param origControl + */ + public void launch(String businessPath, UserRequest ureq, WindowControl origControl) { + BusinessControl bc = BusinessControlFactory.getInstance().createFromString(businessPath); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, origControl); + launch(ureq, bwControl); + } /** * Launch a controller in a tab or site in the given window from a user diff --git a/src/main/java/org/olat/commons/coordinate/cluster/jms/JmsTestSer.java b/src/main/java/org/olat/commons/coordinate/cluster/jms/JmsTestSer.java index 5aa97eb2378e70f90ac948e2ff3b3bd6800df0a7..3a8c0b97fca8b37317f8d05361937b9b4a7f0b53 100644 --- a/src/main/java/org/olat/commons/coordinate/cluster/jms/JmsTestSer.java +++ b/src/main/java/org/olat/commons/coordinate/cluster/jms/JmsTestSer.java @@ -35,6 +35,7 @@ import org.olat.core.util.ObjectCloner; import org.olat.course.assessment.AssessmentChangedEvent; import org.olat.group.BusinessGroup; import org.olat.group.ui.edit.BusinessGroupModifiedEvent; +import org.olat.resource.OLATResource; public class JmsTestSer { @@ -153,6 +154,11 @@ public class JmsTestSer { public String getName() { return null; } + + @Override + public OLATResource getResource() { + return null; + } public SecurityGroup getOwnerGroup() { return null; diff --git a/src/main/java/org/olat/group/BusinessGroup.java b/src/main/java/org/olat/group/BusinessGroup.java index ff9b280dace703108dd82b212bae7c04df892c1b..d1831350a6038df746f8b756b2785ca91fe88f66 100644 --- a/src/main/java/org/olat/group/BusinessGroup.java +++ b/src/main/java/org/olat/group/BusinessGroup.java @@ -32,6 +32,7 @@ import org.olat.core.id.CreateInfo; import org.olat.core.id.ModifiedInfo; import org.olat.core.id.OLATResourceable; import org.olat.core.id.Persistable; +import org.olat.resource.OLATResource; /** * Initial Date: Aug 2, 2004 @@ -87,6 +88,8 @@ public interface BusinessGroup extends Persistable, CreateInfo, ModifiedInfo, OL * @param description the description of this group. Might be NULL */ public void setDescription(String description); + + public OLATResource getResource(); /** * The BusinessGroup has 1..n Owners acting as <i>administrators </i>. diff --git a/src/main/java/org/olat/group/BusinessGroupContextEntryControllerCreator.java b/src/main/java/org/olat/group/BusinessGroupContextEntryControllerCreator.java index 33be7acd36459ed3f3fb04a4ba1ee78815a8210a..cdcb9e2067f45e082b1025861954037f8622446d 100644 --- a/src/main/java/org/olat/group/BusinessGroupContextEntryControllerCreator.java +++ b/src/main/java/org/olat/group/BusinessGroupContextEntryControllerCreator.java @@ -29,8 +29,6 @@ import org.olat.core.id.OLATResourceable; import org.olat.core.id.context.ContextEntry; import org.olat.core.id.context.DefaultContextEntryControllerCreator; import org.olat.group.ui.BGControllerFactory; -import org.olat.resource.OLATResource; -import org.olat.resource.OLATResourceManager; import org.olat.resource.accesscontrol.AccessControlModule; import org.olat.resource.accesscontrol.manager.ACFrontendManager; @@ -59,7 +57,8 @@ public class BusinessGroupContextEntryControllerCreator extends DefaultContextEn Controller ctrl = null; BusinessGroup bgroup = bgs.loadBusinessGroup(gKey); if(bgroup != null) { - boolean isOlatAdmin = ureq.getUserSession().getRoles().isOLATAdmin(); + boolean isOlatAdmin = ureq.getUserSession().getRoles().isOLATAdmin() + || ureq.getUserSession().getRoles().isGroupManager(); // check if allowed to start (must be member or admin) //fxdiff VCRP-1,2: access control of resources if (isOlatAdmin || bgs.isIdentityInBusinessGroup(ureq.getIdentity(), bgroup) || isAccessControlled(bgroup)) { @@ -87,22 +86,22 @@ public class BusinessGroupContextEntryControllerCreator extends DefaultContextEn Long gKey = ores.getResourceableId(); BusinessGroupService bgs = CoreSpringFactory.getImpl(BusinessGroupService.class); BusinessGroup bgroup = bgs.loadBusinessGroup(gKey); - if (bgroup != null){ - return bgs.isIdentityInBusinessGroup(ureq.getIdentity(), bgroup) || isAccessControlled(bgroup); - } - return false; + if (bgroup == null) { + return false; + } + return ureq.getUserSession().getRoles().isOLATAdmin() || + ureq.getUserSession().getRoles().isGroupManager() || + bgs.isIdentityInBusinessGroup(ureq.getIdentity(), bgroup) || isAccessControlled(bgroup); } private boolean isAccessControlled(BusinessGroup bgroup) { AccessControlModule acModule = (AccessControlModule)CoreSpringFactory.getBean("acModule"); if(acModule.isEnabled()) { ACFrontendManager acFrontendManager = (ACFrontendManager)CoreSpringFactory.getBean("acFrontendManager"); - OLATResource resource = OLATResourceManager.getInstance().findResourceable(bgroup); - if(acFrontendManager.isResourceAccessControled(resource, new Date())) { + if(acFrontendManager.isResourceAccessControled(bgroup.getResource(), new Date())) { return true; } } return false; } - } diff --git a/src/main/java/org/olat/group/BusinessGroupImpl.hbm.xml b/src/main/java/org/olat/group/BusinessGroupImpl.hbm.xml index 7f8e5052eb8e20e5f250e814cedfc2756075dc52..5de4089fde7f0343b3e1dfe7d5d7f5c27880d365 100644 --- a/src/main/java/org/olat/group/BusinessGroupImpl.hbm.xml +++ b/src/main/java/org/olat/group/BusinessGroupImpl.hbm.xml @@ -38,19 +38,11 @@ <property name="autoCloseRanksEnabled" type="boolean" column="autocloseranks_enabled" unique="false" not-null="false"/> <property name="groupContextKey" type="long" column="groupcontext_fk" /> - - <!-- - <many-to-one - name="groupContext" - class="org.olat.group.context.BGContextImpl" - outer-join="true" - cascade="none"> - <column - name="groupcontext_fk" - not-null="false" - unique="false" /> + + <many-to-one name="resource" class="org.olat.resource.OLATResourceImpl" + outer-join="true" cascade="none" lazy="false"> + <column name="fk_resource" not-null="false" unique="true" /> </many-to-one> - --> <!-- Implementation Note: diff --git a/src/main/java/org/olat/group/BusinessGroupImpl.java b/src/main/java/org/olat/group/BusinessGroupImpl.java index 6cc5e5d7a3c98e6f2a0384c097232f086eb7a540..7877bb52259d90e87f97a978610a2d363009e188 100644 --- a/src/main/java/org/olat/group/BusinessGroupImpl.java +++ b/src/main/java/org/olat/group/BusinessGroupImpl.java @@ -33,6 +33,7 @@ import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.resource.OresHelper; +import org.olat.resource.OLATResource; /** * Description: <br> @@ -53,6 +54,7 @@ public class BusinessGroupImpl extends PersistentObject implements BusinessGroup private String type; private Integer minParticipants; private Integer maxParticipants; + private OLATResource resource; private SecurityGroup ownerGroup; private SecurityGroup partipiciantGroup; private SecurityGroup waitingGroup; @@ -99,14 +101,14 @@ public class BusinessGroupImpl extends PersistentObject implements BusinessGroup /** * @param partipiciantGroupP */ - private void setPartipiciantGroup(SecurityGroup partipiciantGroupP) { + public void setPartipiciantGroup(SecurityGroup partipiciantGroupP) { this.partipiciantGroup = partipiciantGroupP; } /** * @param ownerGroupP */ - private void setOwnerGroup(SecurityGroup ownerGroupP) { + public void setOwnerGroup(SecurityGroup ownerGroupP) { this.ownerGroup = ownerGroupP; } @@ -139,6 +141,14 @@ public class BusinessGroupImpl extends PersistentObject implements BusinessGroup return this.name; } + public OLATResource getResource() { + return resource; + } + + public void setResource(OLATResource resource) { + this.resource = resource; + } + /** * @see org.olat.group.BusinessGroup#getOwnerGroup() */ diff --git a/src/main/java/org/olat/group/BusinessGroupService.java b/src/main/java/org/olat/group/BusinessGroupService.java index 835786ae10562f8522ca94ea2c2e8829c4e2a88b..79985afe65c6eeeeffed0554d72b3531b7a8384e 100644 --- a/src/main/java/org/olat/group/BusinessGroupService.java +++ b/src/main/java/org/olat/group/BusinessGroupService.java @@ -33,6 +33,7 @@ import org.olat.core.util.mail.MailTemplate; import org.olat.core.util.mail.MailerResult; import org.olat.group.area.BGArea; import org.olat.group.model.AddToGroupsEvent; +import org.olat.group.model.BGRepositoryEntryRelation; import org.olat.group.model.DisplayMembers; import org.olat.group.model.SearchBusinessGroupParams; import org.olat.group.ui.BGConfigFlags; @@ -130,6 +131,8 @@ public interface BusinessGroupService { public List<RepositoryEntry> findRepositoryEntries(Collection<BusinessGroup> groups, int firstResult, int maxResults); + public List<BGRepositoryEntryRelation> findRelationToRepositoryEntries(Collection<BusinessGroup> groups, int firstResult, int maxResults); + public List<OLATResource> findResources(Collection<BusinessGroup> groups, int firstResult, int maxResults); @@ -181,6 +184,8 @@ public interface BusinessGroupService { //security public boolean isIdentityInBusinessGroup(Identity identity, BusinessGroup businessGroup); + + public List<Long> isIdentityInBusinessGroups(Identity identity, List<BusinessGroup> businessGroups); /** * * @param identity diff --git a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java index 85074f816695b764eba4703dd4ce425916c48590..51a5ffbdc5b8b795331ddbf2db483f0519ad5d56 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java @@ -19,6 +19,7 @@ */ package org.olat.group.manager; +import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Collections; @@ -105,6 +106,8 @@ public class BusinessGroupDAO { */ OLATResource businessgroupOlatResource = olatResourceManager.createOLATResourceInstance(businessgroup); olatResourceManager.saveOLATResource(businessgroupOlatResource); + businessgroup.setResource(businessgroupOlatResource); + em.merge(businessgroup); // securityManager.createAndPersistPolicy(ownerGroup, Constants.PERMISSION_ACCESS, businessgroup); securityManager.createAndPersistPolicyWithResource(ownerGroup, Constants.PERMISSION_ACCESS, businessgroupOlatResource); @@ -133,9 +136,10 @@ public class BusinessGroupDAO { } StringBuilder sb = new StringBuilder(); sb.append("select bgi from ").append(BusinessGroupImpl.class.getName()).append(" bgi ") - .append(" left join fetch bgi.ownerGroup ownerGroup") - .append(" left join fetch bgi.partipiciantGroup participantGroup") - .append(" left join fetch bgi.waitingGroup waitingGroup") + .append(" inner join fetch bgi.ownerGroup ownerGroup") + .append(" inner join fetch bgi.partipiciantGroup participantGroup") + .append(" inner join fetch bgi.waitingGroup waitingGroup") + .append(" inner join fetch bgi.resource resource") .append(" where bgi.key in (:ids)"); List<BusinessGroup> groups = dbInstance.getCurrentEntityManager() @@ -148,9 +152,10 @@ public class BusinessGroupDAO { public List<BusinessGroup> loadAll() { StringBuilder sb = new StringBuilder(); sb.append("select bgi from ").append(BusinessGroupImpl.class.getName()).append(" bgi ") - .append(" left join fetch bgi.ownerGroup ownerGroup") - .append(" left join fetch bgi.partipiciantGroup participantGroup") - .append(" left join fetch bgi.waitingGroup waitingGroup"); + .append(" inner join fetch bgi.ownerGroup ownerGroup") + .append(" inner join fetch bgi.partipiciantGroup participantGroup") + .append(" inner join fetch bgi.waitingGroup waitingGroup") + .append(" inner join fetch bgi.resource resource"); List<BusinessGroup> groups = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), BusinessGroup.class) @@ -256,6 +261,50 @@ public class BusinessGroupDAO { return group; } + + public List<Long> isIdentityInBusinessGroups(Identity identity, boolean owner, boolean attendee, List<BusinessGroup> groups) { + if(groups == null || groups.isEmpty() || (!owner && !attendee)) { + return Collections.emptyList(); + } + + StringBuilder sb = new StringBuilder(); + sb.append("select bgi.key from ").append(BusinessGroupImpl.class.getName()).append(" as bgi "); + if(owner && attendee) { + sb.append(" left join bgi.ownerGroup ownerGroup"); + sb.append(" left join bgi.partipiciantGroup participantGroup"); + } else if(owner) { + sb.append(" inner join bgi.ownerGroup ownerGroup"); + } else if(attendee) { + sb.append(" inner join bgi.partipiciantGroup participantGroup"); + } + sb.append(" where bgi.key in (:groupKeys) and ("); + + boolean or = false; + if(owner) { + or = or(sb, or); + sb.append("ownerGroup.key in (select ownerMemberShip.securityGroup.key from ").append(SecurityGroupMembershipImpl.class.getName()).append(" ownerMemberShip ") + .append(" where ownerMemberShip.identity.key=:identId ") + .append(")"); + } + if(attendee) { + or = or(sb, or); + sb.append(" participantGroup.key in (select partMembership.securityGroup.key from ").append(SecurityGroupMembershipImpl.class.getName()).append(" as partMembership ") + .append(" where partMembership.identity.key=:identId") + .append(" )"); + } + sb.append(")"); + + List<Long> groupKeys = new ArrayList<Long>(); + for(BusinessGroup group:groups) { + groupKeys.add(group.getKey()); + } + List<Long> res = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), Long.class) + .setParameter("groupKeys", groupKeys) + .setParameter("identId", identity.getKey()) + .getResultList(); + return res; + } + public BusinessGroup findBusinessGroup(SecurityGroup secGroup) { StringBuilder sb = new StringBuilder(); @@ -263,6 +312,7 @@ public class BusinessGroupDAO { .append(" left join fetch bgi.ownerGroup ownerGroup") .append(" left join fetch bgi.partipiciantGroup participantGroup") .append(" left join fetch bgi.waitingGroup waitingGroup") + .append(" inner join fetch bgi.resource resource") .append(" where (bgi.partipiciantGroup=:secGroup or bgi.ownerGroup=:secGroup or bgi.waitingGroup=:secGroup)"); List<BusinessGroup> res = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), BusinessGroup.class) @@ -278,15 +328,17 @@ public class BusinessGroupDAO { if(resource == null) { sb.append("select bgs from ").append(BusinessGroupImpl.class.getName()).append(" as bgs ") .append(" inner join fetch bgs.waitingGroup waitingList ") - .append(" left join fetch bgs.ownerGroup ownerGroup ") - .append(" left join fetch bgs.partipiciantGroup participantGroup ") + .append(" inner join fetch bgs.ownerGroup ownerGroup ") + .append(" inner join fetch bgs.partipiciantGroup participantGroup ") + .append(" inner join fetch bgs.resource bgResource") .append(" where "); } else { sb.append("select bgs from ").append(BGResourceRelation.class.getName()).append(" as rel ") .append(" inner join rel.group bgs ") .append(" inner join fetch bgs.waitingGroup waitingList ") - .append(" left join fetch bgs.ownerGroup ownerGroup ") - .append(" left join fetch bgs.partipiciantGroup participantGroup ") + .append(" inner join fetch bgs.ownerGroup ownerGroup ") + .append(" inner join fetch bgs.partipiciantGroup participantGroup ") + .append(" inner join fetch bgs.resource bgResource") .append(" where rel.resource.key=:resourceKey and "); } sb.append(" waitingList in (select memberShip.securityGroup from ").append(SecurityGroupMembershipImpl.class.getName()).append(" memberShip ") @@ -339,13 +391,14 @@ public class BusinessGroupDAO { } //inner joins if(BusinessGroup.class.equals(resultClass)) { - query.append("left join fetch bgi.ownerGroup ownerGroup "); - query.append("left join fetch bgi.partipiciantGroup participantGroup "); - query.append("left join fetch bgi.waitingGroup waitingGroup "); + query.append("inner join fetch bgi.ownerGroup ownerGroup ") + .append("inner join fetch bgi.partipiciantGroup participantGroup ") + .append("inner join fetch bgi.waitingGroup waitingGroup ") + .append("inner join fetch bgi.resource bgResource "); } else { - query.append("left join bgi.ownerGroup ownerGroup "); - query.append("left join bgi.partipiciantGroup participantGroup "); - query.append("left join bgi.waitingGroup waitingGroup "); + query.append("inner join bgi.ownerGroup ownerGroup "); + query.append("inner join bgi.partipiciantGroup participantGroup "); + query.append("inner join bgi.waitingGroup waitingGroup "); } boolean where = false; @@ -566,5 +619,9 @@ public class BusinessGroupDAO { } return true; } - + + private boolean or(StringBuilder sb, boolean or) { + if(or) sb.append(" or "); + return true; + } } diff --git a/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java index 4dc4e1ef1db58f142a170623d8301e040c4a9c2d..535af1a1e5edf6a5f58d0f0f34db525a4e08fb80 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupRelationDAO.java @@ -33,6 +33,7 @@ import org.olat.core.commons.persistence.DB; import org.olat.core.id.Identity; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupImpl; +import org.olat.group.model.BGRepositoryEntryRelation; import org.olat.group.model.BGResourceRelation; import org.olat.repository.RepositoryEntry; import org.olat.resource.OLATResource; @@ -201,7 +202,7 @@ public class BusinessGroupRelationDAO { public int countResources(BusinessGroup group) { if(group == null) return 0; StringBuilder sb = new StringBuilder(); - sb.append("select count(bgcr) from ").append(BGResourceRelation.class.getName()).append(" bgcr where bgcr.group.key=:groupKeys"); + sb.append("select count(bgcr) from ").append(BGResourceRelation.class.getName()).append(" bgcr where bgcr.group.key=:groupKey"); Number count = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), Number.class) .setParameter("groupKey", group.getKey()) @@ -259,4 +260,27 @@ public class BusinessGroupRelationDAO { query.setParameter("groupKeys", groupKeys); return query.getResultList(); } + + public List<BGRepositoryEntryRelation> findRelationToRepositoryEntries(Collection<BusinessGroup> groups, int firstResult, int maxResults) { + if(groups == null || groups.isEmpty()) { + return Collections.emptyList(); + } + + StringBuilder sb = new StringBuilder(); + sb.append("select rel from ").append(BGRepositoryEntryRelation.class.getName()).append(" as rel ") + .append(" where rel.groupKey in (:groupKeys)"); + + TypedQuery<BGRepositoryEntryRelation> query = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), BGRepositoryEntryRelation.class); + query.setFirstResult(firstResult); + if(maxResults > 0) { + query.setMaxResults(maxResults); + } + + List<Long> groupKeys = new ArrayList<Long>(); + for(BusinessGroup group:groups) { + groupKeys.add(group.getKey()); + } + query.setParameter("groupKeys", groupKeys); + return query.getResultList(); + } } diff --git a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java index f3c01c15e9459137e55522d18ecbd76a08293954..ef1a87c141e2e72349f027859b45b002284030a8 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java @@ -71,6 +71,7 @@ import org.olat.group.GroupLoggingAction; import org.olat.group.area.BGArea; import org.olat.group.area.BGAreaManager; import org.olat.group.model.AddToGroupsEvent; +import org.olat.group.model.BGRepositoryEntryRelation; import org.olat.group.model.DisplayMembers; import org.olat.group.model.SearchBusinessGroupParams; import org.olat.group.right.BGRightManager; @@ -1086,6 +1087,11 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { public List<RepositoryEntry> findRepositoryEntries(Collection<BusinessGroup> groups, int firstResult, int maxResults) { return businessGroupRelationDAO.findRepositoryEntries(groups, firstResult, maxResults); } + + @Override + public List<BGRepositoryEntryRelation> findRelationToRepositoryEntries(Collection<BusinessGroup> groups, int firstResult, int maxResults) { + return businessGroupRelationDAO.findRelationToRepositoryEntries(groups, firstResult, maxResults); + } @Override @Transactional(readOnly=true) @@ -1101,6 +1107,11 @@ public class BusinessGroupServiceImpl implements BusinessGroupService { return false; } + @Override + public List<Long> isIdentityInBusinessGroups(Identity identity, List<BusinessGroup> groups) { + return businessGroupDAO.isIdentityInBusinessGroups(identity, true, true, groups); + } + @Override @Transactional(readOnly=true) public boolean isIdentityInBusinessGroup(Identity identity, String groupName, diff --git a/src/main/java/org/olat/group/model/BGRepositoryEntryRelation.java b/src/main/java/org/olat/group/model/BGRepositoryEntryRelation.java new file mode 100644 index 0000000000000000000000000000000000000000..fc772feba4cc1126f790221e07bf19a5790a0ed4 --- /dev/null +++ b/src/main/java/org/olat/group/model/BGRepositoryEntryRelation.java @@ -0,0 +1,82 @@ +/** + * <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.io.Serializable; + +/** + * + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ +public class BGRepositoryEntryRelation implements Serializable { + + private static final long serialVersionUID = -589388325515371455L; + + private Long groupKey; + private Long repositoryEntryKey; + private String repositoryEntryDisplayName; + + public BGRepositoryEntryRelation() { + // + } + + public Long getGroupKey() { + return groupKey; + } + + public void setGroupKey(Long groupKey) { + this.groupKey = groupKey; + } + + public Long getRepositoryEntryKey() { + return repositoryEntryKey; + } + + public void setRepositoryEntryKey(Long repositoryEntryKey) { + this.repositoryEntryKey = repositoryEntryKey; + } + + public String getRepositoryEntryDisplayName() { + return repositoryEntryDisplayName; + } + + public void setRepositoryEntryDisplayName(String repositoryEntryDisplayName) { + this.repositoryEntryDisplayName = repositoryEntryDisplayName; + } + + @Override + public int hashCode() { + return (groupKey == null ? 8934 : groupKey.hashCode()) + + (repositoryEntryKey == null ? 8934 : repositoryEntryKey.hashCode()); + } + + @Override + public boolean equals(Object obj) { + if(this == obj) { + return true; + } + if(obj instanceof BGRepositoryEntryRelation) { + BGRepositoryEntryRelation rel = (BGRepositoryEntryRelation)obj; + return groupKey != null && groupKey.equals(rel.groupKey) + && repositoryEntryKey != null && repositoryEntryKey.equals(rel.repositoryEntryKey); + } + return false; + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/group/model/BGResourceRelation.hbm.xml b/src/main/java/org/olat/group/model/BGResourceRelation.hbm.xml index 0f48ca769a237daeb3c9bd010048eff9780bbae9..c8bfcb7290822453837d6d6f8dc93f833c2439e7 100644 --- a/src/main/java/org/olat/group/model/BGResourceRelation.hbm.xml +++ b/src/main/java/org/olat/group/model/BGResourceRelation.hbm.xml @@ -25,4 +25,13 @@ </many-to-one> </class> + + <class name="org.olat.group.model.BGRepositoryEntryRelation" table="o_gp_business_to_repository_v" mutable="false"> + <composite-id> + <key-property name="groupKey" column="grp_id" type="long" /> + <key-property name="repositoryEntryKey" column="re_id" type="long" /> + </composite-id> + <property name="repositoryEntryDisplayName" column="re_displayname" /> + </class> + </hibernate-mapping> \ No newline at end of file diff --git a/src/main/java/org/olat/group/ui/main/BGAccessControlledCellRenderer.java b/src/main/java/org/olat/group/ui/main/BGAccessControlledCellRenderer.java index f09675cc6276b18a313c9c23b2cce33692efdf97..2b4900308bbebc97ab4dbe5ecb6cb7f7ea4d9604 100644 --- a/src/main/java/org/olat/group/ui/main/BGAccessControlledCellRenderer.java +++ b/src/main/java/org/olat/group/ui/main/BGAccessControlledCellRenderer.java @@ -26,7 +26,6 @@ import java.util.Locale; import org.olat.core.gui.components.table.CustomCellRenderer; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; -import org.olat.resource.accesscontrol.model.OLATResourceAccess; import org.olat.resource.accesscontrol.model.Price; import org.olat.resource.accesscontrol.model.PriceMethodBundle; import org.olat.resource.accesscontrol.ui.PriceFormat; diff --git a/src/main/java/org/olat/group/ui/main/BGMainController.java b/src/main/java/org/olat/group/ui/main/BGMainController.java index 9f6eb205a3c1cb4102023f1352953da761e7a705..d4aae9bd7b04ea1797c6d7192463d207a7f9df75 100644 --- a/src/main/java/org/olat/group/ui/main/BGMainController.java +++ b/src/main/java/org/olat/group/ui/main/BGMainController.java @@ -161,6 +161,7 @@ public class BGMainController extends MainLayoutBasicController implements Activ private Link searchOpenLink; private SegmentViewComponent segmentView; private BGSearchController searchController; + private BusinessGroupListController groupsCtr; // group list table rows private static final String TABLE_ACTION_LEAVE = "bgTblLeave"; @@ -169,6 +170,7 @@ public class BGMainController extends MainLayoutBasicController implements Activ //fxdiff VCRP-1,2: access control of resources private static final String TABLE_ACTION_ACCESS = "bgTblAccess"; private static final String CMD_MENU_INDEX = "cmd.menu.index"; + private static final String CMD_MENU_LIST = "cmd.menu.list"; //fxdiff VCRP-1,2: access control of resources private static final String CMD_MENU_OPEN = "cmd.menu.open"; private static final String CMD_MENU_OPEN_SEARCH = "cmd.menu.open.search"; @@ -282,6 +284,8 @@ public class BGMainController extends MainLayoutBasicController implements Activ doOpenGroupList(ureq, getWindowControl()); } else if (userObject.equals(CMD_MENU_OPEN_SEARCH)) { doSearchOpenGroupList(ureq, getWindowControl()); + } else if (userObject.equals(CMD_MENU_LIST)) { + doList(ureq, getWindowControl()); } } @@ -525,6 +529,16 @@ public class BGMainController extends MainLayoutBasicController implements Activ ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_CREATED, getClass()); return newGroup; } + + private void doList(UserRequest ureq, WindowControl wControl) { + if(groupsCtr == null) { + groupsCtr = new BusinessGroupListController(ureq, wControl); + listenTo(groupsCtr); + } + + columnLayoutCtr.setCol3(groupsCtr.getInitialComponent()); + columnLayoutCtr.hideCol2(false); + } /** * Prepare everything and show all groups @@ -540,6 +554,7 @@ public class BGMainController extends MainLayoutBasicController implements Activ // 3) set correct page main.setPage(Util.getPackageVelocityRoot(this.getClass()) + "/index.html"); // 4) update toolboxe + columnLayoutCtr.setCol3(main); columnLayoutCtr.hideCol2(false); //fxdiff BAKS-7 Resume function OLATResourceable ores = OresHelper.createOLATResourceableInstance(CMD_MENU_INDEX, 0l); @@ -570,6 +585,7 @@ public class BGMainController extends MainLayoutBasicController implements Activ } // 4) update toolboxe + columnLayoutCtr.setCol3(main); columnLayoutCtr.hideCol2(true); //fxdiff BAKS-7 Resume function OLATResourceable ores = OresHelper.createOLATResourceableInstance(CMD_MENU_OPEN, 0l); @@ -598,6 +614,7 @@ public class BGMainController extends MainLayoutBasicController implements Activ } // 4) update toolboxe + columnLayoutCtr.setCol3(main); columnLayoutCtr.hideCol2(true); //fxdiff BAKS-7 Resume function @@ -719,7 +736,7 @@ public class BGMainController extends MainLayoutBasicController implements Activ for(BusinessGroup group:groups) { OLATResource ores = OLATResourceManager.getInstance().findResourceable(group); resourceKeys.put(group.getKey(), ores.getKey()); - if(businessGroupService.isIdentityInBusinessGroup(this.getIdentity(), group)) { + if(businessGroupService.isIdentityInBusinessGroup(getIdentity(), group)) { membership.add(group.getKey()); } } @@ -778,7 +795,12 @@ public class BGMainController extends MainLayoutBasicController implements Activ myEntriesTn.setUserObject(CMD_MENU_INDEX); myEntriesTn.setAltText(translate("menu.learninggroups.alt")); rootNode.addChild(myEntriesTn); - rootNode.setDelegate(myEntriesTn); + + GenericTreeNode listEntriesTn = new GenericTreeNode(); + listEntriesTn.setTitle(translate("menu.groups")); + listEntriesTn.setUserObject(CMD_MENU_LIST); + listEntriesTn.setAltText(translate("menu.groups.alt")); + rootNode.addChild(listEntriesTn); //fxdiff VCRP-1,2: access control of resources myEntriesTn = new GenericTreeNode(); diff --git a/src/main/java/org/olat/group/ui/main/BGResourcesCellRenderer.java b/src/main/java/org/olat/group/ui/main/BGResourcesCellRenderer.java index 2949d4d2c464cd70a132c8f5ec25f7a8c84d1689..ef5135de669dbc3efa302849bcbfed0b18b8e6c1 100644 --- a/src/main/java/org/olat/group/ui/main/BGResourcesCellRenderer.java +++ b/src/main/java/org/olat/group/ui/main/BGResourcesCellRenderer.java @@ -27,11 +27,13 @@ import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.link.LinkFactory; import org.olat.core.gui.components.table.CustomCellRenderer; import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.Controller; import org.olat.core.gui.render.RenderResult; import org.olat.core.gui.render.Renderer; import org.olat.core.gui.render.StringOutput; import org.olat.core.gui.render.URLBuilder; import org.olat.core.gui.translator.Translator; +import org.olat.group.model.BGRepositoryEntryRelation; import org.olat.repository.RepositoryEntry; /** @@ -47,9 +49,9 @@ public class BGResourcesCellRenderer implements CustomCellRenderer { private final Translator translator; private VelocityContainer container; - private final BGMainController listeningController; + private final Controller listeningController; - public BGResourcesCellRenderer(BGMainController listeningController, VelocityContainer container, Translator translator) { + public BGResourcesCellRenderer(Controller listeningController, VelocityContainer container, Translator translator) { this.listeningController = listeningController; this.container = container; this.translator = translator; @@ -60,35 +62,62 @@ public class BGResourcesCellRenderer implements CustomCellRenderer { if(val instanceof BGTableItem) { BGTableItem item = (BGTableItem)val; List<RepositoryEntry> resources = item.getResources(); - if(resources == null || resources.isEmpty()) { - return; - } - - int count = 0; - for(RepositoryEntry resource:resources) { - if(renderer == null) {//fxdiff: FXOLAT-267 for XSL export - if(sb.length() > 0) { - sb.append(", "); + if(resources != null && !resources.isEmpty()) { + int count = 0; + for(RepositoryEntry resource:resources) { + if(renderer == null) {//fxdiff: FXOLAT-267 for XSL export + if(sb.length() > 0) { + sb.append(", "); + } + sb.append(resource.getDisplayname()); + } else if(count >= 2) { + Link link = LinkFactory.createLink("repo_entry_" + UUID.randomUUID().toString(), container, listeningController); + link.setCustomDisplayText("..."); + link.setUserObject(item.getBusinessGroup()); + + URLBuilder ubu = renderer.getUrlBuilder().createCopyFor(link); + RenderResult renderResult = new RenderResult(); + link.getHTMLRendererSingleton().render(renderer, sb, link, ubu, translator, renderResult, null); + break; + } else { + Link link = LinkFactory.createLink("repo_entry_" + UUID.randomUUID().toString(), container, listeningController); + link.setCustomDisplayText(resource.getDisplayname()); + link.setUserObject(resource.getKey()); + + URLBuilder ubu = renderer.getUrlBuilder().createCopyFor(link); + RenderResult renderResult = new RenderResult(); + link.getHTMLRendererSingleton().render(renderer, sb, link, ubu, translator, renderResult, null); + count++; + } + } + } else if (item.getRelations() != null && !item.getRelations().isEmpty()) { + List<BGRepositoryEntryRelation> relations = item.getRelations(); + int count = 0; + for(BGRepositoryEntryRelation relation:relations) { + if(renderer == null) {//fxdiff: FXOLAT-267 for XSL export + if(sb.length() > 0) { + sb.append(", "); + } + sb.append(relation.getRepositoryEntryDisplayName()); + } else if(count >= 2) { + Link link = LinkFactory.createLink("repo_entry_" + UUID.randomUUID().toString(), container, listeningController); + link.setCustomDisplayText("..."); + link.setUserObject(item.getBusinessGroup()); + + URLBuilder ubu = renderer.getUrlBuilder().createCopyFor(link); + RenderResult renderResult = new RenderResult(); + link.getHTMLRendererSingleton().render(renderer, sb, link, ubu, translator, renderResult, null); + break; + } else { + Link link = LinkFactory.createLink("repo_entry_" + UUID.randomUUID().toString(), container, listeningController); + link.setCustomDisplayText(relation.getRepositoryEntryDisplayName()); + link.setUserObject(relation.getRepositoryEntryKey()); + + URLBuilder ubu = renderer.getUrlBuilder().createCopyFor(link); + RenderResult renderResult = new RenderResult(); + link.getHTMLRendererSingleton().render(renderer, sb, link, ubu, translator, renderResult, null); + count++; } - sb.append(resource.getDisplayname()); - } else if(count >= 2) { - Link link = LinkFactory.createLink("repo_entry_" + UUID.randomUUID().toString(), container, listeningController); - link.setCustomDisplayText("..."); - link.setUserObject(item.getBusinessGroup()); - - URLBuilder ubu = renderer.getUrlBuilder().createCopyFor(link); - RenderResult renderResult = new RenderResult(); - link.getHTMLRendererSingleton().render(renderer, sb, link, ubu, translator, renderResult, null); - break; - } else { - Link link = LinkFactory.createLink("repo_entry_" + UUID.randomUUID().toString(), container, listeningController); - link.setCustomDisplayText(resource.getDisplayname()); - link.setUserObject(resource.getKey()); - - URLBuilder ubu = renderer.getUrlBuilder().createCopyFor(link); - RenderResult renderResult = new RenderResult(); - link.getHTMLRendererSingleton().render(renderer, sb, link, ubu, translator, renderResult, null); - count++; } } } diff --git a/src/main/java/org/olat/group/ui/main/BGSearchController.java b/src/main/java/org/olat/group/ui/main/BGSearchController.java index c62a4862db907a1910c869961701acca2befeaad..5a6060ac450acb9315115d3a1a744fe6e23ba91e 100644 --- a/src/main/java/org/olat/group/ui/main/BGSearchController.java +++ b/src/main/java/org/olat/group/ui/main/BGSearchController.java @@ -24,6 +24,7 @@ import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FormLink; +import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; import org.olat.core.gui.components.form.flexible.elements.TextElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormEvent; @@ -50,6 +51,9 @@ public class BGSearchController extends FormBasicController{ private TextElement owner; private TextElement description; private FormLink searchButton; + private MultipleSelectionElement attendeeEl; + private MultipleSelectionElement ownerEl; + private MultipleSelectionElement waitingEl; private String limitUsername; private boolean isAdmin; @@ -68,24 +72,49 @@ public class BGSearchController extends FormBasicController{ initForm(ureq); } + public BGSearchController(UserRequest ureq, WindowControl wControl, boolean isAdmin, boolean extended) { + super(ureq, wControl, "group_search"); + this.isAdmin = isAdmin; + initForm(ureq); + } + @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - displayName = uifactory.addTextElement("cif_displayname", "cif.displayname", 255, "", formLayout); + FormLayoutContainer leftContainer = FormLayoutContainer.createDefaultFormLayout("left_1", getTranslator()); + leftContainer.setRootForm(mainForm); + formLayout.add(leftContainer); + + displayName = uifactory.addTextElement("cif_displayname", "cif.displayname", 255, "", leftContainer); displayName.setFocus(true); - owner = uifactory.addTextElement("cif_owner", "cif.owner", 255, "", formLayout); + owner = uifactory.addTextElement("cif_owner", "cif.owner", 255, "", leftContainer); if (limitUsername != null) { owner.setValue(limitUsername); owner.setEnabled(false); } - description = uifactory.addTextElement("cif_description", "cif.description", 255, "", formLayout); + description = uifactory.addTextElement("cif_description", "cif.description", 255, "", leftContainer); if(isAdmin) { - id = uifactory.addTextElement("cif_id", "cif.id", 12, "", formLayout); + id = uifactory.addTextElement("cif_id", "cif.id", 12, "", leftContainer); id.setVisible(isAdmin); id.setRegexMatchCheck("\\d*", "search.id.format"); } + FormLayoutContainer rightContainer = FormLayoutContainer.createDefaultFormLayout("right_1", getTranslator()); + rightContainer.setRootForm(mainForm); + formLayout.add(rightContainer); + + String[] ownerValues = new String[]{ translate("search.owner") }; + ownerEl = uifactory.addCheckboxesVertical("search.owner", rightContainer, new String[]{"owner"}, ownerValues, null, 1); + + String[] attendeeValues = new String[]{ translate("search.attendee") }; + attendeeEl = uifactory.addCheckboxesVertical("search.attendee", rightContainer, new String[]{"attendee"}, attendeeValues, null, 1); + + String[] waitingValues = new String[]{ translate("search.waiting") }; + waitingEl = uifactory.addCheckboxesVertical("search.waiting", rightContainer, new String[]{"waiting"}, waitingValues, null, 1); + + + FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("button_layout", getTranslator()); formLayout.add(buttonLayout); searchButton = uifactory.addFormLink("search", buttonLayout, Link.BUTTON); @@ -101,7 +130,12 @@ public class BGSearchController extends FormBasicController{ */ public Long getId() { if (id != null && !id.isEmpty()) { - return new Long(id.getValue()); + try { + return new Long(id.getValue()); + } catch (NumberFormatException e) { + id.setValue(""); + return null; + } } return null; } @@ -161,7 +195,16 @@ public class BGSearchController extends FormBasicController{ @Override protected void formInnerEvent (UserRequest ureq, FormItem source, FormEvent event) { if (source == searchButton) { - fireEvent (ureq, Event.DONE_EVENT); + SearchEvent e = new SearchEvent(); + e.setId(getId()); + e.setName(getName()); + e.setDescription(getDescription()); + e.setOwnerName(getOwner()); + e.setOwner(ownerEl.isAtLeastSelected(1)); + e.setAttendee(attendeeEl.isAtLeastSelected(1)); + e.setWaiting(waitingEl.isAtLeastSelected(1)); + fireEvent(ureq, e); + fireEvent(ureq, Event.DONE_EVENT); } } } \ No newline at end of file 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 ba08b7c66abdfa30d059762a640a4cb85a0b86e2..dd767dfcb8e3b05d934cbce2140514ed6de1f99b 100644 --- a/src/main/java/org/olat/group/ui/main/BGTableItem.java +++ b/src/main/java/org/olat/group/ui/main/BGTableItem.java @@ -19,12 +19,11 @@ */ package org.olat.group.ui.main; -import java.util.ArrayList; import java.util.List; import org.olat.group.BusinessGroup; +import org.olat.group.model.BGRepositoryEntryRelation; import org.olat.repository.RepositoryEntry; -import org.olat.resource.accesscontrol.model.OLATResourceAccess; import org.olat.resource.accesscontrol.model.PriceMethodBundle; /** @@ -43,6 +42,7 @@ public class BGTableItem { private final Boolean allowDelete; private final BusinessGroup businessGroup; private List<RepositoryEntry> resources; + private List<BGRepositoryEntryRelation> relations; private List<PriceMethodBundle> access; public BGTableItem(BusinessGroup businessGroup, boolean member, Boolean allowLeave, Boolean allowDelete, @@ -92,6 +92,14 @@ public class BGTableItem { this.resources = resources; } + public List<BGRepositoryEntryRelation> getRelations() { + return relations; + } + + public void setRelations(List<BGRepositoryEntryRelation> relations) { + this.relations = relations; + } + @Override public int hashCode() { return businessGroup.getKey().hashCode(); diff --git a/src/main/java/org/olat/group/ui/main/BusinessGroupListController.java b/src/main/java/org/olat/group/ui/main/BusinessGroupListController.java new file mode 100644 index 0000000000000000000000000000000000000000..cc5e219c409012f9d7274279ce7a999aa4abf12f --- /dev/null +++ b/src/main/java/org/olat/group/ui/main/BusinessGroupListController.java @@ -0,0 +1,301 @@ +package org.olat.group.ui.main; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.olat.NewControllerFactory; +import org.olat.basesecurity.BaseSecurity; +import org.olat.core.CoreSpringFactory; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.components.table.BooleanColumnDescriptor; +import org.olat.core.gui.components.table.ColumnDescriptor; +import org.olat.core.gui.components.table.CustomCellRenderer; +import org.olat.core.gui.components.table.CustomRenderColumnDescriptor; +import org.olat.core.gui.components.table.DefaultColumnDescriptor; +import org.olat.core.gui.components.table.Table; +import org.olat.core.gui.components.table.TableController; +import org.olat.core.gui.components.table.TableEvent; +import org.olat.core.gui.components.table.TableGuiConfiguration; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.controller.BasicController; +import org.olat.core.gui.control.generic.modal.DialogBoxController; +import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; +import org.olat.core.id.Identity; +import org.olat.core.id.context.BusinessControl; +import org.olat.core.id.context.BusinessControlFactory; +import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; +import org.olat.core.util.StringHelper; +import org.olat.group.BusinessGroup; +import org.olat.group.BusinessGroupService; +import org.olat.group.GroupLoggingAction; +import org.olat.group.model.BGRepositoryEntryRelation; +import org.olat.group.model.SearchBusinessGroupParams; +import org.olat.group.ui.BGConfigFlags; +import org.olat.resource.accesscontrol.manager.ACFrontendManager; +import org.olat.resource.accesscontrol.model.OLATResourceAccess; +import org.olat.resource.accesscontrol.model.PriceMethodBundle; +import org.olat.util.logging.activity.LoggingResourceable; + +/** + * + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ +public class BusinessGroupListController extends BasicController { + private static final String TABLE_ACTION_LEAVE = "bgTblLeave"; + private static final String TABLE_ACTION_DELETE = "bgTblDelete"; + private static final String TABLE_ACTION_LAUNCH = "bgTblLaunch"; + private static final String TABLE_ACTION_ACCESS = "bgTblAccess"; + + private final VelocityContainer mainVC; + private final TableController groupListCtr; + private final BGSearchController searchController; + private BusinessGroupTableModelWithType groupListModel; + + private DialogBoxController deleteDialogBox; + private DialogBoxController sendEMailOnDeleteDialogBox; + private DialogBoxController leaveDialogBox; + + private final boolean admin; + private final BaseSecurity securityManager; + private final ACFrontendManager acFrontendManager; + private final BusinessGroupService businessGroupService; + + public BusinessGroupListController(UserRequest ureq, WindowControl wControl) { + super(ureq, wControl); + + admin = ureq.getUserSession().getRoles().isOLATAdmin() || ureq.getUserSession().getRoles().isGroupManager(); + businessGroupService = CoreSpringFactory.getImpl(BusinessGroupService.class); + acFrontendManager = CoreSpringFactory.getImpl(ACFrontendManager.class); + securityManager = CoreSpringFactory.getImpl(BaseSecurity.class); + + mainVC = createVelocityContainer("group_list"); + //search controller + searchController = new BGSearchController(ureq, wControl, admin, true); + listenTo(searchController); + + //table + TableGuiConfiguration tableConfig = new TableGuiConfiguration(); + tableConfig.setPreferencesOffered(true, "group.list"); + tableConfig.setTableEmptyMessage(translate("open.nogroup")); + groupListCtr = new TableController(tableConfig, ureq, getWindowControl(), getTranslator(), false); + listenTo(groupListCtr); + + CustomCellRenderer acRenderer = new BGAccessControlledCellRenderer(); + groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor("table.header.ac", 8, null, getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, acRenderer)); + groupListCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.bgname", 0, TABLE_ACTION_LAUNCH, getLocale())); + groupListCtr.addColumnDescriptor(false, new DefaultColumnDescriptor("table.header.description", 1, null, getLocale())); + CustomCellRenderer resourcesRenderer = new BGResourcesCellRenderer(this, mainVC, getTranslator()); + groupListCtr.addColumnDescriptor(false, new CustomRenderColumnDescriptor("table.header.resources", 5, null, getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, resourcesRenderer)); + groupListCtr.addColumnDescriptor(false, new BooleanColumnDescriptor("table.header.leave", 3, TABLE_ACTION_LEAVE, translate("table.header.leave"), null)); + if(admin) { + groupListCtr.addColumnDescriptor(false, new BooleanColumnDescriptor("table.header.delete", 4, TABLE_ACTION_DELETE, translate("table.header.delete"), null)); + } + groupListCtr.addColumnDescriptor(false, new DefaultColumnDescriptor("table.header.ac", 7, TABLE_ACTION_ACCESS, getLocale())); + + groupListModel = new BusinessGroupTableModelWithType(new ArrayList<BGTableItem>(), getTranslator(), 7); + groupListCtr.setTableDataModel(groupListModel); + + mainVC.put("searchPanel", searchController.getInitialComponent()); + mainVC.put("groupList", groupListCtr.getInitialComponent()); + putInitialPanel(mainVC); + } + + @Override + protected void doDispose() { + // + } + + @Override + protected void event(UserRequest ureq, Component source, Event event) { + if (source instanceof Link && source.getComponentName().startsWith("repo_entry_")) { + Object uobj = ((Link)source).getUserObject(); + if (uobj instanceof Long) { + Long repoEntryKey = (Long)((Link)source).getUserObject(); + BusinessControl bc = BusinessControlFactory.getInstance().createFromString("[RepositoryEntry:" + repoEntryKey + "]"); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); + NewControllerFactory.getInstance().launch(ureq, bwControl); + } else if(uobj instanceof BusinessGroup) { + BusinessGroup bg = (BusinessGroup)uobj; + BusinessControl bc = BusinessControlFactory.getInstance().createFromString("[BusinessGroup:" + bg.getKey() + "][toolresources:0]"); + WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); + NewControllerFactory.getInstance().launch(ureq, bwControl); + } + } + } + + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if(source == searchController) { + if(event instanceof SearchEvent) { + doSearch((SearchEvent)event); + } + } else if (source == groupListCtr) { + if (event.getCommand().equals(Table.COMMANDLINK_ROWACTION_CLICKED)) { + TableEvent te = (TableEvent) event; + String actionid = te.getActionId(); + + BusinessGroup businessGroup = groupListModel.getObject(te.getRowId()).getBusinessGroup(); + businessGroup = businessGroupService.loadBusinessGroup(businessGroup); + //prevent rs after a group is deleted by someone else + if(businessGroup == null) { + groupListModel.removeBusinessGroup(businessGroup); + groupListCtr.modelChanged(); + } else if(actionid.equals(TABLE_ACTION_LAUNCH)) { + String businessPath = "[BusinessGroup:" + businessGroup.getKey() + "]"; + NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl()); + } else if (actionid.equals(TABLE_ACTION_DELETE)) { + deleteDialogBox = activateYesNoDialog(ureq, null, translate("dialog.modal.bg.delete.text", businessGroup.getName()), deleteDialogBox); + deleteDialogBox.setUserObject(businessGroup); + } else if(actionid.equals(TABLE_ACTION_LEAVE)) { + leaveDialogBox = activateYesNoDialog(ureq, null, translate("dialog.modal.bg.leave.text", businessGroup.getName()), leaveDialogBox); + leaveDialogBox.setUserObject(businessGroup); + } else if (actionid.equals(TABLE_ACTION_ACCESS)) { + //handleAccess(ureq); + } + } + } else if (source == deleteDialogBox) { + if (DialogBoxUIFactory.isOkEvent(event)) { + sendEMailOnDeleteDialogBox = activateYesNoDialog(ureq, null, translate("dialog.modal.bg.mail.text"), sendEMailOnDeleteDialogBox); + sendEMailOnDeleteDialogBox.setUserObject(deleteDialogBox.getUserObject()); + }//else cancel was clicked or box closed + } else if(source == sendEMailOnDeleteDialogBox){ + boolean withEmail = DialogBoxUIFactory.isOkEvent(event); + doGroupDelete(ureq, withEmail, (BusinessGroup)sendEMailOnDeleteDialogBox.getUserObject()); + } else if (source == leaveDialogBox) { + if (event != Event.CANCELLED_EVENT && DialogBoxUIFactory.isYesEvent(event)) { + doGroupLeave(ureq, (BusinessGroup)leaveDialogBox.getUserObject()); + } + } + super.event(ureq, source, event); + } + + /** + * Removes user from the group as owner and participant. If + * no other owner are found the user won't be removed from the owner group + * + * @param ureq + */ + private void doGroupLeave(UserRequest ureq, BusinessGroup group) { + BGConfigFlags flags = BGConfigFlags.createGroupDefaultFlags(); + // 1) remove as owner + if (securityManager.isIdentityInSecurityGroup(getIdentity(), group.getOwnerGroup())) { + List<Identity> ownerList = securityManager.getIdentitiesOfSecurityGroup(group.getOwnerGroup()); + if (ownerList.size() > 1) { + businessGroupService.removeOwners(ureq.getIdentity(), Collections.singletonList(getIdentity()), group, flags); + } else { + // he is the last owner, but there must be at least one oner + // give him a warning, as long as he tries to leave, he gets + // this warning. + getWindowControl().setError(translate("msg.atleastone")); + return; + } + } + // if identity was also owner it must have successfully removed to end here. + // now remove the identity also as participant. + // 2) remove as participant + List<Identity> identities = Collections.singletonList(getIdentity()); + businessGroupService.removeParticipants(ureq.getIdentity(), identities, group, flags); + } + + /** + * Deletes the group. Checks if user is in owner group, + * otherwhise does nothing + * + * @param ureq + * @param doSendMail specifies if notification mails should be sent to users of delted group + */ + private void doGroupDelete(UserRequest ureq, boolean doSendMail, BusinessGroup group) { + // 1) send notification mails to users + boolean ow = securityManager.isIdentityInSecurityGroup(getIdentity(), group.getOwnerGroup()); + // check if user is in owner group (could fake link in table) + if (!admin && !ow) { + logWarn("User tried to delete a group but he was not owner of the group", null); + return; + } + + if (doSendMail) { + String businessPath = getWindowControl().getBusinessControl().getAsString(); + businessGroupService.deleteBusinessGroupWithMail(group, businessPath, getIdentity(), getLocale()); + } else { + businessGroupService.deleteBusinessGroup(group); + } + // do Logging + ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_DELETED, getClass(), LoggingResourceable.wrap(group)); + // 4) update Tables + showInfo("info.group.deleted"); + } + + private void doSearch(SearchEvent event) { + List<BGTableItem> items = search(event); + groupListModel.setEntries(items); + groupListCtr.modelChanged(); + } + + private List<BGTableItem> search(SearchEvent event) { + Long id = event.getId(); + String name = event.getName(); + String description = event.getDescription(); + String owner = event.getOwnerName(); + + SearchBusinessGroupParams params = new SearchBusinessGroupParams(); + params.setKey(id); + params.setName(StringHelper.containsNonWhitespace(name) ? name : null); + params.setDescription(StringHelper.containsNonWhitespace(description) ? description : null); + params.setOwner(StringHelper.containsNonWhitespace(owner) ? owner : null); + + Identity me = null; + if(event.isAttendee() || event.isOwner()) { + me = getIdentity(); + } + List<BusinessGroup> groups = businessGroupService.findBusinessGroups(params, me, event.isOwner(), event.isAttendee(), null, 0, -1); + + List<Long> groupsWithMembership = businessGroupService.isIdentityInBusinessGroups(getIdentity(), groups); + Set<Long> memberships = new HashSet<Long>(groupsWithMembership); + + List<Long> resourceKeys = new ArrayList<Long>(); + for(BusinessGroup group:groups) { + resourceKeys.add(group.getResource().getKey()); + } + List<BGRepositoryEntryRelation> resources = businessGroupService.findRelationToRepositoryEntries(groups, 0, -1); + List<OLATResourceAccess> resourcesWithAC = acFrontendManager.getAccessMethodForResources(resourceKeys, true, new Date()); + + List<BGTableItem> items = new ArrayList<BGTableItem>(); + for(BusinessGroup group:groups) { + Long oresKey = group.getResource().getKey(); + List<PriceMethodBundle> accessMethods = null; + for(OLATResourceAccess access:resourcesWithAC) { + if(oresKey.equals(access.getResource().getKey())){ + accessMethods = access.getMethods(); + break; + } + } + + Boolean allowLeave = memberships.contains(group.getKey()) ? Boolean.TRUE : null; + Boolean allowDelete = admin ? Boolean.TRUE : null; + boolean accessControl = (accessMethods != null); + boolean member = memberships.contains(group.getKey()); + List<BGRepositoryEntryRelation> relations = new ArrayList<BGRepositoryEntryRelation>(); + for(BGRepositoryEntryRelation resource:resources) { + if(group.getKey().equals(resource.getGroupKey())) { + relations.add(resource); + if(relations.size() >= 3) { + break; + } + } + } + BGTableItem tableItem = new BGTableItem(group, member, allowLeave, allowDelete, accessControl, accessMethods); + tableItem.setRelations(relations); + items.add(tableItem); + } + return items; + } +} diff --git a/src/main/java/org/olat/group/ui/main/BusinessGroupTableModelWithType.java b/src/main/java/org/olat/group/ui/main/BusinessGroupTableModelWithType.java index c2aa075ae9a1e68c1ea44b425b1d99d7951a2366..eb98612664e3ca250f81943bff1d5e15fe3b7474 100644 --- a/src/main/java/org/olat/group/ui/main/BusinessGroupTableModelWithType.java +++ b/src/main/java/org/olat/group/ui/main/BusinessGroupTableModelWithType.java @@ -30,7 +30,6 @@ import java.util.List; import org.apache.commons.lang.StringEscapeUtils; import org.olat.core.gui.components.table.DefaultTableDataModel; -import org.olat.core.gui.components.table.TableDataModel; import org.olat.core.gui.translator.Translator; import org.olat.core.util.Formatter; import org.olat.core.util.filter.FilterFactory; @@ -39,7 +38,7 @@ import org.olat.group.BusinessGroup; /** * @author gnaegi */ -public class BusinessGroupTableModelWithType extends DefaultTableDataModel implements TableDataModel { +public class BusinessGroupTableModelWithType extends DefaultTableDataModel<BGTableItem> { private final int columnCount; private Translator trans; @@ -88,11 +87,13 @@ public class BusinessGroupTableModelWithType extends DefaultTableDataModel imple case 6: return new Boolean(wrapped.isAccessControl()); case 7: - if(wrapped.isMember()) return trans.translate("select"); - return trans.translate("table.access"); + if(wrapped.isAccessControl()) { + if(wrapped.isMember()) return trans.translate("select"); + return trans.translate("table.access"); + } + return null; case 8: return wrapped.getAccessTypes(); - default: return "ERROR"; } diff --git a/src/main/java/org/olat/group/ui/main/SearchEvent.java b/src/main/java/org/olat/group/ui/main/SearchEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..905bc602d971d104d86c67355a75d301b502a0e7 --- /dev/null +++ b/src/main/java/org/olat/group/ui/main/SearchEvent.java @@ -0,0 +1,82 @@ +package org.olat.group.ui.main; + +import org.olat.core.gui.control.Event; + +/** + * + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ +public class SearchEvent extends Event { + + private static final long serialVersionUID = 6630250536374073143L; + + private Long id; + private String name; + private String description; + private String ownerName; + private boolean owner; + private boolean attendee; + private boolean waiting; + + public SearchEvent() { + super("search"); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getOwnerName() { + return ownerName; + } + + public void setOwnerName(String owner) { + this.ownerName = owner; + } + + public boolean isOwner() { + return owner; + } + + public void setOwner(boolean owner) { + this.owner = owner; + } + + public boolean isAttendee() { + return attendee; + } + + public void setAttendee(boolean attendee) { + this.attendee = attendee; + } + + public boolean isWaiting() { + return waiting; + } + + public void setWaiting(boolean waiting) { + this.waiting = waiting; + } + + +} diff --git a/src/main/java/org/olat/group/ui/main/_content/group_list.html b/src/main/java/org/olat/group/ui/main/_content/group_list.html new file mode 100644 index 0000000000000000000000000000000000000000..8cefec8737fe767e476eb21b64c3bc5f7c262ebd --- /dev/null +++ b/src/main/java/org/olat/group/ui/main/_content/group_list.html @@ -0,0 +1,6 @@ +<h4 class="b_with_small_icon_left b_group_icon"> + $r.translate("index.header") +</h4> +$r.render("searchPanel") +<p /> +$r.render("groupList") diff --git a/src/main/java/org/olat/group/ui/main/_content/group_search.html b/src/main/java/org/olat/group/ui/main/_content/group_search.html new file mode 100644 index 0000000000000000000000000000000000000000..970e9bd7ff1b36eb17a044ef12dd3e2d4c3f5a39 --- /dev/null +++ b/src/main/java/org/olat/group/ui/main/_content/group_search.html @@ -0,0 +1,13 @@ +<div class="b_clearfix"> + <div class="b_c50l"> + <div class="b_subcl"> + $r.render("left_1") + $r.render("button_layout") + </div> + </div> + <div class="b_c50r"> + <div class="b_subcr"> + $r.render("right_1") + </div> + </div> +</div> \ No newline at end of file diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties index cf8ffe603a37aa58fe847b0f2707c6c9f6b641e0..b4cc5dba783dec8ad1e3f535401374758d90b058 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties @@ -17,6 +17,8 @@ menu.index=Gruppen menu.index.alt=Arbeiten Sie mit Ihren Gruppen menu.learninggroups=Meine Lerngruppen menu.learninggroups.alt=Arbeiten Sie mit Ihren Lerngruppen +menu.groups=Gruppen +menu.groups.alt=Arbeiten Sie mit Ihen Gruppen menu.rightgroups=Meine Rechtegruppen menu.rightgroups.alt=Arbeiten Sie mit Ihren Rechtegruppen menu.opengroups=Ver\u00F6ffentlichte Gruppen @@ -32,6 +34,10 @@ opengroups.search=Suchmaske search.header=Gruppe search.intro=In Gruppe suchen search.generic=Suchmaske +search.attendee=Attendee +search.owner=Owner +search.waiting=Waiting + cif.displayname=Name cif.description=Beschreibung cif.owner=Besitzer diff --git a/src/main/java/org/olat/repository/RepositoryManager.java b/src/main/java/org/olat/repository/RepositoryManager.java index f0d1ba57b1d50d721979cf36fd68bd3add8ba342..4550387b63977e87fb827f611d1401e8558a57a8 100644 --- a/src/main/java/org/olat/repository/RepositoryManager.java +++ b/src/main/java/org/olat/repository/RepositoryManager.java @@ -233,6 +233,18 @@ public class RepositoryManager extends BasicManager { re.setParticipantGroup(participantGroup); } + public void createOwnerSecurityGroup(RepositoryEntry re) { + if(re.getOwnerGroup() != null) return; + + SecurityGroup ownerGroup = securityManager.createAndPersistSecurityGroup(); + // member of this group may modify member's membership + securityManager.createAndPersistPolicy(ownerGroup, Constants.PERMISSION_ACCESS, ownerGroup); + // members of this group are always authors also + securityManager.createAndPersistPolicy(ownerGroup, Constants.PERMISSION_HASROLE, Constants.ORESOURCE_AUTHOR); + securityManager.addIdentityToSecurityGroup(securityManager.findIdentityByName("administrator"), ownerGroup); + re.setOwnerGroup(ownerGroup); + } + /** * * @param addedEntry diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_8_2_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_8_2_0.java index f0a45bb3561190df69d5b220e1a0fb3ab7e33106..123b082b0bef487d47646573a91a8409ddb7cd14 100644 --- a/src/main/java/org/olat/upgrade/OLATUpgrade_8_2_0.java +++ b/src/main/java/org/olat/upgrade/OLATUpgrade_8_2_0.java @@ -23,6 +23,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import org.olat.basesecurity.BaseSecurity; import org.olat.core.commons.persistence.DB; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupImpl; @@ -34,6 +35,7 @@ import org.olat.group.area.BGtoAreaRelationImpl; import org.olat.group.context.BGContext2Resource; import org.olat.group.model.BGResourceRelation; import org.olat.resource.OLATResource; +import org.olat.resource.OLATResourceManager; import org.springframework.beans.factory.annotation.Autowired; /** @@ -57,9 +59,13 @@ public class OLATUpgrade_8_2_0 extends OLATUpgrade { @Autowired private DB dbInstance; @Autowired + private BaseSecurity securityManager; + @Autowired private BGAreaManager areaManager; @Autowired private BusinessGroupService businessGroupService; + @Autowired + private OLATResourceManager resourceManager; public OLATUpgrade_8_2_0() { super(); @@ -146,6 +152,28 @@ public class OLATUpgrade_8_2_0 extends OLATUpgrade { List<OLATResource> resources = findOLATResourcesForBusinessGroup(group); List<OLATResource> currentList = businessGroupService.findResources(Collections.singletonList(group), 0, -1); + boolean merge = false; + if(group.getResource() == null) { + OLATResource resource = resourceManager.findResourceable(group); + ((BusinessGroupImpl)group).setResource(resource); + merge = true; + } + if(group.getOwnerGroup() == null) { + ((BusinessGroupImpl)group).setOwnerGroup(securityManager.createAndPersistSecurityGroup()); + merge = true; + } + if(group.getPartipiciantGroup() == null) { + ((BusinessGroupImpl)group).setPartipiciantGroup(securityManager.createAndPersistSecurityGroup()); + merge = true; + } + if(group.getWaitingGroup() == null) { + group.setWaitingGroup(securityManager.createAndPersistSecurityGroup()); + merge = true; + } + if(merge) { + group = dbInstance.getCurrentEntityManager().merge(group); + } + int count = 0; for (OLATResource resource:resources) { if(!currentList.contains(resource)) { 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 33f5cd1567956ae0165636638232d93deaccfb06..228c77e3130f1d6ff7693a7a45caffb85bd9b8cb 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 @@ -1,3 +1,4 @@ +-- relation groups to resources create table if not exists o_gp_business_to_resource ( g_id bigint not null, version mediumint unsigned not null, @@ -6,14 +7,24 @@ create table if not exists o_gp_business_to_resource ( fk_group bigint not null, primary key (g_id) ); - alter table o_gp_business_to_resource add constraint idx_bgp_to_rsrc_rsrc foreign key (fk_resource) references o_olatresource (resource_id); alter table o_gp_business_to_resource add constraint idx_bgp_to_rsrc_group foreign key (fk_group) references o_gp_business (group_id); +-- groups +alter table o_gp_business add column fk_resource bigint unique default null; - +-- area +alter table o_gp_bgarea modify groupcontext_fk bigint; alter table o_gp_bgarea add column fk_resource bigint default null; alter table o_gp_bgarea add constraint idx_area_to_resource foreign key (fk_resource) references o_olatresource (resource_id); -alter table o_gp_bgarea modify groupcontext_fk bigint; - +-- view +create or replace view o_gp_business_to_repository_v as ( + select + grp.group_id as grp_id, + repoentry.repositoryentry_id as re_id, + repoentry.displayname as re_displayname + from o_gp_business as grp + inner join o_gp_business_to_resource as relation on (relation.fk_group = grp.group_id) + inner join o_repositoryentry as repoentry on (repoentry.fk_olatresource = relation.fk_resource) +); \ No newline at end of file diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index c740ffeab46fa79d7e6c3af54b69537d38d65751..8f5361f66a4438a7dc16fb5620ed4f53bea7e993 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -43,6 +43,7 @@ create table if not exists o_gp_business ( waitinglist_enabled bit, autocloseranks_enabled bit, groupcontext_fk bigint, + fk_resource bigint unique, fk_ownergroup bigint unique, fk_partipiciantgroup bigint unique, fk_waitinggroup bigint unique, @@ -1057,6 +1058,16 @@ create or replace view o_ep_notifications_comment_v as ( left join o_ep_struct_el as page on (page.fk_struct_root_map_id = map.structure_id and page.structure_id = ucomment.ressubpath) ); +create or replace view o_gp_business_to_repository_v as ( + select + grp.group_id as grp_id, + repoentry.repositoryentry_id as re_id, + repoentry.displayname as re_displayname + from o_gp_business as grp + inner join o_gp_business_to_resource as relation on (relation.fk_group = grp.group_id) + inner join o_repositoryentry as repoentry on (repoentry.fk_olatresource = relation.fk_resource) +); + create index ocl_asset_idx on oc_lock (asset); alter table oc_lock add index FK9E30F4B66115906D (identity_fk), add constraint FK9E30F4B66115906D foreign key (identity_fk) references o_bs_identity (id); diff --git a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java index 325dcd580ac759d86d703ddbc49758f621cc94e2..3624b967a1670d54eed659894f797dcec0854801 100644 --- a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java +++ b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java @@ -90,6 +90,7 @@ public class BusinessGroupDAOTest extends OlatTestCase { Assert.assertNotNull(group.getOwnerGroup()); Assert.assertNotNull(group.getPartipiciantGroup()); Assert.assertNotNull(group.getWaitingGroup()); + Assert.assertNotNull(group.getResource()); Assert.assertEquals("gdao", group.getName()); Assert.assertEquals("gdao-desc", group.getDescription()); Assert.assertFalse(group.getWaitingListEnabled()); @@ -112,6 +113,7 @@ public class BusinessGroupDAOTest extends OlatTestCase { Assert.assertNotNull(reloadedGroup.getOwnerGroup()); Assert.assertNotNull(reloadedGroup.getPartipiciantGroup()); Assert.assertNotNull(reloadedGroup.getWaitingGroup()); + Assert.assertNotNull(group.getResource()); Assert.assertEquals("gdbo", reloadedGroup.getName()); Assert.assertEquals("gdbo-desc", reloadedGroup.getDescription()); Assert.assertFalse(reloadedGroup.getWaitingListEnabled()); @@ -671,5 +673,41 @@ public class BusinessGroupDAOTest extends OlatTestCase { Assert.assertTrue(groups.contains(group3)); } + + @Test + public void isIdentityInBusinessGroups() { + 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, 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, 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, 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 fead4822a7ea3092c37d3f9ca5a85cc37b4f1031..bcdbf18c03c1e9655f434a8baa730848760e80d2 100644 --- a/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java +++ b/src/test/java/org/olat/group/test/BusinessGroupRelationDAOTest.java @@ -35,7 +35,9 @@ import org.olat.core.id.Identity; import org.olat.group.BusinessGroup; import org.olat.group.manager.BusinessGroupDAO; import org.olat.group.manager.BusinessGroupRelationDAO; +import org.olat.group.model.BGRepositoryEntryRelation; import org.olat.group.model.SearchBusinessGroupParams; +import org.olat.repository.RepositoryEntry; import org.olat.resource.OLATResource; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; @@ -76,6 +78,9 @@ public class BusinessGroupRelationDAOTest extends OlatTestCase { Assert.assertNotNull(resources); Assert.assertEquals(1, resources.size()); Assert.assertTrue(resources.contains(resource)); + + int count = businessGroupRelationDao.countResources(group); + Assert.assertEquals(1, count); } @Test @@ -640,4 +645,39 @@ public class BusinessGroupRelationDAOTest extends OlatTestCase { Assert.assertEquals(1, participant6.size()); Assert.assertTrue(participant6.contains(part4)); } + + @Test + public void findRelationToRepositoryEntries() { + //create 3 entries and 1 group + RepositoryEntry re1 = JunitTestHelper.createAndPersistRepositoryEntry(); + RepositoryEntry re2 = JunitTestHelper.createAndPersistRepositoryEntry(); + RepositoryEntry re3 = JunitTestHelper.createAndPersistRepositoryEntry(); + BusinessGroup group = businessGroupDao.createAndPersist(null, "rel-repo", "rel-repo-desc", 0, 10, true, false, false, false, false); + dbInstance.commitAndCloseSession(); + + businessGroupRelationDao.addRelationToResource(group, re1.getOlatResource()); + businessGroupRelationDao.addRelationToResource(group, re2.getOlatResource()); + businessGroupRelationDao.addRelationToResource(group, re3.getOlatResource()); + dbInstance.commitAndCloseSession(); + + //check with empty list of groups + List<BGRepositoryEntryRelation> emptyRelations = businessGroupRelationDao.findRelationToRepositoryEntries(Collections.<BusinessGroup>emptyList(), 0, -1); + Assert.assertNotNull(emptyRelations); + Assert.assertEquals(0, emptyRelations.size()); + + //check with the group + List<BGRepositoryEntryRelation> relations = businessGroupRelationDao.findRelationToRepositoryEntries(Collections.singletonList(group), 0, -1); + Assert.assertNotNull(relations); + Assert.assertEquals(3, relations.size()); + + int count = 0; + for(BGRepositoryEntryRelation relation:relations) { + if(relation.getRepositoryEntryKey().equals(re1.getKey()) + || relation.getRepositoryEntryKey().equals(re2.getKey()) + || relation.getRepositoryEntryKey().equals(re3.getKey())) { + count++; + } + } + Assert.assertEquals(3, count); + } } diff --git a/src/test/java/org/olat/test/JunitTestHelper.java b/src/test/java/org/olat/test/JunitTestHelper.java index eb19555cb71a768d0a1b98ec0ec3e83e72198692..cde524af4269d56466171bb558f700601d59e8c9 100644 --- a/src/test/java/org/olat/test/JunitTestHelper.java +++ b/src/test/java/org/olat/test/JunitTestHelper.java @@ -134,6 +134,24 @@ public class JunitTestHelper { return identity; } + public static final RepositoryEntry createAndPersistRepositoryEntry() { + OLATResourceManager resourceManager = OLATResourceManager.getInstance(); + OLATResourceable ores = OresHelper.createOLATResourceableInstance(UUID.randomUUID().toString(), 0l); + OLATResource r = resourceManager.createOLATResourceInstance(ores); + resourceManager.saveOLATResource(r); + + RepositoryManager repositoryManager = RepositoryManager.getInstance(); + RepositoryEntry re = repositoryManager.createRepositoryEntryInstance("Florian Gnägi"); + re.setOlatResource(r); + re.setResourcename("Lernen mit OLAT"); + re.setDisplayname(ores.getResourceableTypeName()); + repositoryManager.createOwnerSecurityGroup(re); + repositoryManager.createTutorSecurityGroup(re); + repositoryManager.createParticipantSecurityGroup(re); + repositoryManager.saveRepositoryEntry(re); + return re; + } + /** * Deploys/imports the "Demo Course". * @return the created RepositoryEntry