001/*
002 *  Copyright 2019 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.core.impl.group.directory;
017
018import java.util.Comparator;
019import java.util.HashMap;
020import java.util.HashSet;
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024import java.util.function.Predicate;
025import java.util.stream.Collectors;
026import java.util.stream.Stream;
027
028import org.apache.commons.lang3.StringUtils;
029
030import org.ametys.core.group.Group;
031import org.ametys.core.group.GroupIdentity;
032import org.ametys.core.group.directory.GroupDirectory;
033import org.ametys.core.user.UserIdentity;
034import org.ametys.runtime.i18n.I18nizableText;
035import org.ametys.runtime.plugin.component.AbstractLogEnabled;
036/**
037 * Static implementation of a {@link GroupDirectory}
038 */
039public class StaticGroupDirectory extends AbstractLogEnabled implements GroupDirectory
040{
041    private static final String __PARAMETER_GROUPS_DEFINITION = "runtime.groups.static.group";
042    
043    private String _id;
044    private I18nizableText _label;
045    private String _gdModelId;
046    private Map<String, Object> _params;
047
048    private Map<String, Group> _groups;
049    
050    @Override
051    public String getId()
052    {
053        return _id;
054    }
055
056    @Override
057    public I18nizableText getLabel()
058    {
059        return _label;
060    }
061
062    @Override
063    public void setId(String id)
064    {
065        _id = id;
066    }
067
068    @Override
069    public void setLabel(I18nizableText label)
070    {
071        _label = label;
072    }
073
074    @Override
075    public String getGroupDirectoryModelId()
076    {
077        return _gdModelId;
078    }
079
080    @Override
081    public Map<String, Object> getParameterValues()
082    {
083        return _params;
084    }
085
086    @Override
087    public void init(String groupDirectoryModelId, Map<String, Object> paramValues) throws Exception
088    {
089        _gdModelId = groupDirectoryModelId;
090        _groups = new HashMap<>();
091        _params = paramValues;
092        String groupsAsText = (String) paramValues.get(__PARAMETER_GROUPS_DEFINITION);
093        for (String groupLine : groupsAsText.split("\\n"))
094        {
095            if (StringUtils.isNotEmpty(groupLine))
096            {
097                String[] groupSplited = groupLine.split(":");
098                if (groupSplited.length == 0)
099                {
100                    getLogger().error("Error while reading StaticGroupDirectory groups, cannot create a group with the data from line {}", groupLine);
101                }
102                else
103                {
104                    String groupId = groupSplited[0];
105                    String label = groupSplited[groupSplited.length > 1 ? 1 : 0];
106                    Set<UserIdentity> users = new HashSet<>();
107                    for (int i = 2; i < groupSplited.length; i++)
108                    {
109                        String userLogin = groupSplited[i].indexOf("#") > -1 ? StringUtils.substringBefore(groupSplited[i], "#") : groupSplited[i];
110                        String userPopulation = groupSplited[i].indexOf("#") > -1 ? StringUtils.substringAfter(groupSplited[i], "#") : null;
111                        users.add(new UserIdentity(userLogin, userPopulation));
112                    }
113                    _groups.put(groupId, new StaticGroup(groupId, _id, label, this, users));
114                }
115            }
116        }
117        
118    }
119
120    @Override
121    public Group getGroup(String groupID)
122    {
123        return _groups.getOrDefault(groupID, null);
124    }
125
126    @Override
127    public Set<Group> getGroups()
128    {
129        return new HashSet<>(_groups.values());
130    }
131
132    @Override
133    public Set<String> getUserGroups(UserIdentity userIdentity)
134    {
135        return _groups.values().stream()
136                .filter(group -> group.getUsers().contains(userIdentity))
137                .map(Group::getIdentity)
138                .map(GroupIdentity::getId)
139                .collect(Collectors.toSet());
140    }
141
142    @Override
143    public List<Group> getGroups(int count, int offset, Map parameters)
144    {
145        String pattern = (String) parameters.get("pattern");
146        boolean sort = (boolean) parameters.getOrDefault("sort", false);
147        Predicate<Group> matchesPattern = group ->
148            StringUtils.isEmpty(pattern) 
149                || group.getLabel().toLowerCase().indexOf(pattern.toLowerCase()) != -1 
150                || (group.getIdentity() != null && group.getIdentity().getId().toLowerCase().indexOf(pattern.toLowerCase()) != -1);
151            
152        Stream<Group> groupsStream = _groups.values().stream()
153                .filter(matchesPattern);
154        if (sort)
155        {
156            groupsStream = groupsStream.sorted(Comparator.comparing(Group::getLabel, String.CASE_INSENSITIVE_ORDER));
157        }
158        return groupsStream
159                .skip(offset)
160                .limit(count)
161                .collect(Collectors.toList());
162    }
163
164    private static final class StaticGroup implements Group
165    {
166        private GroupIdentity _identity;
167        private String _label;
168        private GroupDirectory _groupDirectory;
169        private Set<UserIdentity> _users;
170
171        StaticGroup(String id, String directoryId, String label, GroupDirectory groupDirectory, Set<UserIdentity> users)
172        {
173            _identity = new GroupIdentity(id, directoryId);
174            _label = label;
175            _groupDirectory = groupDirectory;
176            _users = users;
177        }
178        
179        public GroupIdentity getIdentity()
180        {
181            return _identity;
182        }
183
184        public String getLabel()
185        {
186            return _label;
187        }
188
189        public GroupDirectory getGroupDirectory()
190        {
191            return _groupDirectory;
192        }
193
194        public Set<UserIdentity> getUsers()
195        {
196            return _users;
197        }
198        
199    }
200}