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.cdmfr;
017
018import java.io.IOException;
019import java.io.InputStream;
020import java.util.Set;
021import java.util.stream.Stream;
022
023import org.apache.avalon.framework.activity.Initializable;
024import org.apache.avalon.framework.component.Component;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.avalon.framework.service.Serviceable;
028import org.apache.excalibur.source.Source;
029import org.apache.excalibur.source.SourceResolver;
030
031import org.ametys.odf.ODFHelper;
032import org.ametys.odf.program.Program;
033import org.ametys.runtime.config.Config;
034import org.ametys.runtime.plugin.component.AbstractLogEnabled;
035
036/**
037 * Processor to process CDM-fr files.
038 *  - Filter programs if need
039 *  - Iterate on programs
040 *  - Generate the CDM-fr file
041 *  - Process on the CDM-fr file
042 */
043public abstract class AbstractCDMfrProcessor extends AbstractLogEnabled implements Component, Serviceable, Initializable
044{
045    /** The source resolver */
046    protected SourceResolver _sourceResolver;
047
048    /** The ODF helper */
049    protected ODFHelper _odfHelper;
050    
051    private boolean _isActive;
052    
053    public void service(ServiceManager manager) throws ServiceException
054    {
055        _sourceResolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
056        _odfHelper = (ODFHelper) manager.lookup(ODFHelper.ROLE);
057    }
058    
059    public void initialize() throws Exception
060    {
061        _isActive = Config.getInstance().getValue(getConfigActiveParam());
062    }
063    
064    /**
065     * Get the configuration parameter name to determine if the process is active.
066     * @return The configuration parameter name
067     */
068    protected abstract String getConfigActiveParam();
069    
070    /**
071     * <code>true</code> if the process is active
072     * @return <code>true</code> if the process is active
073     */
074    public boolean isActive()
075    {
076        return _isActive;
077    }
078    
079    /**
080     * Process the CDM-fr of the given programs.
081     * @param programs The programs to process
082     */
083    public void processPrograms(Set<Program> programs)
084    {
085        // Check if the process is active
086        if (isActive())
087        {
088            // Filter programs if needed and iterate on it
089            filterPrograms(programs.stream()).forEach(
090                program ->
091                {
092                    // Get the CDM-fr content and process the program
093                    Source cdmfrSource = null;
094                    try
095                    {
096                        cdmfrSource = _getCDMfrContent(program);
097                        try (InputStream is = cdmfrSource != null ? cdmfrSource.getInputStream() : null)
098                        {
099                            processProgram(program, is);
100                        }
101                    }
102                    catch (IOException e)
103                    {
104                        getLogger().error(getErrorMessage(), e);
105                    }
106                    finally
107                    {
108                        if (cdmfrSource != null)
109                        {
110                            _sourceResolver.release(cdmfrSource);
111                        }
112                    }
113                }
114            );
115        }
116    }
117    
118    /**
119     * Process the program and its CDM-fr input stream.
120     * @param program The program
121     * @param cdmfrContent The CDM-fr content as {@link InputStream}
122     * @throws IOException if an exception occurs
123     */
124    protected abstract void processProgram(Program program, InputStream cdmfrContent) throws IOException;
125    
126    /**
127     * Get the error message if process fails.
128     * @return the error message
129     */
130    protected abstract String getErrorMessage();
131    
132    /**
133     * Filter programs if needed.
134     * @param programs The programs to filter
135     * @return The filtered programs
136     */
137    protected Stream<Program> filterPrograms(Stream<Program> programs)
138    {
139        // Default implementation does not filter anything
140        return programs;
141    }
142    
143    /**
144     * Get the CDM-fr of the current program.
145     * @param program The program to export as CDM-fr
146     * @return The {@link InputStream} with the CDM-fr content
147     * @throws IOException if an exception occurs
148     */
149    protected Source _getCDMfrContent(Program program) throws IOException
150    {
151        // Build the URI to export program as CDM-fr
152        StringBuilder sb = new StringBuilder("cocoon://_plugins/odf/export-cdmfr.xml");
153        sb.append("?id=").append(program.getId());
154        sb.append("&").append(ExportCDMfrHelper.REQUEST_PARAM_VALID_LABEL).append("=true");
155        if (isCDMfrForAmetys())
156        {
157            sb.append("&").append(ExportCDMfrHelper.REQUEST_PARAM_EXPORT_FOR_AMETYS).append("=true");
158        }
159        
160        // Generate CDM-fr file
161        return _sourceResolver.resolveURI(sb.toString());
162    }
163    
164    /**
165     * <code>true</code> to generate CDM-fr for another Ametys, <code>false</code> otherwise.
166     * @return <code>true</code> to generate CDM-fr for another Ametys instance
167     */
168    protected abstract boolean isCDMfrForAmetys();
169}