001/*
002 *  Copyright 2024 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.tree;
017
018import java.util.List;
019import java.util.Map;
020
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023
024import org.ametys.cms.repository.Content;
025import org.ametys.odf.ODFHelper;
026import org.ametys.odf.ProgramItem;
027import org.ametys.odf.data.EducationalPath;
028import org.ametys.odf.program.Program;
029import org.ametys.plugins.repository.AmetysObjectResolver;
030import org.ametys.runtime.i18n.I18nizableText;
031import org.ametys.runtime.i18n.I18nizableTextParameter;
032
033/**
034 * {@link ODFTreeIndicator} to display the share status
035 */
036public class ShareStatusIndicator extends AbstractStaticODFTreeIndicator
037{
038    private ODFHelper _odfHelper;
039    private AmetysObjectResolver _resolver;
040
041    @Override
042    public void service(ServiceManager smanager) throws ServiceException
043    {
044        super.service(smanager);
045        _odfHelper = (ODFHelper) smanager.lookup(ODFHelper.ROLE);
046        _resolver = (AmetysObjectResolver) smanager.lookup(AmetysObjectResolver.ROLE);
047    }
048    
049    public IndicatorData getIndicatorData(Content content)
050    {
051        if (content instanceof ProgramItem programItem)
052        {
053            int nbParents = _odfHelper.getParentProgramItems(programItem).size();
054            boolean isShared = nbParents > 1;
055            boolean isSharedByParents = !isShared ? _isSharedByParents(programItem) : false;
056            
057            if (isShared)
058            {
059                long nbOrphanParents = _nbOrphanParents(programItem);
060                if (nbOrphanParents > 0)
061                {
062                    // Program item is shared with orphan parents
063                    Map<String, I18nizableTextParameter> i18nParams = Map.of("nbParents", new I18nizableText(String.valueOf(nbParents)), 
064                            "nbOrphanParents", new I18nizableText(String.valueOf(nbOrphanParents)));
065                    return new IndicatorData(new I18nizableText("plugin.odf", "PLUGINS_ODF_CONTENTS_TREE_INDICATORS_SHARED_WITH_ORPHANS", i18nParams), null, "odficon-share-filled orange-color", Map.of());
066                }
067                else
068                {
069                    Map<String, I18nizableTextParameter> i18nParams = Map.of("nbParents", new I18nizableText(String.valueOf(nbParents)));
070                    return new IndicatorData(new I18nizableText("plugin.odf", "PLUGINS_ODF_CONTENTS_TREE_INDICATORS_SHARED", i18nParams), null, "odficon-share-filled", Map.of());
071                }
072            }
073            else if (isSharedByParents)
074            {
075                return new IndicatorData(new I18nizableText("plugin.odf", "PLUGINS_ODF_CONTENTS_TREE_INDICATORS_PARENT_SHARED"), null, "odficon-share-outline", Map.of());
076            }
077        }
078        
079        return null;
080    }
081    
082    private long _nbOrphanParents(ProgramItem programItem)
083    {
084        List<EducationalPath> educationalPaths = _odfHelper.getEducationalPaths(programItem);
085        
086        return educationalPaths.stream()
087            .filter(p -> !(p.getProgramItems(_resolver).get(0) instanceof Program))
088            .count();
089    }
090    
091    private boolean _isShared(ProgramItem programItem)
092    {
093        return _odfHelper.getParentProgramItems(programItem).size() > 1;
094    }
095    
096    private boolean _isSharedByParents(ProgramItem programItem)
097    {
098        for (ProgramItem parent : _odfHelper.getParentProgramItems(programItem))
099        {
100            return _isShared(programItem) ? true : _isSharedByParents(parent);
101        }
102        return false;
103    }
104
105}