001/* 002 * Copyright 2019 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.observation; 017 018import java.util.HashMap; 019import java.util.Map; 020 021import org.apache.avalon.framework.service.ServiceException; 022import org.apache.avalon.framework.service.ServiceManager; 023import org.apache.avalon.framework.service.Serviceable; 024import org.apache.commons.lang3.ArrayUtils; 025 026import org.ametys.cms.ObservationConstants; 027import org.ametys.cms.repository.Content; 028import org.ametys.cms.workflow.ContentWorkflowHelper; 029import org.ametys.cms.workflow.EditContentFunction; 030import org.ametys.core.observation.Event; 031import org.ametys.core.observation.Observer; 032import org.ametys.odf.course.Course; 033import org.ametys.odf.course.ShareableCourseConstants; 034import org.ametys.odf.course.ShareableCourseHelper; 035import org.ametys.odf.enumeration.OdfReferenceTableHelper; 036import org.ametys.odf.orgunit.OrgUnit; 037import org.ametys.odf.program.Program; 038import org.ametys.plugins.repository.AmetysObjectIterable; 039import org.ametys.plugins.repository.data.holder.values.SynchronizableValue; 040import org.ametys.plugins.repository.data.holder.values.SynchronizableValue.Mode; 041import org.ametys.plugins.workflow.AbstractWorkflowComponent; 042import org.ametys.plugins.workflow.component.CheckRightsCondition; 043import org.ametys.runtime.model.View; 044import org.ametys.runtime.plugin.component.AbstractLogEnabled; 045 046import com.opensymphony.workflow.WorkflowException; 047 048/** 049 * Observer to unlink the shareable field of a {@link Course} on {@link Content} deletion. 050 */ 051public class ShareableFieldCourseObserver extends AbstractLogEnabled implements Observer, Serviceable 052{ 053 private ContentWorkflowHelper _contentWorkflowHelper; 054 private ShareableCourseHelper _shareableCourseHelper; 055 056 @Override 057 public void service(ServiceManager manager) throws ServiceException 058 { 059 _contentWorkflowHelper = (ContentWorkflowHelper) manager.lookup(ContentWorkflowHelper.ROLE); 060 _shareableCourseHelper = (ShareableCourseHelper) manager.lookup(ShareableCourseHelper.ROLE); 061 } 062 063 @Override 064 public boolean supports(Event event) 065 { 066 if (event.getId().equals(ObservationConstants.EVENT_CONTENT_DELETING)) 067 { 068 Content content = (Content) event.getArguments().get(ObservationConstants.ARGS_CONTENT); 069 return _isProgramContent(content) 070 || _isOrgUnitContent(content) 071 || _isDegreeContent(content) 072 || _isPeriodContent(content); 073 } 074 075 return false; 076 } 077 078 @Override 079 public int getPriority(Event event) 080 { 081 return 0; 082 } 083 084 @Override 085 public void observe(Event event, Map<String, Object> transientVars) throws Exception 086 { 087 Content content = (Content) event.getArguments().get(ObservationConstants.ARGS_CONTENT); 088 String contentId = content.getId(); 089 090 if (_isProgramContent(content)) 091 { 092 _editShareableField(_shareableCourseHelper.getShareableCourses(contentId, null, null, null), contentId, ShareableCourseConstants.PROGRAMS_FIELD_ATTRIBUTE_NAME); 093 } 094 else if (_isDegreeContent(content)) 095 { 096 _editShareableField(_shareableCourseHelper.getShareableCourses(null, contentId, null, null), contentId, ShareableCourseConstants.DEGREES_FIELD_ATTRIBUTE_NAME); 097 } 098 else if (_isPeriodContent(content)) 099 { 100 _editShareableField(_shareableCourseHelper.getShareableCourses(null, null, contentId, null), contentId, ShareableCourseConstants.PERIODS_FIELD_ATTRIBUTE_NAME); 101 } 102 else if (_isOrgUnitContent(content)) 103 { 104 _editShareableField(_shareableCourseHelper.getShareableCourses(null, null, null, contentId), contentId, ShareableCourseConstants.ORGUNITS_FIELD_ATTRIBUTE_NAME); 105 } 106 } 107 108 /** 109 * Edit shareable fields 110 * @param courses the list of courses to edit shareable fields 111 * @param contentId the content id to remove from sharebale fields 112 * @param attributeNameToRemove the attribute name of the shareable field 113 * @throws WorkflowException if an error occurred 114 */ 115 protected void _editShareableField(AmetysObjectIterable<Course> courses, String contentId, String attributeNameToRemove) throws WorkflowException 116 { 117 for (Course course : courses) 118 { 119 Map<String, Object> paramsEdit = new HashMap<>(); 120 paramsEdit.put(CheckRightsCondition.FORCE, true); // Ignore the right condition 121 122 Map<String, Object> contextParameters = new HashMap<>(); 123 124 contextParameters.put(EditContentFunction.QUIT, true); 125 126 SynchronizableValue value = new SynchronizableValue(new String[] {contentId}); 127 value.setMode(Mode.REMOVE); 128 contextParameters.put(EditContentFunction.VALUES_KEY, Map.of(attributeNameToRemove, value)); 129 130 View view = View.of(course.getModel(), attributeNameToRemove); 131 contextParameters.put(EditContentFunction.VIEW, view); 132 133 paramsEdit.put(AbstractWorkflowComponent.CONTEXT_PARAMETERS_KEY, contextParameters); 134 _contentWorkflowHelper.doAction(course, 225, paramsEdit); 135 } 136 } 137 138 private boolean _isProgramContent(Content content) 139 { 140 return content instanceof Program; 141 } 142 143 private boolean _isOrgUnitContent(Content content) 144 { 145 return content instanceof OrgUnit; 146 } 147 148 private boolean _isDegreeContent(Content content) 149 { 150 return ArrayUtils.contains(content.getTypes(), OdfReferenceTableHelper.DEGREE); 151 } 152 153 private boolean _isPeriodContent(Content content) 154 { 155 return ArrayUtils.contains(content.getTypes(), OdfReferenceTableHelper.PERIOD); 156 } 157 158}