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