Skip to content

Commit 7a13551

Browse files
committed
Feature #14033
Now the creation and the deletion of a community of users is notified. This can be used for external components to access the newly created commiunity of users in order to perform some post-processing with the community. New CommunityOfUsers#getGroupOfMembers() method. This method returns the group of members in the community. If such a group doesn't yet exist, then it is created for the community of users. It is a way to get all the actual members of a community without having to filter the memberships by their status. New CommunityOfUsers#getAll() static method to get all the existing community of users.
1 parent 364c563 commit 7a13551

File tree

7 files changed

+253
-21
lines changed

7 files changed

+253
-21
lines changed

community/community-library/src/integration-test/java/org/silverpeas/components/community/CommunityAppIT.java

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public void initCurrentRequester() {
8585
public void createANewAppInstanceShouldCreateACommunity() throws AdminException, QuotaException {
8686
Administration admin = Administration.get();
8787
User user = User.getCurrentUser();
88-
ComponentInst componentInst = newCommunityAppInstance();
88+
ComponentInst componentInst = TestScope.newCommunityAppInstance();
8989
String instanceId = admin.addComponentInst(user.getId(), componentInst);
9090

9191
SpaceInst spaceInst = admin.getSpaceInstById(componentInst.getSpaceId());
@@ -109,18 +109,4 @@ public void deleteAnExistingAppInstanceShouldDeleteTheCommunity() throws AdminEx
109109
Optional<CommunityOfUsers> community = CommunityOfUsers.getByComponentInstanceId(instanceId);
110110
assertThat(community.isEmpty(), is(true));
111111
}
112-
113-
private static ComponentInst newCommunityAppInstance() {
114-
ComponentInst componentInst = new ComponentInst();
115-
componentInst.setDomainFatherId("WA4");
116-
componentInst.setCreatorUserId(User.getCurrentUser().getId());
117-
componentInst.setName("community");
118-
componentInst.setLabel("WA4 Community");
119-
componentInst.setDescription("Community of users for space WA4");
120-
componentInst.setPublic(true);
121-
componentInst.setHidden(false);
122-
componentInst.setInheritanceBlocked(true);
123-
componentInst.setParameters(new ArrayList<>());
124-
return componentInst;
125-
}
126112
}

community/community-library/src/integration-test/java/org/silverpeas/components/community/CommunityManagementIT.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,16 @@ public void getAnExistingCommunity() {
111111
assertThat(actualCommunity.getCharterURL().toString(), is("https://www.silverpeas.org"));
112112
}
113113

