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.documents; 017 018import java.util.HashMap; 019import java.util.List; 020import java.util.Map; 021import java.util.Set; 022 023import org.apache.avalon.framework.context.Context; 024import org.apache.avalon.framework.context.ContextException; 025import org.apache.cocoon.components.ContextHelper; 026import org.apache.cocoon.environment.Request; 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.ObservationConstants; 032import org.ametys.plugins.explorer.resources.ModifiableResourceCollection; 033import org.ametys.plugins.explorer.resources.Resource; 034import org.ametys.plugins.explorer.resources.ResourceCollection; 035import org.ametys.plugins.repository.AmetysObject; 036import org.ametys.plugins.repository.data.holder.ModifiableModelAwareDataHolder; 037import org.ametys.plugins.workspaces.AbstractWorkspaceModule; 038import org.ametys.plugins.workspaces.project.objects.Project; 039import org.ametys.plugins.workspaces.util.StatisticColumn; 040import org.ametys.plugins.workspaces.util.StatisticsColumnType; 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 * Helper component for managing documents 051 */ 052public class DocumentWorkspaceModule extends AbstractWorkspaceModule 053{ 054 /** The id of document module */ 055 public static final String DOCUMENT_MODULE_ID = DocumentWorkspaceModule.class.getName(); 056 057 /** Workspaces documents node name */ 058 public static final String WORKSPACES_DOCUMENTS_NODE_NAME = "documents"; 059 060 private static final String __DOCUMENT_NUMBER_HEADER_ID = WORKSPACES_DOCUMENTS_NODE_NAME + "$document_number"; 061 062 @Override 063 public void contextualize(Context context) throws ContextException 064 { 065 _context = context; 066 } 067 068 @Override 069 public String getId() 070 { 071 return DOCUMENT_MODULE_ID; 072 } 073 074 @Override 075 public String getModuleName() 076 { 077 return WORKSPACES_DOCUMENTS_NODE_NAME; 078 } 079 080 public int getOrder() 081 { 082 return ORDER_DOCUMENTS; 083 } 084 085 @Override 086 protected String getModulePageName() 087 { 088 return "documents"; 089 } 090 091 public I18nizableText getModuleTitle() 092 { 093 return new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_SERVICE_MODULE_DOCUMENT_LABEL"); 094 } 095 public I18nizableText getModuleDescription() 096 { 097 return new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_SERVICE_MODULE_DOCUMENT_DESCRIPTION"); 098 } 099 @Override 100 protected I18nizableText getModulePageTitle() 101 { 102 return new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_WORKSPACE_PAGE_DOCUMENTS_TITLE"); 103 } 104 105 @Override 106 protected void initializeModulePage(ModifiablePage documentPage) 107 { 108 ModifiableZone defaultZone = documentPage.createZone("default"); 109 110 String serviceId = "org.ametys.plugins.workspaces.module.Document"; 111 ModifiableZoneItem defaultZoneItem = defaultZone.addZoneItem(); 112 defaultZoneItem.setType(ZoneType.SERVICE); 113 defaultZoneItem.setServiceId(serviceId); 114 115 ModifiableModelAwareDataHolder serviceDataHolder = defaultZoneItem.getServiceParameters(); 116 serviceDataHolder.setValue("xslt", _getDefaultXslt(serviceId)); 117 } 118 119 /** 120 * Get the URI of a folder in project'site 121 * @param project The project 122 * @param collectionId The id of collection 123 * @return The thread uri 124 */ 125 public String getFolderUri(Project project, String collectionId) 126 { 127 String moduleUrl = getModuleUrl(project); 128 if (moduleUrl != null) 129 { 130 StringBuilder sb = new StringBuilder(); 131 sb.append(moduleUrl); 132 sb.append("#").append(collectionId); 133 134 return sb.toString(); 135 } 136 137 return null; 138 } 139 140 /** 141 * Retrieves the set of general rights used in the document module for the current user 142 * @return The map of right data. Keys are the rights id, and values indicates whether the current user has the right or not. 143 */ 144 @Callable 145 public Map<String, Object> getModuleBaseRights() 146 { 147 Request request = ContextHelper.getRequest(_context); 148 149 String projectName = (String) request.getAttribute("projectName"); 150 Project project = _projectManager.getProject(projectName); 151 152 ModifiableResourceCollection documentRoot = getModuleRoot(project, false); 153 154 Map<String, Object> rightsData = new HashMap<>(); 155 UserIdentity user = _currentUserProvider.getUser(); 156 157 // Add file / folder 158 rightsData.put("add-file", _rightManager.hasRight(user, "Plugin_Explorer_File_Add", documentRoot) == RightResult.RIGHT_ALLOW); 159 rightsData.put("add-folder", _rightManager.hasRight(user, "Plugin_Explorer_Folder_Add", documentRoot) == RightResult.RIGHT_ALLOW); 160 rightsData.put("add-cmis-folder", _rightManager.hasRight(user, "Plugin_Explorer_CMIS_Add", documentRoot) == RightResult.RIGHT_ALLOW); 161 162 // Tags 163 rightsData.put("add-tag", _projectRightHelper.canAddTag(project)); 164 rightsData.put("remove-tag", _projectRightHelper.canRemoveTag(project)); 165 166 return rightsData; 167 } 168 169 @Override 170 public Set<String> getAllowedEventTypes() 171 { 172 return ImmutableSet.of(ObservationConstants.EVENT_RESOURCE_CREATED, 173 ObservationConstants.EVENT_RESOURCE_COMMENTED, 174 ObservationConstants.EVENT_RESOURCE_RENAMED, 175 ObservationConstants.EVENT_RESOURCE_UPDATED); 176 } 177 178 @Override 179 public Map<String, Object> _getInternalStatistics(Project project, boolean isActive) 180 { 181 if (isActive) 182 { 183 ModifiableResourceCollection documentRoot = getModuleRoot(project, false); 184 long fileNumber = documentRoot.getChildren() 185 .stream() 186 .mapToLong(child -> _getFileNumber(child)) 187 .sum(); 188 return Map.of(__DOCUMENT_NUMBER_HEADER_ID, fileNumber); 189 } 190 else 191 { 192 return Map.of(__DOCUMENT_NUMBER_HEADER_ID, __SIZE_INACTIVE); 193 } 194 } 195 196 private long _getRessourceSize(AmetysObject document) 197 { 198 if (document instanceof Resource) 199 { 200 Resource file = (Resource) document; 201 return file.getLength(); 202 } 203 else if (document instanceof ResourceCollection) 204 { 205 ResourceCollection folder = (ResourceCollection) document; 206 return folder.getChildren() 207 .stream() 208 .mapToLong(child -> _getRessourceSize(child)) 209 .sum(); 210 } 211 return 0; 212 } 213 214 private long _getFileNumber(AmetysObject document) 215 { 216 if (document instanceof Resource) 217 { 218 return 1; 219 } 220 else if (document instanceof ResourceCollection) 221 { 222 ResourceCollection folder = (ResourceCollection) document; 223 return folder.getChildren() 224 .stream() 225 .mapToLong(child -> _getFileNumber(child)) 226 .sum(); 227 } 228 return 0; 229 } 230 231 @Override 232 public List<StatisticColumn> _getInternalStatisticModel() 233 { 234 235 return List.of(new StatisticColumn(__DOCUMENT_NUMBER_HEADER_ID, new I18nizableText("plugin." + _pluginName, "PLUGINS_WORKSPACES_PROJECT_STATISTICS_TOOL_COLUMN_FILE_NUMBER")) 236 .withRenderer("Ametys.plugins.workspaces.project.tool.ProjectsGridHelper.renderElements") 237 .withType(StatisticsColumnType.LONG) 238 .withGroup(GROUP_HEADER_ELEMENTS_ID)); 239 } 240 241 @Override 242 protected long _getModuleSize(Project project) 243 { 244 return getModuleRoot(project, false).getChildren() 245 .stream() 246 .mapToLong(child -> _getRessourceSize(child)) 247 .sum(); 248 } 249 250 @Override 251 protected boolean _showModuleSize() 252 { 253 return true; 254 } 255 256 @Override 257 public Set<String> getAllEventTypes() 258 { 259 return Set.of(ObservationConstants.EVENT_RESOURCE_CREATED, 260 ObservationConstants.EVENT_RESOURCE_COMMENTED, 261 ObservationConstants.EVENT_RESOURCE_DELETED, 262 ObservationConstants.EVENT_RESOURCE_MOVED, 263 ObservationConstants.EVENT_RESOURCE_RENAMED, 264 ObservationConstants.EVENT_RESOURCE_UPDATED); 265 } 266}