001/*
002 *  Copyright 2018 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.members;
017
018import java.io.IOException;
019import java.util.Iterator;
020import java.util.List;
021import java.util.Locale;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.cocoon.ProcessingException;
026import org.apache.cocoon.environment.ObjectModelHelper;
027import org.apache.cocoon.environment.Request;
028import org.apache.cocoon.generation.ServiceableGenerator;
029import org.apache.cocoon.xml.AttributesImpl;
030import org.apache.cocoon.xml.XMLUtils;
031import org.apache.commons.lang.StringUtils;
032import org.apache.commons.lang3.ArrayUtils;
033import org.xml.sax.SAXException;
034
035import org.ametys.cms.contenttype.ContentType;
036import org.ametys.cms.contenttype.ContentTypeExtensionPoint;
037import org.ametys.cms.repository.Content;
038import org.ametys.core.group.GroupManager;
039import org.ametys.core.right.RightManager;
040import org.ametys.core.user.User;
041import org.ametys.core.user.UserIdentity;
042import org.ametys.plugins.core.user.UserHelper;
043import org.ametys.plugins.repository.AmetysObjectIterable;
044import org.ametys.plugins.repository.AmetysRepositoryException;
045import org.ametys.plugins.repository.data.holder.ModelAwareDataHolder;
046import org.ametys.plugins.userdirectory.UserDirectoryHelper;
047import org.ametys.plugins.userdirectory.UserDirectoryPageHandler;
048import org.ametys.plugins.workspaces.members.JCRProjectMember.MemberType;
049import org.ametys.plugins.workspaces.members.ProjectMemberManager.ProjectMember;
050import org.ametys.plugins.workspaces.project.ProjectManager;
051import org.ametys.plugins.workspaces.project.objects.Project;
052import org.ametys.runtime.config.Config;
053import org.ametys.runtime.model.View;
054import org.ametys.web.WebConstants;
055import org.ametys.web.repository.page.Page;
056import org.ametys.web.repository.page.ZoneItem;
057import org.ametys.web.usermanagement.UserSignUpConfiguration;
058
059/**
060 * Generator used sax project member
061 */
062public class ProjectMembersGenerator extends ServiceableGenerator
063{
064    /** The project manager component */
065    protected ProjectManager _projectManager;
066    
067    /** The project member manager */
068    protected ProjectMemberManager _projectMemberManager;
069    
070    /** The user helper */
071    protected UserHelper _userHelper;
072    
073    /** The user directory helper */
074    protected UserDirectoryHelper _userDirectoryHelper;
075    
076    /** The content type extension point */
077    protected ContentTypeExtensionPoint _cTypeEP;
078    
079    /** The group manager */
080    protected GroupManager _groupManager;
081
082    /** The sign up configuration */
083    protected UserSignUpConfiguration _signupConfig;
084
085    /** The right manager */
086    protected RightManager _rightManager;
087
088    @Override
089    public void service(ServiceManager serviceManager) throws ServiceException
090    {
091        _projectManager = (ProjectManager) serviceManager.lookup(ProjectManager.ROLE);
092        _projectMemberManager = (ProjectMemberManager) serviceManager.lookup(ProjectMemberManager.ROLE);
093        _userHelper = (UserHelper) serviceManager.lookup(UserHelper.ROLE);
094        _userDirectoryHelper = (UserDirectoryHelper) serviceManager.lookup(UserDirectoryHelper.ROLE);
095        _cTypeEP = (ContentTypeExtensionPoint) serviceManager.lookup(ContentTypeExtensionPoint.ROLE);
096        _groupManager = (GroupManager) serviceManager.lookup(GroupManager.ROLE);
097        _signupConfig = (UserSignUpConfiguration) serviceManager.lookup(UserSignUpConfiguration.ROLE);
098        _rightManager = (RightManager) serviceManager.lookup(RightManager.ROLE);
099    }
100
101    @Override
102    public void generate() throws IOException, SAXException, ProcessingException
103    {
104        Request request = ObjectModelHelper.getRequest(objectModel);
105        
106        Page page = (Page) request.getAttribute(WebConstants.REQUEST_ATTR_PAGE);
107        String lang = page.getSitemapName();
108        
109        ZoneItem zoneItem = (ZoneItem) request.getAttribute(WebConstants.REQUEST_ATTR_ZONEITEM);
110        ModelAwareDataHolder serviceParameters2018 = zoneItem.getServiceParameters();
111        
112        long maxNbMembers = serviceParameters2018.getValue("nbMembers", false, -1L);
113        boolean expandGroup = serviceParameters2018.getValue("expandGroup", false, false);
114        
115        contentHandler.startDocument();
116        
117        List<Project> projects = _projectManager.getProjectsForSite(page.getSite());
118        Project project = projects.isEmpty() ? null : projects.get(0);
119        
120        if (project == null)
121        {
122            throw new IllegalArgumentException("There is no project for site " + page.getSiteName());
123        }
124        
125        try
126        {
127            List<ProjectMember> members = _projectMemberManager.getProjectMembers(project, expandGroup);
128            
129            AttributesImpl attrs = new AttributesImpl();
130            attrs.addCDATAAttribute("nbMembers", String.valueOf(members.size()));
131            
132            String memberPageId = _getMembersPageId(project, lang);
133            if (memberPageId != null)
134            {
135                attrs.addCDATAAttribute("memberPageId", memberPageId);
136            }
137            
138            String siteName = Config.getInstance().getValue("workspaces.member.userdirectory.site.name");
139            if (StringUtils.isNotEmpty(siteName))
140            {
141                attrs.addCDATAAttribute("userDirectorySiteName", siteName);
142            }
143            XMLUtils.startElement(contentHandler, "project", attrs);
144            
145            UserIdentity[] managers = project.getManagers();
146            
147            int count = 0;
148            Iterator<ProjectMember> it = members.iterator();
149            while (it.hasNext() && (maxNbMembers < 1 || count < maxNbMembers))
150            {
151                ProjectMember member = it.next();
152                _saxMember(member, managers, lang);
153                count++;
154            }
155            
156            XMLUtils.endElement(contentHandler, "project");
157        }
158        catch (IllegalAccessException | AmetysRepositoryException e)
159        {
160            throw new ProcessingException("Unable to get project members", e);
161        }
162        
163        contentHandler.endDocument();
164    }
165    
166    /**
167     * Get the id of member page if exists and current user has access
168     * @param project The project
169     * @param lang the language
170     * @return the id of member page. Can be null.
171     */
172    protected String _getMembersPageId(Project project, String lang)
173    {
174        AmetysObjectIterable<Page> memberPages = _projectManager.getModulePages(project, MembersWorkspaceModule.MEMBERS_MODULE_ID, lang);
175        
176        if (memberPages.getSize() > 0)
177        {
178            Page memberPage = memberPages.iterator().next();
179            
180            if (_rightManager.currentUserHasReadAccess(memberPage))
181            {
182                return memberPage.getId();
183            }
184        }
185        
186        return null;
187    }
188    /**
189     * SAX a member
190     * @param member the member
191     * @param managers the user identities of project's manager
192     * @param lang the current language
193     * @throws SAXException if an error occurred while saxing
194     * @throws AmetysRepositoryException if an error occurred
195     * @throws IOException if failed to sax user content
196     */
197    protected void _saxMember (ProjectMember member, UserIdentity[] managers, String lang) throws SAXException, AmetysRepositoryException, IOException
198    {
199        AttributesImpl attrs = new AttributesImpl();
200        attrs.addCDATAAttribute("manager", String.valueOf(member.isManager()));
201        
202        if (member.isManager())
203        {
204            // Get the position of this manager
205            int position = ArrayUtils.indexOf(managers, member.getUser().getIdentity());
206            attrs.addCDATAAttribute("managerPosition", String.valueOf(position + 1));
207        }
208        
209        attrs.addCDATAAttribute("type", member.getType().toString());
210        
211        XMLUtils.startElement(contentHandler, "member", attrs);
212        
213        XMLUtils.createElement(contentHandler, "title", member.getTitle());
214        XMLUtils.createElement(contentHandler, "sortabletitle", member.getSortableTitle());
215        String role = member.getRole();
216        if (StringUtils.isNotBlank(role))
217        {
218            XMLUtils.createElement(contentHandler, "role", role);
219        }
220        
221        if (member.getType().equals(MemberType.USER))
222        {
223            User user = member.getUser();
224            _saxUser(user, lang);
225        }
226        
227        XMLUtils.endElement(contentHandler, "member");
228    }
229    
230    /**
231     * Sax user
232     * @param user the user 
233     * @param lang the lang
234     * @throws SAXException if an error occurs saxing data
235     * @throws AmetysRepositoryException if an repository error occurs
236     * @throws IOException if an IO exception error occurs
237     */
238    protected void _saxUser(User user, String lang) throws SAXException, AmetysRepositoryException, IOException
239    {
240        XMLUtils.startElement(contentHandler, "user");
241        _userHelper.saxUser(user, contentHandler, "info");
242        Content userContent = _userDirectoryHelper.getUserContent(user.getIdentity(), lang);
243        if (userContent != null)
244        {
245            AttributesImpl contentAttrs = new AttributesImpl();
246            contentAttrs.addCDATAAttribute("id", userContent.getId());
247            XMLUtils.startElement(contentHandler, "content", contentAttrs);
248            ContentType contentType = _cTypeEP.getExtension(UserDirectoryPageHandler.ABSTRACT_USER_CONTENT_TYPE);
249            View view = contentType.getView("abstract");
250            userContent.dataToSAX(contentHandler, view, new Locale(lang));
251            XMLUtils.endElement(contentHandler, "content");
252        }
253        XMLUtils.endElement(contentHandler, "user");
254        
255    }
256}