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}