001/*
002 *  Copyright 2021 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.Arrays;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023import java.util.stream.Collectors;
024
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.cocoon.ProcessingException;
028import org.apache.cocoon.environment.ObjectModelHelper;
029import org.apache.cocoon.environment.Request;
030import org.apache.cocoon.generation.ServiceableGenerator;
031import org.apache.cocoon.xml.XMLUtils;
032import org.apache.commons.lang3.StringUtils;
033import org.xml.sax.SAXException;
034
035import org.ametys.cms.repository.Content;
036import org.ametys.core.user.CurrentUserProvider;
037import org.ametys.core.user.UserIdentity;
038import org.ametys.plugins.workspaces.catalog.CatalogSiteType;
039import org.ametys.plugins.workspaces.members.JCRProjectMember.MemberType;
040import org.ametys.plugins.workspaces.project.ProjectManager;
041import org.ametys.plugins.workspaces.project.ProjectsCatalogueManager;
042import org.ametys.plugins.workspaces.project.favorites.FavoritesHelper;
043import org.ametys.plugins.workspaces.project.objects.Project;
044import org.ametys.web.WebHelper;
045import org.ametys.web.repository.site.Site;
046import org.ametys.web.repository.site.SiteManager;
047
048/**
049 * Sax the public and moderated projects of current member content
050 *
051 */
052public class MemberProjectsGenerator extends ServiceableGenerator
053{
054    /** The project manager */
055    protected ProjectManager _projectManager;
056    /** The project catalog manager */
057    protected ProjectsCatalogueManager _projectCatalogManager;
058    /** The current user provider */
059    protected CurrentUserProvider _currentUserProvider;
060    /** To handle favorites */
061    protected FavoritesHelper _favoritesHelper;
062    private SiteManager _siteManager;
063
064    @Override
065    public void service(ServiceManager smanager) throws ServiceException
066    {
067        super.service(smanager);
068        _projectManager = (ProjectManager) smanager.lookup(ProjectManager.ROLE);
069        _projectCatalogManager = (ProjectsCatalogueManager) smanager.lookup(ProjectsCatalogueManager.ROLE);
070        _currentUserProvider = (CurrentUserProvider) smanager.lookup(CurrentUserProvider.ROLE);
071        _favoritesHelper = (FavoritesHelper) manager.lookup(FavoritesHelper.ROLE);
072        _siteManager = (SiteManager) manager.lookup(SiteManager.ROLE);
073    }
074
075    public void generate() throws IOException, SAXException, ProcessingException
076    {
077        contentHandler.startDocument();
078        
079        XMLUtils.startElement(contentHandler, "projects");
080        
081        Request request = ObjectModelHelper.getRequest(objectModel);
082        
083        boolean userContent = parameters.getParameterAsBoolean("userContent", false);
084        
085        // If generator is used for a user content, check if it's a catalog site to avoid saxing projects in non-catalog sites which may cause performance issue
086        // Otherwise no site check needed as only projects of connected user are saxed
087        if (!userContent || _isCatalogSite(request)) 
088        {
089            UserIdentity user = _getUser(request, userContent);
090            if (user != null)
091            {
092                // The filtered projects' categories
093                Set<String> filteredCategories = _getFilteredCategories(request);
094                
095                // Pattern filter
096                String pattern = request.getParameter("pattern");
097                
098                boolean excludePrivate = parameters.getParameterAsBoolean("excludePrivate", false);
099                
100                Map<Project, MemberType> userProjects = _projectManager.getUserProjects(user, filteredCategories, null, pattern, false, excludePrivate);
101                
102                Set<String> favorites = _favoritesHelper.getFavorites(user);
103                
104                List<Project> projects = userProjects.keySet()
105                        .stream()
106                        .collect(Collectors.toList());
107                
108                int maxMembers = parameters.getParameterAsInteger("maxMembers", Integer.MAX_VALUE);
109                boolean withMembers = parameters.getParameterAsBoolean("withMembers", false);
110                boolean expandGroup = parameters.getParameterAsBoolean("expandGroup", false);
111                
112                for (Project project : projects)
113                {
114                    _projectCatalogManager.saxProject(contentHandler, project, withMembers, expandGroup, maxMembers, favorites.contains(project.getName()));
115                }
116            }
117        }
118        
119        XMLUtils.endElement(contentHandler, "projects");
120        contentHandler.endDocument();
121    }
122    
123    private boolean _isCatalogSite(Request request)
124    {
125        String siteName = WebHelper.getSiteName(request);
126        Site site = _siteManager.getSite(siteName);
127        return site != null && CatalogSiteType.TYPE_ID.equals(site.getType());
128    }
129    
130    private UserIdentity _getUser(Request request, boolean userContent)
131    {
132        if (userContent)
133        {
134            // Get user from user content
135            Content content = (Content) request.getAttribute(Content.class.getName());
136            return content.getValue("user");
137        }
138        else
139        {
140            // Get connected user
141            return _currentUserProvider.getUser();
142        }
143    }
144    
145    private Set<String> _getFilteredCategories(Request request)
146    {
147        String[] categoryIds = request.getParameterValues("categories");
148        if (categoryIds != null)
149        {
150            return Arrays.stream(categoryIds)
151                    .filter(StringUtils::isNotEmpty)
152                    .collect(Collectors.toSet());
153        }
154        else
155        {
156            return Set.of();
157        }
158    }
159}