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