001/*
002 *  Copyright 2016 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.tasks.generators;
017
018import java.io.IOException;
019import java.util.Set;
020import java.util.stream.Stream;
021
022import org.apache.avalon.framework.context.Context;
023import org.apache.avalon.framework.context.ContextException;
024import org.apache.avalon.framework.context.Contextualizable;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.cocoon.ProcessingException;
028import org.apache.cocoon.generation.ServiceableGenerator;
029import org.apache.cocoon.xml.AttributesImpl;
030import org.apache.cocoon.xml.XMLUtils;
031import org.xml.sax.SAXException;
032
033import org.ametys.core.user.User;
034import org.ametys.core.user.UserManager;
035import org.ametys.core.util.LambdaUtils;
036import org.ametys.plugins.core.user.UserHelper;
037import org.ametys.plugins.explorer.tasks.Task;
038import org.ametys.plugins.explorer.tasks.Task.TaskPriority;
039import org.ametys.plugins.explorer.tasks.Task.TaskStatus;
040import org.ametys.plugins.explorer.tasks.jcr.JCRTask;
041import org.ametys.plugins.explorer.tasks.jcr.JCRTasksDAO.TaskListResult;
042import org.ametys.plugins.workspaces.project.ProjectManager;
043import org.ametys.plugins.workspaces.project.ProjectsCatalogueManager;
044import org.ametys.plugins.workspaces.project.modules.WorkspaceModule;
045import org.ametys.plugins.workspaces.project.modules.WorkspaceModuleExtensionPoint;
046import org.ametys.plugins.workspaces.project.objects.Project;
047import org.ametys.plugins.workspaces.tasks.TasksWorkspaceModule;
048import org.ametys.plugins.workspaces.tasks.WorkspaceTaskDAO;
049import org.ametys.web.repository.page.Page;
050
051import com.google.common.collect.Iterables;
052
053/**
054 * Task list generator for the simple service.
055 */
056public class TaskListGenerator extends ServiceableGenerator implements Contextualizable
057{
058    /** The project manager */
059    protected ProjectManager _projectManager;
060    
061    /** The project calaog manager */
062    protected ProjectsCatalogueManager _projectCatalogManager;
063    
064    /** The user manager */
065    protected UserManager _userManager;
066    
067    /** The user helper */
068    protected UserHelper _userHelper;
069    
070    /** Avalon context */
071    protected Context _context;
072
073    private WorkspaceTaskDAO _taskDAO;
074
075    private WorkspaceModuleExtensionPoint _moduleEP;
076
077    
078    @Override
079    public void contextualize(Context context) throws ContextException
080    {
081        _context = context;
082    }
083    
084    @Override
085    public void service(ServiceManager serviceManager) throws ServiceException
086    {
087        _projectManager = (ProjectManager) serviceManager.lookup(ProjectManager.ROLE);
088        _taskDAO = (WorkspaceTaskDAO) serviceManager.lookup(WorkspaceTaskDAO.ROLE);
089        _userManager = (UserManager) serviceManager.lookup(UserManager.ROLE);
090        _userHelper = (UserHelper) serviceManager.lookup(UserHelper.ROLE);
091        _moduleEP = (WorkspaceModuleExtensionPoint) serviceManager.lookup(WorkspaceModuleExtensionPoint.ROLE);
092        _projectCatalogManager = (ProjectsCatalogueManager) serviceManager.lookup(ProjectsCatalogueManager.ROLE);
093    }
094    
095    @Override
096    public void generate() throws IOException, SAXException, ProcessingException
097    {
098        int max = parameters.getParameterAsInteger("max-results", 0);
099        
100        TaskListResult taskListResult = _taskDAO.getProjectTaskList(null, true, true, null, null, null, JCRTask.METADATA_ENDDATE, true);
101        
102        Stream<Task> taskStream = taskListResult.getTasks().stream()
103            .filter(task ->
104            {
105                // filter out ended tasks
106                return !TaskStatus.ENDED.equals(task.getStatus());
107            });
108        
109        // limit
110        if (max > 0)
111        {
112            taskStream = taskStream.limit(max);
113        }
114        
115        // SAX the tasks
116        contentHandler.startDocument();
117        XMLUtils.startElement(contentHandler, "tasks");
118        
119        taskStream.forEach(task ->
120        {
121            // Retrieving info on the project of the task
122            Project project = _projectManager.getParentProject(task);
123            this._saxTask(project, task);
124        });
125        
126        XMLUtils.endElement(contentHandler, "tasks");
127        contentHandler.endDocument();
128    }
129    
130    /**
131     * SAX necessary task properties for the simple task list service.
132     * @param project the parent roject
133     * @param task The task
134     */
135    protected void _saxTask(Project project, Task task)
136    {
137        try
138        {
139            AttributesImpl attrs = new AttributesImpl();
140            
141            attrs.addCDATAAttribute("id", task.getId());
142            
143            String pageId = _getTaskPageId(project);
144            if (pageId != null)
145            {
146                attrs.addCDATAAttribute("pageId", pageId);
147            }
148            XMLUtils.startElement(contentHandler, "task", attrs);
149            
150            // project
151            attrs.clear();
152            attrs.addCDATAAttribute("id", project.getId());
153            String siteUrl = Iterables.getFirst(_projectManager.getProjectUrls(project), null);
154            if (siteUrl != null)
155            {
156                attrs.addCDATAAttribute("url", siteUrl);
157            }
158            XMLUtils.createElement(contentHandler, "project", project.getTitle());
159            
160            _projectCatalogManager.saxCategory(contentHandler, project, "projectCategory");
161            
162            XMLUtils.createElement(contentHandler, "title", task.getLabel());
163            
164            // priority
165            TaskPriority priority = task.getPriority();
166            attrs.clear();
167            attrs.addCDATAAttribute("name", priority.toString());
168            XMLUtils.startElement(contentHandler, "priority", attrs);
169            priority.getLabel().toSAX(contentHandler);
170            XMLUtils.endElement(contentHandler, "priority");
171            
172            // status
173            TaskStatus status = task.getStatus();
174            attrs.clear();
175            attrs.addCDATAAttribute("name", status.toString());
176            XMLUtils.startElement(contentHandler, "status", attrs);
177            status.getLabel().toSAX(contentHandler);
178            XMLUtils.endElement(contentHandler, "status");
179            
180            // assignments
181            XMLUtils.startElement(contentHandler, "assignments");
182            
183            task.getAssignment().stream().forEach(LambdaUtils.wrapConsumer(userIdentity ->
184            {
185                User user = _userManager.getUser(userIdentity);
186                if (user != null)
187                {
188                    _userHelper.saxUser(user, contentHandler);
189                }
190            }));
191            
192            XMLUtils.endElement(contentHandler, "assignments");
193            
194            XMLUtils.endElement(contentHandler, "task");
195        }
196        catch (SAXException e)
197        {
198            throw new RuntimeException("An error occurred while gathering the tasks' information.");
199        }
200    }
201    
202    private String _getTaskPageId (Project project)
203    {
204        WorkspaceModule module = _moduleEP.getModule(TasksWorkspaceModule.TASK_MODULE_ID);
205        Set<Page> taskModulePages = _projectManager.getModulePages(project, module);
206        if (!taskModulePages.isEmpty())
207        {
208            return taskModulePages.iterator().next().getId();
209        }
210        
211        return null;
212    }
213}