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}