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