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.Collection; 019import java.util.List; 020import java.util.Map; 021import java.util.Set; 022 023import org.apache.avalon.framework.service.ServiceException; 024import org.apache.avalon.framework.service.ServiceManager; 025 026import org.ametys.cms.data.Binary; 027import org.ametys.plugins.explorer.resources.ModifiableResourceCollection; 028import org.ametys.plugins.explorer.resources.jcr.JCRResourcesCollectionFactory; 029import org.ametys.plugins.repository.data.holder.ModifiableModelAwareDataHolder; 030import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject; 031import org.ametys.plugins.workspaces.AbstractWorkspaceModule; 032import org.ametys.plugins.workspaces.ObservationConstants; 033import org.ametys.plugins.workspaces.project.objects.Project; 034import org.ametys.plugins.workspaces.util.StatisticColumn; 035import org.ametys.plugins.workspaces.util.StatisticsColumnType; 036import org.ametys.runtime.i18n.I18nizableText; 037import org.ametys.web.repository.page.ModifiablePage; 038import org.ametys.web.repository.page.ModifiableZone; 039import org.ametys.web.repository.page.ModifiableZoneItem; 040import org.ametys.web.repository.page.ZoneItem.ZoneType; 041 042import com.google.common.collect.ImmutableSet; 043 044/** 045 * Tasks manager for workspaces 046 */ 047public class TasksWorkspaceModule extends AbstractWorkspaceModule 048{ 049 /** The id of task module */ 050 public static final String TASK_MODULE_ID = TasksWorkspaceModule.class.getName(); 051 052 /** Workspaces tasks list node name */ 053 private static final String __WORKSPACES_TASKS_NODE_NAME = "tasks"; 054 055 /** Workspaces root tasks node name */ 056 private static final String __WORKSPACES_TASKS_ROOT_NODE_NAME = "tasks-root"; 057 058 /** Workspaces root tasks lists node name */ 059 private static final String __WORKSPACES_TASKS_LIST_ROOT_NODE_NAME = "tasks-list-root"; 060 061 private static final String __TASK_NUMBER_HEADER_ID = __WORKSPACES_TASKS_NODE_NAME + "$task_number"; 062 063 /** The tasks module DAO */ 064 private WorkspaceTaskDAO _workspaceTaskDAO; 065 066 @Override 067 public void service(ServiceManager serviceManager) throws ServiceException 068 { 069 super.service(serviceManager); 070 _workspaceTaskDAO = (WorkspaceTaskDAO) serviceManager.lookup(WorkspaceTaskDAO.ROLE); 071 } 072 073 @Override 074 public String getId() 075 { 076 return TASK_MODULE_ID; 077 } 078 079 @Override 080 public String getModuleName() 081 { 082 return __WORKSPACES_TASKS_NODE_NAME; 083 } 084 085 public int getOrder() 086 { 087 return ORDER_TASKS; 088 } 089 090 @Override 091 protected String getModulePageName() 092 { 093 return "tasks"; 094 } 095 096 public I18nizableText getModuleTitle() 097 { 098 return new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_PROJECT_SERVICE_MODULE_TASK_LABEL"); 099 } 100 public I18nizableText getModuleDescription() 101 { 102 return new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_PROJECT_SERVICE_MODULE_TASK_DESCRIPTION"); 103 } 104 @Override 105 protected I18nizableText getModulePageTitle() 106 { 107 return new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_WORKSPACE_PAGE_TASKS_TITLE"); 108 } 109 110 @Override 111 protected void initializeModulePage(ModifiablePage taskPage) 112 { 113 ModifiableZone defaultZone = taskPage.createZone("default"); 114 115 String serviceId = "org.ametys.plugins.workspaces.module.Tasks"; 116 ModifiableZoneItem defaultZoneItem = defaultZone.addZoneItem(); 117 defaultZoneItem.setType(ZoneType.SERVICE); 118 defaultZoneItem.setServiceId(serviceId); 119 120 ModifiableModelAwareDataHolder serviceDataHolder = defaultZoneItem.getServiceParameters(); 121 serviceDataHolder.setValue("xslt", _getDefaultXslt(serviceId)); 122 } 123 124 /** 125 * Get the URI of a task in project'site 126 * @param project The project 127 * @param taskId The id of the task 128 * @return The task uri 129 */ 130 public String getTaskUri(Project project, String taskId) 131 { 132 String moduleUrl = getModuleUrl(project); 133 if (moduleUrl != null) 134 { 135 StringBuilder sb = new StringBuilder(); 136 sb.append(moduleUrl); 137 sb.append("#task-").append(taskId); 138 139 return sb.toString(); 140 } 141 142 return null; 143 } 144 145 /** 146 * Get the root for tasks 147 * @param project The project 148 * @param create true to create root if not exists 149 * @return The root for tasks 150 */ 151 public DefaultTraversableAmetysObject getTasksRoot(Project project, boolean create) 152 { 153 ModifiableResourceCollection moduleRoot = getModuleRoot(project, create); 154 return _getAmetysObject(moduleRoot, __WORKSPACES_TASKS_ROOT_NODE_NAME, JCRResourcesCollectionFactory.RESOURCESCOLLECTION_NODETYPE, create); 155 } 156 157 /** 158 * Get the root for tasks lists 159 * @param project The project 160 * @param create true to create root if not exists 161 * @return The root for tasks lists 162 */ 163 public DefaultTraversableAmetysObject getTasksListsRoot(Project project, boolean create) 164 { 165 ModifiableResourceCollection moduleRoot = getModuleRoot(project, create); 166 return _getAmetysObject(moduleRoot, __WORKSPACES_TASKS_LIST_ROOT_NODE_NAME, JCRResourcesCollectionFactory.RESOURCESCOLLECTION_NODETYPE, create); 167 } 168 169 170 @Override 171 public Set<String> getAllowedEventTypes() 172 { 173 return ImmutableSet.of(ObservationConstants.EVENT_TASK_CREATED, ObservationConstants.EVENT_TASK_ASSIGNED, ObservationConstants.EVENT_TASK_CLOSED_STATUS_CHANGED, ObservationConstants.EVENT_TASK_DELETING); 174 } 175 176 @Override 177 public Map<String, Object> _getInternalStatistics(Project project, boolean isActive) 178 { 179 if (isActive) 180 { 181 return Map.of(__TASK_NUMBER_HEADER_ID, _workspaceTaskDAO.getTasksCount(project)); 182 } 183 else 184 { 185 return Map.of(__TASK_NUMBER_HEADER_ID, __SIZE_INACTIVE); 186 } 187 } 188 189 @Override 190 protected long _getModuleSize(Project project) 191 { 192 return _workspaceTaskDAO.getProjectTasks(project) 193 .stream() 194 .map(Task::getAttachments) 195 .flatMap(Collection::stream) 196 .mapToLong(Binary::getLength) 197 .sum(); 198 } 199 200 @Override 201 public List<StatisticColumn> _getInternalStatisticModel() 202 { 203 return List.of(new StatisticColumn(__TASK_NUMBER_HEADER_ID, new I18nizableText("plugin.workspaces", "PLUGINS_WORKSPACES_PROJECT_STATISTICS_TOOL_COLUMN_TASK_NUMBER")) 204 .withRenderer("Ametys.plugins.workspaces.project.tool.ProjectsGridHelper.renderElements") 205 .withType(StatisticsColumnType.LONG) 206 .withGroup(GROUP_HEADER_ELEMENTS_ID)); 207 } 208 209 @Override 210 protected boolean _showModuleSize() 211 { 212 return true; 213 } 214}