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;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022import java.util.Set;
023
024import org.apache.cocoon.components.ContextHelper;
025import org.apache.cocoon.environment.Request;
026import org.apache.commons.lang.IllegalClassException;
027
028import org.ametys.core.right.RightManager.RightResult;
029import org.ametys.core.ui.Callable;
030import org.ametys.core.user.UserIdentity;
031import org.ametys.plugins.explorer.ExplorerNode;
032import org.ametys.plugins.explorer.resources.ModifiableResourceCollection;
033import org.ametys.plugins.explorer.resources.jcr.JCRResourcesCollectionFactory;
034import org.ametys.plugins.explorer.tasks.jcr.JCRTasksDAO;
035import org.ametys.plugins.explorer.tasks.jcr.JCRTasksListFactory;
036import org.ametys.plugins.repository.AmetysRepositoryException;
037import org.ametys.plugins.repository.data.holder.ModifiableModelAwareDataHolder;
038import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject;
039import org.ametys.plugins.workspaces.AbstractWorkspaceModule;
040import org.ametys.plugins.workspaces.project.objects.Project;
041import org.ametys.runtime.i18n.I18nizableText;
042import org.ametys.web.repository.page.ModifiablePage;
043import org.ametys.web.repository.page.ModifiableZone;
044import org.ametys.web.repository.page.ModifiableZoneItem;
045import org.ametys.web.repository.page.ZoneItem.ZoneType;
046
047import com.google.common.collect.ImmutableSet;
048
049/**
050 * Tasks manager for workspaces
051 */
052public class TasksWorkspaceModule extends AbstractWorkspaceModule
053{
054    /** The id of task module */
055    public static final String TASK_MODULE_ID = TasksWorkspaceModule.class.getName();
056    
057    /** Workspaces tasks list node name */
058    private static final String __WORKSPACES_TASKS_NODE_NAME = "tasks";
059    
060    /** Workspaces default tasks list node name */
061    private static final String __WORKSPACES_TASKS_DEFAULT_NODE_NAME = "default";
062
063    @Override
064    public String getId()
065    {
066        return TASK_MODULE_ID;
067    }
068    
069    @Override
070    public String getModuleName()
071    {
072        return __WORKSPACES_TASKS_NODE_NAME;
073    }
074    
075    public int getOrder()
076    {
077        return ORDER_TASKS;
078    }
079    
080    @Override
081    protected String getModulePageName()
082    {
083        return "tasks";
084    }
085    
086    public I18nizableText getModuleTitle()
087    {
088        return new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_PROJECT_SERVICE_MODULE_TASK_LABEL");
089    }
090    public I18nizableText getModuleDescription()
091    {
092        return new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_PROJECT_SERVICE_MODULE_TASK_DESCRIPTION");
093    }
094    @Override
095    protected I18nizableText getModulePageTitle()
096    {
097        return new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_WORKSPACE_PAGE_TASKS_TITLE");
098    }
099    
100    @Override
101    protected void initializeModulePage(ModifiablePage taskPage)
102    {
103        ModifiableZone defaultZone = taskPage.createZone("default");
104        
105        String serviceId = "org.ametys.plugins.workspaces.module.Tasks";
106        ModifiableZoneItem defaultZoneItem = defaultZone.addZoneItem();
107        defaultZoneItem.setType(ZoneType.SERVICE);
108        defaultZoneItem.setServiceId(serviceId);
109        
110        ModifiableModelAwareDataHolder serviceDataHolder = defaultZoneItem.getServiceParameters();
111        serviceDataHolder.setValue("xslt", _getDefaultXslt(serviceId));
112    }
113
114    /**
115     * Retrieves the rights for the current user in the project
116     * @return The project
117     */
118    @Callable
119    public Map<String, Object> getTasksModuleRights()
120    {
121        Map<String, Object> rights = new HashMap<>();
122        
123        Request request = ContextHelper.getRequest(_context);
124        String projectName = (String) request.getAttribute("projectName");
125        Project project = _projectManager.getProject(projectName);
126        ModifiableResourceCollection tasksRoot = getModuleRoot(project, false);
127        
128        UserIdentity currentUser = _currentUserProvider.getUser();
129        rights.put("view", tasksRoot != null && _rightManager.hasRight(currentUser, JCRTasksDAO.RIGHTS_VIEW_TASKS, tasksRoot) == RightResult.RIGHT_ALLOW);
130        rights.put("add", tasksRoot != null && _rightManager.hasRight(currentUser, JCRTasksDAO.RIGHTS_ADD_TASK, tasksRoot) == RightResult.RIGHT_ALLOW);
131        
132        return rights;
133    }
134    
135    /**
136     * Retrieves the rights for the current user in the projects list
137     * @param projectNames The name of projects to checks rights from
138     * @return The rights data
139     */
140    @Callable
141    public Map<String, Object> getTasksServiceRights(List<String> projectNames)
142    {
143        Map<String, Object> rights = new HashMap<>();
144        
145        List<String> rightAdd = new ArrayList<>();
146        
147        UserIdentity currentUser = _currentUserProvider.getUser();
148        for (String projectName : projectNames)
149        {
150            Project project = _projectManager.getProject(projectName);
151            ModifiableResourceCollection tasksRoot = getModuleRoot(project, false);
152            
153            if (tasksRoot != null && _rightManager.hasRight(currentUser, JCRTasksDAO.RIGHTS_ADD_TASK, tasksRoot) == RightResult.RIGHT_ALLOW)
154            {
155                rightAdd.add(projectName);
156            }
157        }
158        
159        rights.put("add", rightAdd);
160        
161        return rights;
162    }
163    
164    /**
165     * Get the URI of a task in project'site
166     * @param project The project
167     * @param taskId The id of the task
168     * @return The thread uri
169     */
170    public String getTaskUri(Project project, String taskId)
171    {
172        String moduleUrl = getModuleUrl(project);
173        if (moduleUrl != null)
174        {
175            StringBuilder sb = new StringBuilder();
176            sb.append(moduleUrl);
177            sb.append("#").append(taskId);
178            
179            return sb.toString();
180        }
181        
182        return null;
183    }
184    
185    @Override
186    public ModifiableResourceCollection getModuleRoot(Project project, boolean create)
187    {
188        try
189        {
190            ExplorerNode projectRootNode = project.getExplorerRootNode();
191            
192            if (projectRootNode instanceof ModifiableResourceCollection)
193            {
194                ModifiableResourceCollection projectRootNodeRc = (ModifiableResourceCollection) projectRootNode;
195                return _getAmetysObject(projectRootNodeRc, __WORKSPACES_TASKS_NODE_NAME, JCRResourcesCollectionFactory.RESOURCESCOLLECTION_NODETYPE, create);
196            }
197            else
198            {
199                throw new IllegalClassException(ModifiableResourceCollection.class, projectRootNode.getClass());
200            }
201        }
202        catch (AmetysRepositoryException e)
203        {
204            throw new AmetysRepositoryException("Error getting the documents root node.", e);
205        }
206    }
207    
208    /**
209     * Get the root for tasks
210     * @param project The project
211     * @param create true to create root if not exists
212     * @return The root for tasks
213     */
214    public DefaultTraversableAmetysObject getTasksRoot(Project project, boolean create)
215    {
216        ModifiableResourceCollection moduleRoot = getModuleRoot(project, create);
217        return _getAmetysObject(moduleRoot, __WORKSPACES_TASKS_DEFAULT_NODE_NAME, JCRTasksListFactory.TASKS_LIST_NODETYPE, create);
218    }
219
220    @Override
221    public Set<String> getAllowedEventTypes()
222    {
223        return ImmutableSet.of("task.created", "task.assigned", "task.status.changed");
224    }
225}