114+
@Test
115+
public void getAllExistingCommunities() {
116+
List<String> appIds = List.of("community1", "community2", "community3");
117+
List<CommunityOfUsers> communities = CommunityOfUsers.getAll();
118+
assertThat(communities.size(), is(3));
119+
boolean matches =
120+
communities.stream().allMatch(c -> appIds.contains(c.getComponentInstanceId()));
121+
assertThat(matches, is(true));
122+
}
123+
114124
@Test
115125
public void getANonExistingCommunity() {
116126
String instanceId = "community100";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright (C) 2000 - 2024 Silverpeas
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as
6+
* published by the Free Software Foundation, either version 3 of the
7+
* License, or (at your option) any later version.
8+
*
9+
* As a special exception to the terms and conditions of version 3.0 of
10+
* the GPL, you may redistribute this Program in connection with Free/Libre
11+
* Open Source Software ("FLOSS") applications as described in Silverpeas's
12+
* FLOSS exception. You should have received a copy of the text describing
13+
* the FLOSS exception, and it is also available here:
14+
* "http://www.silverpeas.com/legal/licensing"
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Affero General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Affero General Public License
22+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23+
*/
24+
25+
package org.silverpeas.components.community;
26+
27+
import org.jboss.arquillian.container.test.api.Deployment;
28+
import org.jboss.arquillian.junit.Arquillian;
29+
import org.jboss.shrinkwrap.api.Archive;
30+
import org.junit.Before;
31+
import org.junit.Rule;
32+
import org.junit.Test;
33+
import org.junit.runner.RunWith;
34+
import org.silverpeas.components.community.model.CommunityOfUsers;
35+
import org.silverpeas.components.community.notification.CommunityEvent;
36+
import org.silverpeas.core.admin.component.model.ComponentInst;
37+
import org.silverpeas.core.admin.service.Administration;
38+
import org.silverpeas.core.admin.user.model.User;
39+
import org.silverpeas.core.annotation.Bean;
40+
import org.silverpeas.core.cache.service.CacheAccessorProvider;
41+
import org.silverpeas.core.cache.service.SessionCacheAccessor;
42+
import org.silverpeas.core.notification.system.CDIResourceEventListener;
43+
import org.silverpeas.core.test.integration.rule.DbSetupRule;
44+
45+
import static org.hamcrest.MatcherAssert.assertThat;
46+
import static org.hamcrest.Matchers.*;
47+
48+
/**
49+
* Integration tests on the notification about the creation and the deletion of a community of
50+
* users.
51+
* @author mmoquillon
52+
*/
53+
@RunWith(Arquillian.class)
54+
public class CommunityNotificationIT {
55+
56+
private static final String DATABASE_CREATION_SCRIPT = "/community-database.sql";
57+
58+
private static final String DATASET_SCRIPT = "/community-dataset.sql";
59+
60+
@Rule
61+
public DbSetupRule dbSetupRule = DbSetupRule.createTablesFrom(DATABASE_CREATION_SCRIPT)
62+
.loadInitialDataSetFrom(DATASET_SCRIPT);
63+
64+
@Deployment
65+
public static Archive<?> createTestArchive() {
66+
return CommunityWarBuilder.onWarForTestClass(CommunityAppIT.class)
67+
.initJcr()
68+
.addAsResource("org/silverpeas/publication/publicationSettings.properties")
69+
.addAsResource("org/silverpeas/publicationTemplate/settings/mapping.properties")
70+
.addAsResource("org/silverpeas/publicationTemplate/settings/template.properties")
71+
.addAsResource(DATABASE_CREATION_SCRIPT.substring(1))
72+
.addAsResource(DATASET_SCRIPT.substring(1))
73+
.build();
74+
}
75+
76+
@Before
77+
public void initCurrentRequester() {
78+
SessionCacheAccessor sessionCacheAccessor =
79+
CacheAccessorProvider.getSessionCacheAccessor();
80+
sessionCacheAccessor.newSessionCache(User.getById("0"));
81+
}
82+
83+
@Test
84+
public void toBeNotifiedAtCommunityCreation() throws Exception {
85+
Administration admin = Administration.get();
86+
User user = User.getCurrentUser();
87+
ComponentInst componentInst = TestScope.newCommunityAppInstance();
88+
admin.addComponentInst(user.getId(), componentInst);
89+
}
90+
91+
@Test
92+
public void toBeNotifiedAtCommunityDeletion() throws Exception {
93+
User admin = User.getCurrentUser();
94+
String instanceId = "community2";
95+
Administration.get().deleteComponentInst(admin.getId(), instanceId, true);
96+
}
97+
98+
@Bean
99+
public static class CommunityEventListener extends CDIResourceEventListener<CommunityEvent> {
100+
101+
102+
@Override
103+
public void onDeletion(CommunityEvent event) {
104+
CommunityOfUsers community = event.getTransition().getBefore();
105+
assertThat(community.isPersisted(), is(false));
106+
var optionalCommunity =
107+
CommunityOfUsers.getByComponentInstanceId(community.getComponentInstanceId());
108+
assertThat(optionalCommunity.isEmpty(), is(true));
109+
}
110+
111+
@Override
112+
public void onCreation(CommunityEvent event) {
113+
CommunityOfUsers community = event.getTransition().getAfter();
114+
assertThat(community, is(notNullValue()));
115+
assertThat(community.isPersisted(), is(true));
116+
assertThat(community.getGroupOfMembers(), is(notNullValue()));
117+
assertThat(community.getGroupOfMembers().getAllUsers(), is(empty()));
118+
assertThat(community.getGroupOfMembers().getSubGroups(), is(empty()));
119+
}
120+
}
121+
}
122+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (C) 2000 - 2024 Silverpeas
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as
6+
* published by the Free Software Foundation, either version 3 of the
7+
* License, or (at your option) any later version.
8+
*
9+
* As a special exception to the terms and conditions of version 3.0 of
10+
* the GPL, you may redistribute this Program in connection with Free/Libre
11+
* Open Source Software ("FLOSS") applications as described in Silverpeas's
12+
* FLOSS exception. You should have received a copy of the text describing
13+
* the FLOSS exception, and it is also available here:
14+
* "http://www.silverpeas.com/legal/licensing"
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Affero General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Affero General Public License
22+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
23+
*/
24+
25+
package org.silverpeas.components.community;
26+
27+
import org.silverpeas.core.admin.component.model.ComponentInst;
28+
import org.silverpeas.core.admin.user.model.User;
29+
30+
import java.util.ArrayList;
31+
32+
/**
33+
* Scope of a running integration test. It provides useful and utility methods for tests.
34+
* @author mmoquillon
35+
*/
36+
public class TestScope {
37+
38+
public static ComponentInst newCommunityAppInstance() {
39+
ComponentInst componentInst = new ComponentInst();
40+
componentInst.setDomainFatherId("WA4");
41+
componentInst.setCreatorUserId(User.getCurrentUser().getId());
42+
componentInst.setName("community");
43+
componentInst.setLabel("WA4 Community");
44+
componentInst.setDescription("Community of users for space WA4");
45+
componentInst.setPublic(true);
46+
componentInst.setHidden(false);
47+
componentInst.setInheritanceBlocked(true);
48+
componentInst.setParameters(new ArrayList<>());
49+
return componentInst;
50+
}
51+
}
52+

community/community-library/src/main/java/org/silverpeas/components/community/CommunityInstancePostConstruction.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
package org.silverpeas.components.community;
2525

2626
import org.silverpeas.components.community.model.CommunityOfUsers;
27+
import org.silverpeas.components.community.notification.CommunityEventNotifier;
2728
import org.silverpeas.components.community.repository.CommunityOfUsersRepository;
29+
import org.silverpeas.core.notification.system.ResourceEvent;
2830
import org.silverpeas.kernel.SilverpeasRuntimeException;
2931
import org.silverpeas.core.admin.component.ComponentInstancePostConstruction;
3032
import org.silverpeas.core.admin.component.model.ComponentInst;
@@ -54,19 +56,24 @@ public class CommunityInstancePostConstruction implements ComponentInstancePostC
5456
@Inject
5557
private CommunityOfUsersRepository repository;
5658

59+
@Inject
60+
private CommunityEventNotifier notifier;
61+
5762

5863
@Transactional
5964
@Override
6065
public void postConstruct(final String componentInstanceId) {
6166
ComponentInst instance = getComponentInst(componentInstanceId);
6267
SpaceInst spaceInst = getSpaceInst(instance.getSpaceId());
6368
CommunityOfUsers community = new CommunityOfUsers(instance.getId(), spaceInst.getId());
64-
repository.save(community);
69+
CommunityOfUsers savedCommunity = repository.save(community);
6570

6671
spaceInst.setFirstPageExtraParam(componentInstanceId);
6772
spaceInst.setInheritanceBlocked(true);
6873
spaceInst.setFirstPageType(SpaceHomePageType.COMPONENT_INST.ordinal());
6974
updateSpaceInst(spaceInst);
75+
76+
notifier.notifyEventOn(ResourceEvent.Type.CREATION, savedCommunity);
7077
}
7178

7279
private ComponentInst getComponentInst(final String instanceId) {

community/community-library/src/main/java/org/silverpeas/components/community/CommunityInstancePreDestruction.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323
*/
2424
package org.silverpeas.components.community;
2525

26+
import org.silverpeas.components.community.notification.CommunityEventNotifier;
2627
import org.silverpeas.components.community.repository.CommunityMembershipRepository;
2728
import org.silverpeas.components.community.repository.CommunityOfUsersRepository;
2829
import org.silverpeas.core.admin.component.ComponentInstancePreDestruction;
2930
import org.silverpeas.core.annotation.Bean;
3031
import org.silverpeas.core.contribution.model.WysiwygContent;
32+
import org.silverpeas.core.notification.system.ResourceEvent;
3133

3234
import javax.inject.Inject;
3335
import javax.inject.Named;
@@ -45,6 +47,8 @@ public class CommunityInstancePreDestruction implements ComponentInstancePreDest
4547
private CommunityOfUsersRepository communitiesRepository;
4648
@Inject
4749
private CommunityMembershipRepository membersRepository;
50+
@Inject
51+
private CommunityEventNotifier notifier;
4852

4953
@Transactional
5054
@Override
@@ -58,6 +62,7 @@ public void preDestroy(final String componentInstanceId) {
5862
membersRepository.getMembershipsTable(c).deleteAll();
5963
// delete finally the community of users
6064
c.delete();
65+
notifier.notifyEventOn(ResourceEvent.Type.DELETION, c);
6166
});
6267
}
6368
}

