001/* 002 * Copyright 2021 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.odfsync.pegase; 017 018import java.util.List; 019import java.util.Map; 020import java.util.Objects; 021import java.util.Optional; 022import java.util.stream.Collectors; 023import java.util.stream.Stream; 024 025import org.apache.commons.lang.StringUtils; 026import org.slf4j.Logger; 027 028import org.ametys.cms.contenttype.ContentType; 029import org.ametys.odf.courselist.CourseList.ChoiceType; 030import org.ametys.odf.program.ProgramFactory; 031import org.ametys.odf.program.SubProgramFactory; 032import org.ametys.plugins.odfsync.apogee.scc.operator.ApogeeSynchronizingContentOperator; 033import org.ametys.plugins.odfsync.scc.operator.AbstractODFSynchronizingContentOperator; 034import org.ametys.plugins.odfsync.utils.ContentWorkflowDescription; 035 036/** 037 * Pegase synchronizing content operator extending {@link ApogeeSynchronizingContentOperator} because we keep some mapping mechanisms. 038 */ 039public class PegaseSynchronizingContentOperator extends AbstractODFSynchronizingContentOperator 040{ 041 042 @Override 043 protected String getHelperRole() 044 { 045 return "org.ametys.plugins.odfsync.pegase.scc.operator.PegaseSynchronizingContentOperatorHelper"; 046 } 047 048 @Override 049 public Map<String, List<Object>> transform(ContentType obsoleteCType, Map<String, List<Object>> remoteValues, Logger logger) 050 { 051 // Get the right content type from the category field 052 ContentType contentType = Optional.of(remoteValues) 053 .map(v -> v.get("workflowDescription")) 054 .map(l -> l.get(0)) 055 .map(ContentWorkflowDescription.class::cast) 056 .map(ContentWorkflowDescription::getContentType) 057 .map(_contentTypeEP::getExtension) 058 .orElse(null); 059 060 if (contentType == null) 061 { 062 return remoteValues; 063 } 064 065 _transformSpecificValues(contentType.getId(), remoteValues); 066 067 return super.transform(contentType, remoteValues, logger); 068 } 069 070 private void _transformSpecificValues(String contentTypeId, Map<String, List<Object>> remoteValues) 071 { 072 switch (contentTypeId) 073 { 074 case ProgramFactory.PROGRAM_CONTENT_TYPE: 075 case SubProgramFactory.SUBPROGRAM_CONTENT_TYPE: 076 _transformSpecificAbstractProgramValues(remoteValues); 077 break; 078 default: 079 // Nothing to do 080 } 081 082 // Always transform courseList values in case of we have courses not under course list 083 _transformSpecificCourseListValues(remoteValues); 084 } 085 086 private void _transformSpecificAbstractProgramValues(Map<String, List<Object>> remoteValues) 087 { 088 // Transform ects for AbstractProgram (ECTS value is a double, transform it to String with a Long appearance, 5.0 -> "5") 089 List<Object> ects = Optional.ofNullable(remoteValues.get("ects")) 090 .map(List::stream) 091 .orElseGet(Stream::empty) 092 .filter(Objects::nonNull) 093 .map(Object::toString) 094 .filter(StringUtils::isNotEmpty) 095 .map(Double::valueOf) 096 .map(Double::longValue) 097 .map(String::valueOf) 098 .collect(Collectors.toList()); 099 100 if (ects.isEmpty()) 101 { 102 remoteValues.remove("ects"); 103 } 104 else 105 { 106 remoteValues.put("ects", ects); 107 } 108 } 109 110 private void _transformSpecificCourseListValues(Map<String, List<Object>> remoteValues) 111 { 112 // Set the choiceType for CourseList 113 String choiceType = 114 Optional.ofNullable(_getFirstValueAsString(remoteValues.remove("plageDeChoix"))) 115 .map(Boolean::parseBoolean) 116 .orElse(false) 117 ? ChoiceType.CHOICE.toString() 118 : ( 119 Optional.ofNullable(_getFirstValueAsString(remoteValues.remove("obligatoire"))) 120 .map(Boolean::parseBoolean) 121 .orElse(false) 122 ? ChoiceType.MANDATORY.toString() 123 : ChoiceType.OPTIONAL.toString() 124 ); 125 126 remoteValues.put("choiceType", List.of(choiceType)); 127 } 128}