From 063cfdc574e92f0a57bc11897be4db4cdd10f516 Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Thu, 2 Aug 2012 14:01:59 +0200 Subject: [PATCH] OO-291: add count of owners --- .../org/olat/group/BusinessGroupView.java | 2 + .../olat/group/manager/BusinessGroupDAO.java | 14 +++++ .../group/model/BusinessGroupViewImpl.hbm.xml | 1 + .../group/model/BusinessGroupViewImpl.java | 17 +++++- .../model/SearchBusinessGroupParams.java | 54 +++++++++++++++++-- .../main/AdminBusinessGroupsController.java | 4 +- .../main/BusinessGroupSearchController.java | 19 ++++++- .../SearchBusinessGroupListController.java | 2 +- .../org/olat/group/ui/main/SearchEvent.java | 10 ++++ .../ui/main/_i18n/LocalStrings_de.properties | 2 + .../olat/group/ui/portlet/GroupsPortlet.java | 19 +++---- .../database/mysql/alter_8_1_x_to_8_2_0.sql | 6 +-- .../olat/group/test/BusinessGroupDAOTest.java | 50 +++++++++++++++++ 13 files changed, 179 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/olat/group/BusinessGroupView.java b/src/main/java/org/olat/group/BusinessGroupView.java index 1d2f013d8c2..271b0dced2c 100644 --- a/src/main/java/org/olat/group/BusinessGroupView.java +++ b/src/main/java/org/olat/group/BusinessGroupView.java @@ -52,6 +52,8 @@ public interface BusinessGroupView extends BusinessGroupShort, Persistable, Crea public int getNumOfRelations(); + public int getNumOfOwners(); + public int getNumOfParticipants(); public int getNumOfOffers(); diff --git a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java index 4ee4de43616..ef156a53601 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupDAO.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupDAO.java @@ -738,6 +738,20 @@ public class BusinessGroupDAO { .append(" )"); } + if(params.isHeadless()) { + where = where(query, where); + query.append(" bgi.numOfRelations=0 and bgi.numOfOwners=0 and bgi.numOfParticipants=0"); + } + + if(params.getNumOfMembers() > -1) { + where = where(query, where); + if(params.isNumOfMembersBigger()) { + query.append(" (bgi.numOfOwners + bgi.numOfParticipants)>=").append(params.getNumOfMembers()); + } else { + query.append(" (bgi.numOfOwners + bgi.numOfParticipants)<=").append(params.getNumOfMembers()); + } + } + if(StringHelper.containsNonWhitespace(params.getNameOrDesc())) { where = where(query, where); query.append("("); diff --git a/src/main/java/org/olat/group/model/BusinessGroupViewImpl.hbm.xml b/src/main/java/org/olat/group/model/BusinessGroupViewImpl.hbm.xml index 203e0a1c72c..d5427dcf3ba 100644 --- a/src/main/java/org/olat/group/model/BusinessGroupViewImpl.hbm.xml +++ b/src/main/java/org/olat/group/model/BusinessGroupViewImpl.hbm.xml @@ -21,6 +21,7 @@ <property name="waitingListEnabled" type="boolean" column="waitinglist_enabled" unique="false" not-null="false"/> <property name="autoCloseRanksEnabled" type="boolean" column="autocloseranks_enabled" unique="false" not-null="false"/> <!-- statistics informations --> + <property name="numOfOwners" column="num_of_owners" type="integer" /> <property name="numOfParticipants" column="num_of_participants" type="integer" /> <property name="numOfRelations" column="num_of_relations" type="integer" /> <property name="numOfOffers" column="num_of_offers" type="integer" /> diff --git a/src/main/java/org/olat/group/model/BusinessGroupViewImpl.java b/src/main/java/org/olat/group/model/BusinessGroupViewImpl.java index 479c5258ec1..361a004649e 100644 --- a/src/main/java/org/olat/group/model/BusinessGroupViewImpl.java +++ b/src/main/java/org/olat/group/model/BusinessGroupViewImpl.java @@ -28,7 +28,10 @@ import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupView; import org.olat.resource.OLATResource; - +/** + * + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ public class BusinessGroupViewImpl extends PersistentObject implements BusinessGroupView { private static final long serialVersionUID = -9042740930754224954L; @@ -46,7 +49,8 @@ public class BusinessGroupViewImpl extends PersistentObject implements BusinessG private Boolean waitingListEnabled; private Boolean autoCloseRanksEnabled; private Date lastModified; - + + private int numOfOwners; private int numOfParticipants; private int numOfRelations; private int numOfOffers; @@ -61,6 +65,15 @@ public class BusinessGroupViewImpl extends PersistentObject implements BusinessG this.numOfRelations = numOfRelations; } + @Override + public int getNumOfOwners() { + return numOfOwners; + } + + public void setNumOfOwners(int numOfOwners) { + this.numOfOwners = numOfOwners; + } + @Override public int getNumOfParticipants() { return numOfParticipants; diff --git a/src/main/java/org/olat/group/model/SearchBusinessGroupParams.java b/src/main/java/org/olat/group/model/SearchBusinessGroupParams.java index c62a46ae8e4..8d553e825f9 100644 --- a/src/main/java/org/olat/group/model/SearchBusinessGroupParams.java +++ b/src/main/java/org/olat/group/model/SearchBusinessGroupParams.java @@ -52,6 +52,10 @@ public class SearchBusinessGroupParams { private Boolean publicGroups; private Boolean marked; private Boolean resources; + private boolean headless = false; + private int numOfMembers = -1; + private boolean numOfMembersBigger = true; + public SearchBusinessGroupParams() { // @@ -191,8 +195,52 @@ public class SearchBusinessGroupParams { public void setResources(Boolean resources) { this.resources = resources; } + + /** + * Only available on views + * @return + */ + public boolean isHeadless() { + return headless; + } + + /** + * Only available on views + * @param headless + */ + public void setHeadless(boolean headless) { + this.headless = headless; + } + + /** + * Only available on views + * @return + */ + public int getNumOfMembers() { + return numOfMembers; + } + + /** + * Only available on views + * @param headless + */ + public void setNumOfMembers(int numOfMembers) { + this.numOfMembers = numOfMembers; + } - - - + /** + * Only available on views + * @return + */ + public boolean isNumOfMembersBigger() { + return numOfMembersBigger; + } + + /** + * Only available on views + * @param headless + */ + public void setNumOfMembersBigger(boolean numOfMembersBigger) { + this.numOfMembersBigger = numOfMembersBigger; + } } diff --git a/src/main/java/org/olat/group/ui/main/AdminBusinessGroupsController.java b/src/main/java/org/olat/group/ui/main/AdminBusinessGroupsController.java index 3e2b9f6881e..4719e1ecc27 100644 --- a/src/main/java/org/olat/group/ui/main/AdminBusinessGroupsController.java +++ b/src/main/java/org/olat/group/ui/main/AdminBusinessGroupsController.java @@ -42,9 +42,9 @@ public class AdminBusinessGroupsController extends AbstractBusinessGroupListCont public AdminBusinessGroupsController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl, "admin_group_list"); if(isAdmin()) { - searchController = new BusinessGroupSearchController(ureq, wControl, true, false); + searchController = new BusinessGroupSearchController(ureq, wControl, true, false, true); } else { - searchController = new BusinessGroupSearchController(ureq, wControl, false, true); + searchController = new BusinessGroupSearchController(ureq, wControl, false, true, false); } //search controller listenTo(searchController); diff --git a/src/main/java/org/olat/group/ui/main/BusinessGroupSearchController.java b/src/main/java/org/olat/group/ui/main/BusinessGroupSearchController.java index 9580c070189..05616c2aa19 100644 --- a/src/main/java/org/olat/group/ui/main/BusinessGroupSearchController.java +++ b/src/main/java/org/olat/group/ui/main/BusinessGroupSearchController.java @@ -22,6 +22,7 @@ package org.olat.group.ui.main; 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.MultipleSelectionElement; import org.olat.core.gui.components.form.flexible.elements.SingleSelection; import org.olat.core.gui.components.form.flexible.elements.TextElement; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; @@ -52,9 +53,11 @@ public class BusinessGroupSearchController extends FormBasicController{ private SingleSelection rolesEl; private SingleSelection publicEl; private SingleSelection resourceEl; + private MultipleSelectionElement headlessEl; private final boolean showId; private final boolean showRoles; + private final boolean showAdminTools; private String limitUsername; private String[] roleKeys = {"all", "owner", "attendee", "waiting"}; @@ -69,10 +72,11 @@ public class BusinessGroupSearchController extends FormBasicController{ * @param isAdmin Is calling identity an administrator? If yes, allow search by ID * @param limitTypes Limit searches to specific types. */ - public BusinessGroupSearchController(UserRequest ureq, WindowControl wControl, boolean showId, boolean showRoles) { + public BusinessGroupSearchController(UserRequest ureq, WindowControl wControl, boolean showId, boolean showRoles, boolean showAdminTools) { super(ureq, wControl, "group_search"); this.showId = showId; this.showRoles = showRoles; + this.showAdminTools = showAdminTools; initForm(ureq); } @@ -128,6 +132,12 @@ public class BusinessGroupSearchController extends FormBasicController{ } resourceEl = uifactory.addRadiosHorizontal("resourceBg", "search.resources", rightContainer, resourceKeys, resourceValues); resourceEl.select("all", true); + + if(showAdminTools) { + String[] keys = new String[] { "headless" }; + String[] values = new String[] { translate("search.headless.check") }; + headlessEl = uifactory.addCheckboxesHorizontal("headless.groups", "search.headless", rightContainer, keys, values, null); + } FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("button_layout", getTranslator()); formLayout.add(buttonLayout); @@ -223,11 +233,18 @@ public class BusinessGroupSearchController extends FormBasicController{ private void fireSearchEvent(UserRequest ureq) { SearchEvent e = new SearchEvent(); + e.setId(getId()); e.setName(getName()); e.setDescription(getDescription()); e.setOwnerName(getOwner()); e.setCourseTitle(getCourseTitle()); + if(headlessEl != null && headlessEl.isAtLeastSelected(1)) { + e.setHeadless(true); + } else { + e.setHeadless(false); + } + if(rolesEl != null && rolesEl.isOneSelected()) { e.setAttendee(rolesEl.isSelected(0) || rolesEl.isSelected(1)); e.setOwner(rolesEl.isSelected(0) || rolesEl.isSelected(2)); diff --git a/src/main/java/org/olat/group/ui/main/SearchBusinessGroupListController.java b/src/main/java/org/olat/group/ui/main/SearchBusinessGroupListController.java index f196916ebc4..6feb525de9a 100644 --- a/src/main/java/org/olat/group/ui/main/SearchBusinessGroupListController.java +++ b/src/main/java/org/olat/group/ui/main/SearchBusinessGroupListController.java @@ -44,7 +44,7 @@ public class SearchBusinessGroupListController extends AbstractBusinessGroupList super(ureq, wControl, "group_list_search"); //search controller - searchController = new BusinessGroupSearchController(ureq, wControl, isAdmin(), true); + searchController = new BusinessGroupSearchController(ureq, wControl, isAdmin(), true, false); listenTo(searchController); mainVC.put("search", searchController.getInitialComponent()); } diff --git a/src/main/java/org/olat/group/ui/main/SearchEvent.java b/src/main/java/org/olat/group/ui/main/SearchEvent.java index 8e462b20a2f..98f2886c834 100644 --- a/src/main/java/org/olat/group/ui/main/SearchEvent.java +++ b/src/main/java/org/olat/group/ui/main/SearchEvent.java @@ -42,6 +42,7 @@ public class SearchEvent extends Event { private boolean owner; private boolean attendee; private boolean waiting; + private boolean headless = false; private Boolean publicGroups; private Boolean resources; @@ -129,6 +130,14 @@ public class SearchEvent extends Event { this.resources = resources; } + public boolean isHeadless() { + return headless; + } + + public void setHeadless(boolean headless) { + this.headless = headless; + } + public SearchBusinessGroupParams convertToSearchBusinessGroupParams(Identity identity) { SearchBusinessGroupParams params = new SearchBusinessGroupParams(); if(id != null) { @@ -144,6 +153,7 @@ public class SearchEvent extends Event { params.setPublicGroups(getPublicGroups()); params.setResources(getResources()); params.setIdentity(identity); + params.setHeadless(isHeadless()); return params; } } 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 56a3d42120c..f0248d986ba 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 @@ -54,6 +54,8 @@ search.roles=Rolle search.yes=Ja search.no=Nein search.resources=In Kursen verwendet +search.headless=Orphans +search.headless.check=Gruppe ohne Mitglieder und Resourcen cif.displayname=Name cif.description=Beschreibung cif.owner=Besitzer diff --git a/src/main/java/org/olat/group/ui/portlet/GroupsPortlet.java b/src/main/java/org/olat/group/ui/portlet/GroupsPortlet.java index a9c1d16901e..e61d5ae3e2f 100644 --- a/src/main/java/org/olat/group/ui/portlet/GroupsPortlet.java +++ b/src/main/java/org/olat/group/ui/portlet/GroupsPortlet.java @@ -80,9 +80,11 @@ public class GroupsPortlet extends AbstractPortlet { * org.olat.core.gui.UserRequest) */ public Component getInitialRunComponent(WindowControl wControl, UserRequest ureq) { - if(this.runCtr != null) runCtr.dispose(); - this.runCtr = new GroupsPortletRunController(wControl, ureq, getTranslator(), this.getName()); - return this.runCtr.getInitialComponent(); + if(runCtr != null) { + runCtr.dispose(); + } + runCtr = new GroupsPortletRunController(wControl, ureq, getTranslator(), this.getName()); + return runCtr.getInitialComponent(); } /** @@ -103,18 +105,17 @@ public class GroupsPortlet extends AbstractPortlet { * @see org.olat.gui.control.generic.portal.Portlet#disposeRunComponent(boolean) */ public void disposeRunComponent() { - if (this.runCtr != null) { - this.runCtr.dispose(); - this.runCtr = null; + if (runCtr != null) { + runCtr.dispose(); + runCtr = null; } } - public PortletToolController getTools(UserRequest ureq, WindowControl wControl) { + public PortletToolController<BusinessGroupEntry> getTools(UserRequest ureq, WindowControl wControl) { //portlet was not yet visible if ( runCtr == null ) { - this.runCtr = new GroupsPortletRunController(wControl, ureq, getTranslator(), this.getName()); + runCtr = new GroupsPortletRunController(wControl, ureq, getTranslator(), this.getName()); } return runCtr.createSortingTool(ureq, wControl); } - } 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 7bf00986db6..997ab6cae80 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 @@ -115,8 +115,6 @@ create or replace view o_bs_gp_membership_v as ( where (owned_gp.group_id is not null or participant_gp.group_id is not null or waiting_gp.group_id is not null) ); - - create or replace view o_gp_business_v as ( select gp.group_id as group_id, @@ -131,6 +129,8 @@ create or replace view o_gp_business_v as ( gp.autocloseranks_enabled as autocloseranks_enabled, -- count participants (select count(part.id) from o_bs_membership as part where part.secgroup_id = gp.fk_partipiciantgroup) as num_of_participants, + -- count owners + (select count(own.id) from o_bs_membership as own where own.secgroup_id = gp.fk_ownergroup) as num_of_owners, -- count valid offers (select count(offer.offer_id) from o_ac_offer as offer where offer.fk_resource_id = gp.fk_resource @@ -152,5 +152,5 @@ create or replace view o_gp_business_v as ( gp.fk_partipiciantgroup as fk_partipiciantgroup, gp.fk_waitinggroup as fk_waitinggroup from o_gp_business as gp -) +); diff --git a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java index 9ed9c47c081..41d60a35dba 100644 --- a/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java +++ b/src/test/java/org/olat/group/test/BusinessGroupDAOTest.java @@ -1048,6 +1048,56 @@ public class BusinessGroupDAOTest extends OlatTestCase { Assert.assertTrue(contains(markedGroupsView2, group2)); } + @Test + public void findBusinessGroupsHeadless() { + Identity owner = JunitTestHelper.createAndPersistIdentityAsUser("head-1-" + UUID.randomUUID().toString()); + BusinessGroup headlessGroup = businessGroupDao.createAndPersist(null, "headless-grp", "headless-grp-desc", 0, 5, true, false, true, false, false); + BusinessGroup headedGroup = businessGroupDao.createAndPersist(owner, "headed-grp", "headed-grp-desc", 0, 5, true, false, true, false, false); + dbInstance.commitAndCloseSession(); + + //check marked + SearchBusinessGroupParams headlessParams = new SearchBusinessGroupParams(); + headlessParams.setHeadless(true); + List<BusinessGroupView> groups = businessGroupDao.findBusinessGroupViews(headlessParams, null, 0, 0); + Assert.assertNotNull(groups); + Assert.assertFalse(groups.isEmpty()); + Assert.assertTrue(contains(groups, headlessGroup)); + Assert.assertFalse(contains(groups, headedGroup)); + } + + @Test + public void findBusinessGroupsNumOfMembers() { + Identity owner = JunitTestHelper.createAndPersistIdentityAsUser("head-1-" + UUID.randomUUID().toString()); + Identity part1 = JunitTestHelper.createAndPersistIdentityAsUser("head-1-" + UUID.randomUUID().toString()); + Identity part2 = JunitTestHelper.createAndPersistIdentityAsUser("head-1-" + UUID.randomUUID().toString()); + BusinessGroup groupWith1 = businessGroupDao.createAndPersist(owner, "headless-grp", "headless-grp-desc", 0, 5, true, false, true, false, false); + BusinessGroup groupWith3 = businessGroupDao.createAndPersist(owner, "headed-grp", "headed-grp-desc", 0, 5, true, false, true, false, false); + securityManager.addIdentityToSecurityGroup(part1, groupWith3.getPartipiciantGroup()); + securityManager.addIdentityToSecurityGroup(part2, groupWith3.getPartipiciantGroup()); + dbInstance.commitAndCloseSession(); + + //check groups with more than 2 members + SearchBusinessGroupParams paramsWithMoreThan2 = new SearchBusinessGroupParams(); + paramsWithMoreThan2.setNumOfMembers(2); + paramsWithMoreThan2.setNumOfMembersBigger(true); + List<BusinessGroupView> groupsWithMoreThan2 = businessGroupDao.findBusinessGroupViews(paramsWithMoreThan2, null, 0, 0); + Assert.assertNotNull(groupsWithMoreThan2); + Assert.assertFalse(groupsWithMoreThan2.isEmpty()); + Assert.assertTrue(contains(groupsWithMoreThan2, groupWith3)); + Assert.assertFalse(contains(groupsWithMoreThan2, groupWith1)); + + //check groups with more than 2 members + SearchBusinessGroupParams paramsWithLessThan2 = new SearchBusinessGroupParams(); + paramsWithLessThan2.setNumOfMembers(2); + paramsWithLessThan2.setNumOfMembersBigger(false); + List<BusinessGroupView> groupsWithLessThan2 = businessGroupDao.findBusinessGroupViews(paramsWithLessThan2, null, 0, 0); + Assert.assertNotNull(groupsWithLessThan2); + Assert.assertFalse(groupsWithLessThan2.isEmpty()); + Assert.assertTrue(contains(groupsWithLessThan2, groupWith1)); + Assert.assertFalse(contains(groupsWithLessThan2, groupWith3)); + } + + @Test public void findBusinessGroupOrdered() { BusinessGroup group1 = businessGroupDao.createAndPersist(null, "a_ordered-grp-3", "marked-grp-1-desc", 0, 5, true, false, true, false, false); -- GitLab