001/*
002 *  Copyright 2023 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.apogee.scc.impl;
017
018import java.util.List;
019import java.util.Map;
020import java.util.Objects;
021import java.util.Optional;
022import java.util.stream.Stream;
023
024import org.apache.commons.lang3.StringUtils;
025import org.apache.commons.lang3.tuple.Pair;
026import org.slf4j.Logger;
027
028import org.ametys.cms.repository.ModifiableContent;
029import org.ametys.odf.course.Course;
030import org.ametys.odf.coursepart.CoursePart;
031import org.ametys.plugins.contentio.synchronize.SynchronizableContentsCollection;
032import org.ametys.plugins.odfsync.apogee.scc.AbstractApogeeSynchronizableContentsWithCatalogCollection;
033
034/**
035 * SCC for course part contents.
036 */
037public class CoursePartSynchronizableContentsCollection extends AbstractApogeeSynchronizableContentsWithCatalogCollection
038{
039    /** SCC model id */
040    public static final String MODEL_ID = "org.ametys.plugins.odfsync.apogee.scc.coursepart";
041    
042    @Override
043    protected List<Map<String, Object>> _search(Map<String, Object> searchParameters, Logger logger)
044    {
045        return _convertBigDecimal(_apogeeDAO.searchCourseParts(getDataSourceId(), getParameterValues(), searchParameters));
046    }
047
048    @Override
049    protected String getMappingName()
050    {
051        return "coursepart";
052    }
053
054    @Override
055    protected String getChildrenAttributeName()
056    {
057        return null;
058    }
059    
060    @Override
061    protected Pair<String, Object> getParentAttribute(ModifiableContent parent)
062    {
063        if (parent instanceof Course)
064        {
065            return Pair.of(CoursePart.PARENT_COURSES, new ModifiableContent[] {parent});
066        }
067
068        return super.getParentAttribute(parent);
069    }
070    
071    @Override
072    protected Map<String, Map<String, List<Object>>> getTransformedRemoteValues(Map<String, Object> searchParameters, Logger logger)
073    {
074        Map<String, Map<String, List<Object>>> remoteValuesByContent = super.getTransformedRemoteValues(searchParameters, logger);
075        
076        SynchronizableContentsCollection courseSCC = _sccHelper.getSCCFromModelId(CourseSynchronizableContentsCollection.MODEL_ID);
077        String lang = _apogeeSCCHelper.getSynchronizationLang();
078
079        // Search and add the course holder to each value
080        remoteValuesByContent.values()
081            .stream()
082            .forEach(remoteValues -> _transformCourseHolder(remoteValues, courseSCC, lang));
083        
084        return remoteValuesByContent;
085    }
086    
087    private void _transformCourseHolder(Map<String, List<Object>> remoteValues, SynchronizableContentsCollection courseSCC, String lang)
088    {
089        // Get the course holder sync code from remote values
090        Optional.ofNullable(remoteValues.get(CoursePart.COURSE_HOLDER))
091            .map(List::stream)
092            .orElseGet(Stream::of)
093            .map(String.class::cast)
094            .filter(StringUtils::isNotBlank)
095            // Get the course corresponding to the sync code
096            .map(courseHolderSyncCode -> courseSCC.getContent(lang, courseHolderSyncCode, false))
097            // Check if it exists
098            .filter(Objects::nonNull)
099            .findFirst()
100            .map(ModifiableContent::getId)
101            .ifPresentOrElse(
102                // Set the course holder value
103                courseHolderId -> remoteValues.put(CoursePart.COURSE_HOLDER, List.of(courseHolderId)),
104                // Remove the value if no course holder found
105                () -> remoteValues.remove(CoursePart.COURSE_HOLDER)
106            );
107    }
108}