community/community-library/src/main/java/org/silverpeas/components/community/model/CommunityOfUsers.java

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,12 @@
7070
* difference is the community space is visible to all users of the platform without requiring this
7171
* space to be public; they have just a view of it and of its presentation page.
7272
* <p>
73-
* The actual members of a community of users are all included in a specific group of users
74-
* that is automatically created lazily when a first member joins the community. This group of
75-
* members is a easy way to access all the members of the community.
73+
* The actual members of a community of users are all included in a specific group of users that is
74+
* automatically created when the community is spawned. This group of members is kept up-to-date
75+
* with the users playing a role in the community space. The group of members allow to get in one
76+
* shot all the actual members of the community. To have a glance about the memberships to the
77+
* community, passed, actual and pending, please asks to the {@link CommunityMembershipsProvider}
78+
* object associated with the community of users.
7679
* </p>
7780
*/
7881
@Entity
@@ -130,6 +133,15 @@ public CommunityOfUsers(final String componentInstanceId, final String spaceId)
130133
this.communitySpace = new CommunitySpace(this);
131134
}
132135

136+
/**
137+
* Gets all the communities of users existing in Silverpeas.
138+
* @return a list of exiting community of users.
139+
*/
140+
public static List<CommunityOfUsers> getAll() {
141+
CommunityOfUsersRepository repository = CommunityOfUsersRepository.get();
142+
return repository.getAll();
143+
}
144+
133145
/**
134146
* Gets the community of users managed by the specified component instance. If the component
135147
* instance doesn't exist then nothing is returned.
@@ -403,6 +415,36 @@ public void delete() {
403415
});
404416
}
405417

418+
/**
419+
* Gets the group of all the members of this community of users. If this community isn't
420+
* persisted, null is returned. Otherwise the group of members of this community of users is
421+
* returned. In the case such a group isn't yet created, then this method will create it before
422+
* returning it. If no users are currently members in this community, then the returned group of
423+
* users will be empty.
424+
*
425+
* @return the group of users who are all members of this community or null if this community
426+
* isn't yet persisted.
427+
* @throws SilverpeasRuntimeException if an error occurs while creating or getting the group of
428+
* members.
429+
*/
430+
public GroupDetail getGroupOfMembers() {
431+
if (!isPersisted()) {
432+
return null;
433+
}
434+
GroupDetail group;
435+
try {
436+
if (groupId == null) {
437+
SpaceInst spaceInst = getCommunitySpace().getSilverpeasSpace();
438+
group = getCommunitySpace().createMembersGroup(spaceInst);
439+
} else {
440+
group = getCommunitySpace().getMembersGroup();
441+
}
442+
} catch (AdminException e) {
443+
throw new SilverpeasRuntimeException(e);
444+
}
445+
return group;
446+
}
447+
406448
@Override
407449
public boolean equals(final Object obj) {
408450
return super.equals(obj);
@@ -626,6 +668,13 @@ private void addUserInMembershipGroup(User user, SpaceInst space) throws AdminEx
626668
}
627669
}
628670

671+
/**
672+
* Creates the group of the members for the specified community space.
673+
*
674+
* @param space an existing community space in Silverpeas
675+
* @return the created group of members
676+
* @throws AdminException if an error occurs while creating the group of members.
677+
*/
629678
private GroupDetail createMembersGroup(SpaceInst space) throws AdminException {
630679
GroupDetail group;
631680
group = new GroupDetail();
@@ -715,8 +764,9 @@ class SynchronizationTask {
715764
* this space is up-to-date with the users playing a role in it. If a user playing a role in
716765
* the space isn't yet in the members group, then he's added in this group. If the a user in
717766
* the group isn't playing any role in the space, then he's removed from the members group.
718-
* @param usersPlayingARole a set with the unique identifiers of the users who play a role
719-
* in the community space.
767+
*
768+
* @param usersPlayingARole a set with the unique identifiers of the users who play a role in
769+
* the community space.
720770
*/
721771
void synchronizeMembersGroup(final Set<String> usersPlayingARole) {
722772
execute(() -> {

0 commit comments

Comments
 (0)