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