001/*
002 *  Copyright 2023 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.workspaces.activities.projects;
017
018import java.util.List;
019import java.util.stream.Stream;
020
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023
024import org.ametys.core.group.Group;
025import org.ametys.core.group.GroupIdentity;
026import org.ametys.core.group.GroupManager;
027import org.ametys.core.user.User;
028import org.ametys.core.user.UserIdentity;
029import org.ametys.plugins.repository.AmetysObject;
030import org.ametys.plugins.repository.activities.Activity;
031import org.ametys.plugins.repository.activities.ActivityType;
032import org.ametys.plugins.workspaces.activities.AbstractWorkspacesActivityNotifier;
033import org.ametys.plugins.workspaces.activities.AbstractWorkspacesActivityType;
034import org.ametys.plugins.workspaces.members.JCRProjectMember.MemberType;
035import org.ametys.plugins.workspaces.members.ProjectMemberManager;
036import org.ametys.plugins.workspaces.members.ProjectMemberManager.ProjectMember;
037import org.ametys.plugins.workspaces.project.notification.preferences.NotificationPreferencesHelper.Frequency;
038import org.ametys.plugins.workspaces.project.objects.Project;
039
040/**
041 * Class representing a activity notifier for member added in workspaces
042 */
043public class MemberAddedActivityNotifier extends AbstractWorkspacesActivityNotifier
044{
045    /** The group manager */
046    protected GroupManager _groupManager;
047    
048    /** The project member manager */
049    protected ProjectMemberManager _projectMemberManager;
050    
051    @Override
052    public void service(ServiceManager manager) throws ServiceException
053    {
054        super.service(manager);
055        _groupManager = (GroupManager) manager.lookup(GroupManager.ROLE);
056        _projectMemberManager = (ProjectMemberManager) manager.lookup(ProjectMemberManager.ROLE);
057    }
058    
059    public boolean support(ActivityType activityType)
060    {
061        return activityType instanceof MemberAddedActivityType;
062    }
063    
064    @Override
065    public List<String> getUsersEmailToNotify(Activity activity)
066    {
067        Stream<User> previousUser = null;
068        Project project = _projectManager.getProject(activity.getValue(AbstractWorkspacesActivityType.PROJECT_NAME));
069
070        // if the new member is a user, we just need to inform all other user
071        // we have already check that it is in fact a new member
072        MemberType memberType = MemberType.valueOf(activity.<String> getValue(MemberAddedActivityType.MEMBER_TYPE).toUpperCase());
073        if (MemberType.USER.equals(memberType))
074        {
075            UserIdentity userIdentity = UserIdentity.stringToUserIdentity(activity.getValue(MemberAddedActivityType.MEMBER));
076            if (userIdentity != null)
077            {
078                User newUser = _userManager.getUser(userIdentity);
079                if (newUser != null)
080                {
081                    previousUser = _projectMemberManager.getProjectMembers(project, true).stream().map(ProjectMember::getUser).filter(u -> !u.equals(newUser));
082                }
083            }
084        }
085        else
086        {
087            GroupIdentity groupIdentity = GroupIdentity.stringToGroupIdentity(activity.getValue(MemberAddedActivityType.MEMBER));
088            if (groupIdentity != null)
089            {
090                Group group = _groupManager.getGroup(groupIdentity);
091                if (group != null)
092                {
093                    previousUser = _projectMemberManager.getProjectMembers(project, false).stream()
094                            // we remove the new group from the project members.
095                            .filter(member -> MemberType.USER.equals(member.getType()) || group.equals(member.getGroup()))
096                            // now we can expand all the group. If a user from
097                            // the new group was already present he shall
098                            // receive a notification as an activity was created
099                            .flatMap(member -> {
100                                if (MemberType.USER.equals(member.getType()))
101                                {
102                                    return Stream.<User> of(member.getUser());
103                                }
104                                else
105                                {
106                                    return member.getGroup().getUsers().stream().map(_userManager::getUser);
107                                }
108                            });
109                }
110            }
111        }
112        if (previousUser != null)
113        {
114            return previousUser.filter(user -> _notificationPreferenceHelper.askedToBeNotified(user.getIdentity(), activity.getValue(AbstractWorkspacesActivityType.PROJECT_NAME),
115                    Frequency.EACH)).map(User::getEmail).toList();
116        }
117        else
118        {
119            // Something bad happened…
120            return List.of();
121        }
122    }
123    
124    
125    @Override
126    public String getMailBodyURI(Activity activity)
127    {
128        return "cocoon://_plugins/workspaces/notification-mail-member";
129    }
130    
131    @Override
132    public AmetysObject getTargetAmetysObject(Activity activity)
133    {
134        // we don't need this method as we override the AbstractWorkspacesActivityNotifier::getUsersEmailToNotify method
135        return null;
136    }
137}