001/* 002 * Copyright 2010 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.odf.clientsideelement; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.List; 022import java.util.Map; 023import java.util.Set; 024import java.util.stream.Collectors; 025 026import org.apache.avalon.framework.service.ServiceException; 027import org.apache.avalon.framework.service.ServiceManager; 028import org.apache.commons.lang3.tuple.Pair; 029 030import org.ametys.cms.repository.Content; 031import org.ametys.core.ui.Callable; 032import org.ametys.odf.ODFHelper; 033import org.ametys.odf.ProgramItem; 034import org.ametys.odf.course.Course; 035import org.ametys.odf.helper.DeleteODFContentHelper; 036import org.ametys.odf.orgunit.OrgUnit; 037import org.ametys.odf.orgunit.RootOrgUnitProvider; 038 039/** 040 * This element creates an action button to delete a ODF content 041 */ 042public class DeleteContentClientSideElement extends org.ametys.cms.clientsideelement.DeleteContentClientSideElement 043{ 044 /** The root orgunit provider */ 045 protected RootOrgUnitProvider _rootOrgUnitProvider; 046 047 /** The delete ODF content helper */ 048 protected DeleteODFContentHelper _deleteODFContentHelper; 049 050 /** The ODF helper */ 051 protected ODFHelper _odfHelper; 052 053 @Override 054 public void service(ServiceManager manager) throws ServiceException 055 { 056 super.service(manager); 057 _rootOrgUnitProvider = (RootOrgUnitProvider) manager.lookup(RootOrgUnitProvider.ROLE); 058 _deleteODFContentHelper = (DeleteODFContentHelper) manager.lookup(DeleteODFContentHelper.ROLE); 059 _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE); 060 } 061 062 @Override 063 protected boolean _hasRight(Content content) 064 { 065 return _deleteODFContentHelper.hasRight(content); 066 } 067 068 @Override 069 protected boolean _isModifiable(Content content) 070 { 071 if (content instanceof OrgUnit && _rootOrgUnitProvider.isRoot(content.getId())) 072 { 073 // The root orgunit can not be deleted 074 return false; 075 } 076 077 return super._isModifiable(content); 078 } 079 080 @Override 081 protected boolean _isContentReferenced(Content content) 082 { 083 return _deleteODFContentHelper.isContentReferenced(content); 084 } 085 086 /** 087 * Get information of the program item structure (type, if program has children) 088 * @param programItemIds the list of program item id 089 * @return a map of information 090 */ 091 @Callable 092 public Map<String, Object> getStructureInfo(List<String> programItemIds) 093 { 094 Map<String, Object> results = new HashMap<>(); 095 results.putAll(_odfHelper.getStructureInfo(programItemIds)); 096 097 // For the deletion, we need to have the number of content to delete 098 // Loop for each content to not count shareable content twice 099 // We need to split the course count with the other content because of the deletion mode 100 Set<String> onlyStructureContentsIds = new HashSet<>(); 101 Set<String> courseIds = new HashSet<>(); 102 for (String programItemId : programItemIds) 103 { 104 ProgramItem programItem = _resolver.resolveById(programItemId); 105 Pair<Set<String>, Set<String>> childContents = _getChildContents(programItem); 106 onlyStructureContentsIds.addAll(childContents.getLeft()); 107 courseIds.addAll(childContents.getRight()); 108 } 109 110 results.put("nbOnlyStructureContents", onlyStructureContentsIds.size()); 111 results.put("nbCourses", courseIds.size()); 112 113 return results; 114 } 115 116 private Pair<Set<String>, Set<String>> _getChildContents(ProgramItem programItem) 117 { 118 Set<String> onlyStructureContentsIds = new HashSet<>(); 119 Set<String> courseIds = new HashSet<>(); 120 121 for (ProgramItem item : _odfHelper.getChildProgramItems(programItem)) 122 { 123 if (item instanceof Course) 124 { 125 courseIds.add(item.getId()); 126 } 127 else 128 { 129 onlyStructureContentsIds.add(item.getId()); 130 } 131 Pair<Set<String>, Set<String>> childContents = _getChildContents(item); 132 onlyStructureContentsIds.addAll(childContents.getLeft()); 133 courseIds.addAll(childContents.getRight()); 134 } 135 136 return Pair.of(onlyStructureContentsIds, courseIds); 137 } 138 139 /** 140 * Delete ODF contents 141 * @param contentsId The ids of contents to delete 142 * @param parameters the additional parameters 143 * @return the deleted and undeleted contents 144 */ 145 @SuppressWarnings("unchecked") 146 @Callable 147 public Map<String, Object> deleteContents(List<String> contentsId, Map<String, Object> parameters) 148 { 149 Map<String, Map<String, Object>> initialContentParameters = new HashMap<>(); 150 for (String contentId : contentsId) 151 { 152 initialContentParameters.put(contentId, getContentDefaultParameters(_resolver.resolveById(contentId))); 153 } 154 155 Map<String, Object> deleteResults = _deleteODFContentHelper.deleteContents(contentsId, (String) parameters.get("mode")); 156 157 Map<String, Object> updatedResults = new HashMap<>(); 158 Set<Content> allReferencedContents = new HashSet<>(); 159 Set<Content> allLockedContents = new HashSet<>(); 160 Set<Content> allUnauthorizedContents = new HashSet<>(); 161 Set<Content> allUnDeletedContents = new HashSet<>(); 162 for (String deletedContentId : deleteResults.keySet()) 163 { 164 Map<String, Object> deleteResult = (Map<String, Object>) deleteResults.get(deletedContentId); 165 Map<String, Object> updatedContentResults = new HashMap<>(); 166 167 if (deleteResult.containsKey("check-before-deletion-failed")) 168 { 169 updatedContentResults.put("check-before-deletion-failed", deleteResult.get("check-before-deletion-failed")); 170 } 171 172 String initialContentId = (String) deleteResult.get("initial-content"); 173 updatedContentResults.put("initial-content", initialContentParameters.get(initialContentId)); 174 175 List<Map<String, Object>> deletedContents = new ArrayList<>(); 176 for (String deleteContentId : (Set<String>) deleteResult.get("deleted-contents")) 177 { 178 Map<String, Object> deleteParameters = new HashMap<>(); 179 deleteParameters.put("id", deleteContentId); 180 deletedContents.add(deleteParameters); 181 } 182 updatedContentResults.put("deleted-contents", deletedContents); 183 184 List<Map<String, Object>> undeletedContents = new ArrayList<>(); 185 for (Content content : (Set<Content>) deleteResult.get("undeleted-contents")) 186 { 187 allUnDeletedContents.add(content); 188 undeletedContents.add(getContentDefaultParameters(content)); 189 } 190 updatedContentResults.put("undeleted-contents", undeletedContents); 191 192 List<Map<String, Object>> referencedContents = new ArrayList<>(); 193 for (Content content : (Set<Content>) deleteResult.get("referenced-contents")) 194 { 195 allReferencedContents.add(content); 196 referencedContents.add(getContentDefaultParameters(content)); 197 } 198 updatedContentResults.put("referenced-contents", referencedContents); 199 200 // Update the description for locked contents 201 List<Map<String, Object>> updatedLockedContents = new ArrayList<>(); 202 for (Content content : (Set<Content>) deleteResult.get("locked-contents")) 203 { 204 allLockedContents.add(content); 205 Map<String, Object> contentParameters = getContentDefaultParameters(content); 206 contentParameters.put("description", _getLockedDescription(content)); 207 updatedLockedContents.add(contentParameters); 208 } 209 updatedContentResults.put("locked-contents", updatedLockedContents); 210 211 // Update the description for unauthorized contents 212 List<Map<String, Object>> updatedUnauthorizedContents = new ArrayList<>(); 213 for (Content content : (Set<Content>) deleteResult.get("unauthorized-contents")) 214 { 215 allUnauthorizedContents.add(content); 216 Map<String, Object> contentParameters = getContentDefaultParameters(content); 217 contentParameters.put("description", _getNoRightDescription(content)); 218 updatedUnauthorizedContents.add(contentParameters); 219 } 220 updatedContentResults.put("unauthorized-contents", updatedUnauthorizedContents); 221 222 updatedResults.put(deletedContentId, updatedContentResults); 223 } 224 225 // Add the list of all referenced contents (removing duplicate contents) 226 List<Map<String, Object>> allReferencedContentsMap = allReferencedContents.stream() 227 .map(c -> getContentDefaultParameters(c)) 228 .collect(Collectors.toList()); 229 230 updatedResults.put("all-referenced-contents", allReferencedContentsMap); 231 232 // Add the list of all locked contents (removing duplicate contents) 233 List<Map<String, Object>> allLockedContentsMap = allLockedContents.stream() 234 .map(c -> getContentDefaultParameters(c)) 235 .collect(Collectors.toList()); 236 237 updatedResults.put("all-locked-contents", allLockedContentsMap); 238 239 // Add the list of all unauthorized contents (removing duplicate contents) 240 List<Map<String, Object>> allUnauthorizedContentsMap = allUnauthorizedContents.stream() 241 .map(c -> getContentDefaultParameters(c)) 242 .collect(Collectors.toList()); 243 244 updatedResults.put("all-unauthorized-contents", allUnauthorizedContentsMap); 245 246 // Add the list of all undeleted contents (removing duplicate contents) 247 List<Map<String, Object>> allUnDeletedContentsMap = allUnDeletedContents.stream() 248 .map(c -> getContentDefaultParameters(c)) 249 .collect(Collectors.toList()); 250 251 updatedResults.put("all-undeleted-contents", allUnDeletedContentsMap); 252 253 return updatedResults; 254 } 255 256 @Override 257 protected Map<String, Object> getContentDefaultParameters(Content content) 258 { 259 Map<String, Object> contentDefaultParameters = super.getContentDefaultParameters(content); 260 261 if (content instanceof ProgramItem && content.hasValue(ProgramItem.CODE) && contentDefaultParameters.containsKey("title")) 262 { 263 String title = (String) contentDefaultParameters.get("title"); 264 contentDefaultParameters.put("title", title + " (" + content.getValue(ProgramItem.CODE) + ")"); 265 } 266 267 return contentDefaultParameters; 268 } 269}