001/*
002 *  Copyright 2025 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.content;
017
018import java.util.HashSet;
019import java.util.Map;
020import java.util.Optional;
021import java.util.Set;
022import java.util.stream.Collectors;
023
024import org.apache.avalon.framework.context.Context;
025import org.apache.avalon.framework.context.ContextException;
026import org.apache.avalon.framework.context.Contextualizable;
027import org.apache.avalon.framework.service.ServiceException;
028import org.apache.avalon.framework.service.ServiceManager;
029import org.apache.avalon.framework.service.Serviceable;
030import org.apache.cocoon.components.ContextHelper;
031
032import org.ametys.cms.data.ContentValue;
033import org.ametys.cms.repository.Content;
034import org.ametys.odf.ODFHelper;
035import org.ametys.odf.program.Container;
036import org.ametys.odf.program.Program;
037import org.ametys.plugins.repository.UnknownAmetysObjectException;
038import org.ametys.runtime.i18n.I18nizableText;
039import org.ametys.runtime.model.Enumerator;
040
041/**
042 * {@link Enumerator} for previous/next available years of a year container
043 */
044public class YearsEnumerator implements Enumerator<ContentValue>, Serviceable, Contextualizable
045{
046    private Context _context;
047    private ODFHelper _odfHelper;
048
049    public void contextualize(Context context) throws ContextException
050    {
051        _context = context;
052    }
053    
054    public void service(ServiceManager manager) throws ServiceException
055    {
056        _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE);
057    }
058    
059    // FIXME CMS-12608: it should be not be necessary to override this method. Temporary fix.
060    public I18nizableText getEntry(ContentValue value) throws Exception
061    {
062        try
063        {
064            return _getDisplayName((Container) value.getContent());
065        }
066        catch (UnknownAmetysObjectException e)
067        {
068            // Ignore.
069        }
070        
071        return null;
072    }
073
074    public Map<ContentValue, I18nizableText> getEntries() throws Exception
075    {
076        Optional<Container> container = Optional.of(_context)
077                                                .map(ContextHelper::getRequest)
078                                                .map(r -> r.getAttribute(Content.class.getName()))
079                                                .filter(Container.class::isInstance)
080                                                .map(Container.class::cast);
081        
082        if (container.isEmpty())
083        {
084            // Not in a container context
085            return Map.of();
086        }
087        
088        Container containerObj = container.get();
089        if (!_odfHelper.isContainerOfTypeYear(containerObj))
090        {
091            // Not a year container
092            return Map.of();
093        }
094        
095        Set<Program> parentPrograms = _odfHelper.getParentPrograms(containerObj);
096        
097        Set<Container> years = new HashSet<>();
098        for (Program program : parentPrograms)
099        {
100            years.addAll(_odfHelper.getYears(program));
101        }
102        
103        // Remove the current year
104        years.remove(containerObj);
105        
106        return years.stream().collect(Collectors.toMap(ContentValue::new, this::_getDisplayName));
107    }
108    
109    private I18nizableText _getDisplayName(Container container)
110    {
111        StringBuilder displayName = new StringBuilder();
112        
113        // Display code
114        displayName.append("[");
115        displayName.append(container.getDisplayCode());
116        displayName.append("] ");
117        
118        displayName.append(container.getTitle());
119        
120        return new I18nizableText(displayName.toString());
121    }
122}