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}